svg_draw(): if xschem started with -x but cairo is available use a temporary X connection (if X available) to create a cairo context so we get more precise font metricx for text bbox calculations

This commit is contained in:
stefan schippers 2024-03-12 02:36:32 +01:00
parent 560a9c5f57
commit 65ba2e1cc4
5 changed files with 84 additions and 42 deletions

View File

@ -3371,6 +3371,23 @@ void new_polygon(int what, double mousex_snap, double mousey_snap)
}
}
#if HAS_CAIRO==1
static int temporary_x_connection = 0;
#endif
void close_temporary_x_connection(void)
{
#if HAS_CAIRO==1
if(temporary_x_connection) {
cairo_destroy(xctx->cairo_ctx);
cairo_surface_destroy(xctx->cairo_sfc);
XDestroyWindow(display, xctx->window);
XCloseDisplay(display);
display = NULL;
temporary_x_connection = 0;
}
#endif
}
#if HAS_CAIRO==1
int text_bbox(const char *str, double xscale, double yscale,
short rot, short flip, int hcenter, int vcenter, double x1,double y1, double *rx1, double *ry1,
@ -3383,8 +3400,28 @@ int text_bbox(const char *str, double xscale, double yscale,
cairo_font_extents_t fext;
double ww, hh, maxw;
/* try to create a cairo context so we get better font metric calculation (text bbox) */
if(!display) {
int screen;
unsigned long white;
Visual *visual;
if((display = XOpenDisplay(NULL))) {
screen = DefaultScreen(display);
visual = DefaultVisual(display, screen);
white = WhitePixel(display, screen);
xctx->window = XCreateSimpleWindow(display,
DefaultRootWindow(display), 0, 0, 1, 1, CopyFromParent, white, white);
xctx->cairo_sfc = cairo_xlib_surface_create(display, xctx->window, visual, 1, 1);
xctx->cairo_ctx = cairo_create(xctx->cairo_sfc);
temporary_x_connection = 1;
}
}
/* if XOpenDisplay() failed display will be still NULL so we will go with
* text_bbox_nocairo() */
/* will not match exactly font metrics when doing ps/svg output , but better than nothing */
if(!has_x) return text_bbox_nocairo(str, xscale, yscale, rot, flip, hcenter, vcenter, x1, y1,
if(!has_x && !display) return text_bbox_nocairo(str, xscale, yscale, rot, flip, hcenter, vcenter, x1, y1,
rx1, ry1, rx2, ry2, cairo_lines, cairo_longest_line);
size = xscale*52.*cairo_font_scale;

View File

@ -26,7 +26,7 @@
/* ------------------------------------------------ */
/* X11 specific globals */
/* ------------------------------------------------ */
Display *display;
Display *display = NULL;
#ifdef HAS_XCB
xcb_connection_t *xcb_conn;

View File

@ -958,6 +958,11 @@ void svg_draw(void)
tclsetboolvar("draw_grid", old_grid);
my_free(_ALLOC_ID_, &svg_colors);
my_free(_ALLOC_ID_, &unused_layer);
/* if xschem started with no X connection, text_bbox() will
* try to open an X connection and create a cairo surface
* that will be used to return more precise font metrics for
* text bbox calculation. so we close the temporary connection here. */
close_temporary_x_connection();
Tcl_SetResult(interp,"",TCL_STATIC);
}

View File

@ -1330,7 +1330,7 @@ extern int text_bbox(const char * str,double xscale, double yscale,
short rot, short flip, int hcenter, int vcenter,
double x1,double y1, double *rx1, double *ry1,
double *rx2, double *ry2, int *cairo_lines, double *longest_line);
extern void close_temporary_x_connection(void);
extern int get_color(int value);
extern void incr_hilight_color(void);
extern void get_inst_pin_coord(int i, int j, double *x, double *y);

File diff suppressed because one or more lines are too long