add xschemrc option ps_page_title (default: enabled, 1) to set or hide page title in ps/pdf exports, more precise graph exports in svg and ps/pdf

This commit is contained in:
stefan schippers 2023-12-11 10:43:09 +01:00
parent c360187d8a
commit f042b940c2
8 changed files with 84 additions and 42 deletions

View File

@ -543,6 +543,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> abort_operation</kbd></li><pre>
@ -1044,6 +1045,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> preview_window create|draw|destroy [winpath] [file]</kbd></li><pre>
Used in fileselector to show a schematic preview.</pre>
<li><kbd> print png|svg|ps|pdf|ps_full|pdf_full img_file [img_x img_y] [x1 y1 x2 y2]</kbd></li><pre>
If img_x and img_y are set to 0 (recommended for svg)
they will be calculated by xschem automatically
Export current schematic to image.
img x y size xschem area to export
0 1 2 3 4 5 6 7 8 9
@ -1460,7 +1463,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
</ul>

View File

@ -2558,34 +2558,31 @@ void set_viewport_size(int w, int h, double lw)
xctx->areah = xctx->areay2-xctx->areay1;
}
void save_restore_zoom(int save)
void save_restore_zoom(int save, Zoom_info *zi)
{
static int savew, saveh; /* safe to keep even with multiple schematics */
static double savexor, saveyor, savezoom, savelw; /* safe to keep even with multiple schematics */
if(save) {
savew = xctx->xrect[0].width;
saveh = xctx->xrect[0].height;
savelw = xctx->lw;
savexor = xctx->xorigin;
saveyor = xctx->yorigin;
savezoom = xctx->zoom;
zi->savew = xctx->xrect[0].width;
zi->saveh = xctx->xrect[0].height;
zi->savelw = xctx->lw;
zi->savexor = xctx->xorigin;
zi->saveyor = xctx->yorigin;
zi->savezoom = xctx->zoom;
} else {
xctx->xrect[0].x = 0;
xctx->xrect[0].y = 0;
xctx->xrect[0].width = (unsigned short)savew;
xctx->xrect[0].height = (unsigned short)saveh;
xctx->areax2 = savew+2*INT_WIDTH(savelw);
xctx->areay2 = saveh+2*INT_WIDTH(savelw);
xctx->areax1 = -2*INT_WIDTH(savelw);
xctx->areay1 = -2*INT_WIDTH(savelw);
xctx->lw = savelw;
xctx->xrect[0].width = (unsigned short)zi->savew;
xctx->xrect[0].height = (unsigned short)zi->saveh;
xctx->areax2 = zi->savew+2*INT_WIDTH(zi->savelw);
xctx->areay2 = zi->saveh+2*INT_WIDTH(zi->savelw);
xctx->areax1 = -2*INT_WIDTH(zi->savelw);
xctx->areay1 = -2*INT_WIDTH(zi->savelw);
xctx->lw = zi->savelw;
xctx->areaw = xctx->areax2-xctx->areax1;
xctx->areah = xctx->areay2-xctx->areay1;
xctx->xorigin = savexor;
xctx->yorigin = saveyor;
xctx->zoom = savezoom;
xctx->mooz = 1 / savezoom;
xctx->xorigin = zi->savexor;
xctx->yorigin = zi->saveyor;
xctx->zoom = zi->savezoom;
xctx->mooz = 1 / zi->savezoom;
}
}

View File

@ -3924,6 +3924,7 @@ static void draw_images_all(void)
void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2, double ry2)
{
#if HAS_CAIRO==1
Zoom_info zi;
char *ptr = NULL;
double x1, y1, x2, y2, w, h, rw, rh, scale;
char transform[150];
@ -3931,7 +3932,7 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
cairo_surface_t *png_sfc;
int save, save_draw_window, save_draw_grid, rwi, rhi;
size_t olength;
const double max_size = 2000.0;
const double max_size = 5000.0;
if(!has_x) return;
rw = fabs(rx2 -rx1);
@ -3944,9 +3945,16 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
}
rwi = (int) (rw * scale + 1.0);
rhi = (int) (rh * scale + 1.0);
save_restore_zoom(1);
save_restore_zoom(1, &zi);
set_viewport_size(rwi, rhi, xctx->lw);
zoom_box(rx1 - xctx->lw, ry1 - xctx->lw, rx2 + xctx->lw, ry2 + xctx->lw, 1.0);
/* zoom_box(rx1 - xctx->lw, ry1 - xctx->lw, rx2 + xctx->lw, ry2 + xctx->lw, 1.0); */
xctx->xorigin = -rx1;
xctx->yorigin = -ry1;
xctx->zoom=(rx2-rx1)/(rwi - 1);
xctx->mooz = 1 / xctx->zoom;
resetwin(1, 1, 1, rwi, rhi);
save_draw_grid = tclgetboolvar("draw_grid");
tclsetvar("draw_grid", "0");
@ -3987,7 +3995,7 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
xctx->draw_window=save_draw_window;
xctx->do_copy_area=save;
tclsetboolvar("draw_grid", save_draw_grid);
save_restore_zoom(0);
save_restore_zoom(0, &zi);
resetwin(1, 1, 1, 0, 0);
x1=X_TO_SVG(rx1);

View File

@ -232,10 +232,11 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, i
void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
{
#if defined(HAS_LIBJPEG) && HAS_CAIRO==1
Zoom_info zi;
double rw, rh, scale;
cairo_surface_t* png_sfc;
int save, save_draw_window, save_draw_grid, rwi, rhi;
const double max_size = 2000.0;
const double max_size = 5000.0;
int d_c;
unsigned char* jpgData = NULL;
size_t fileSize = 0;
@ -269,11 +270,17 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
rwi = (int)(rw * scale + 1.0);
rhi = (int)(rh * scale + 1.0);
dbg(1, "graph size: %dx%d\n", rwi, rhi);
save_restore_zoom(1);
save_restore_zoom(1, &zi);
set_viewport_size(rwi, rhi, xctx->lw);
zoom_box(rx1 - xctx->lw, ry1 - xctx->lw, rx2 + xctx->lw, ry2 + xctx->lw, 1.0);
/* zoom_box(rx1 - xctx->lw, ry1 - xctx->lw, rx2 + xctx->lw, ry2 + xctx->lw, 1.0); */
xctx->xorigin = -rx1;
xctx->yorigin = -ry1;
xctx->zoom=(rx2-rx1)/(rwi - 1);
xctx->mooz = 1 / xctx->zoom;
resetwin(1, 1, 1, rwi, rhi);
change_linewidth(xctx->lw * 1.0);
dbg(1, "lw=%g\n", xctx->lw);
save_draw_grid = tclgetboolvar("draw_grid");
tclsetvar("draw_grid", "0");
@ -286,6 +293,7 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
tclsetboolvar("dark_colorscheme", 0);
build_colors(0, 0);
draw();
dbg(1, "width=%d, rwi=%d height=%d rhi=%d\n", xctx->xrect[0].width, rwi, xctx->xrect[0].height, rhi);
#ifdef __unix__
png_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual,
xctx->xrect[0].width, xctx->xrect[0].height);
@ -314,7 +322,7 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
cairo_surface_destroy(png_sfc);
xctx->draw_pixmap = 1;
tclsetboolvar("draw_grid", save_draw_grid);
save_restore_zoom(0);
save_restore_zoom(0, &zi);
resetwin(1, 1, 1, 0, 0);
change_linewidth(xctx->lw);
tclsetboolvar("dark_colorscheme", d_c);
@ -983,6 +991,7 @@ void create_ps(char **psfile, int what, int fullzoom)
static int savex1, savey1, savex2, savey2, savew, saveh;
static int saveadjustedx1, saveadjustedy1, saveadjustedx2, saveadjustedy2, saveadjustedw, saveadjustedh;
static XRectangle savexrect, saveadjustedxrect;
int save_change_lw;
dbg(1, "create_ps(): what = %d, fullzoom=%d\n", what, fullzoom);
if(tcleval("info exists ps_paper_size")[0] == '1') {
@ -1158,7 +1167,8 @@ void create_ps(char **psfile, int what, int fullzoom)
fprintf(fd, "%%%%EndPageSetup\n");
/* add small page title */
fprintf(fd, "/Helvetica FF 10 SCF SF NP 20 %g MT (%s) show\n", pagey - 20, xctx->current_name);
if(tclgetboolvar("ps_page_title"))
fprintf(fd, "/Helvetica FF 10 SCF SF NP 20 %g MT (%s) show\n", pagey - 20, xctx->current_name);
/* Add anchor for pdfmarks */
fprintf(fd,
@ -1216,6 +1226,8 @@ void create_ps(char **psfile, int what, int fullzoom)
xctx->text[i].xscale, xctx->text[i].yscale);
}
}
save_change_lw = tclgetintvar("change_lw");
tclsetintvar("change_lw", 0);
for(c=0;c<cadlayers; ++c)
{
set_ps_colors(c);
@ -1274,6 +1286,7 @@ void create_ps(char **psfile, int what, int fullzoom)
}
dbg(1, "create_ps(): starting drawing symbols on layer %d\n", c);
} /* for(c=0;c<cadlayers; ++c) */
tclsetintvar("change_lw", save_change_lw);
/* bring outside previous for(c=0...) loop since ps_embedded_graph() calls ps_draw_symbol() */
for(c=0;c<cadlayers; ++c) {

View File

@ -3042,6 +3042,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
/* print png|svg|ps|pdf|ps_full|pdf_full img_file [img_x img_y] [x1 y1 x2 y2]
* If img_x and img_y are set to 0 (recommended for svg)
* they will be calculated by xschem automatically
* Export current schematic to image.
* img x y size xschem area to export
* 0 1 2 3 4 5 6 7 8 9
@ -3054,6 +3056,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
*/
else if(!strcmp(argv[1], "print") )
{
Zoom_info zi;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc < 3) {
Tcl_SetResult(interp, "xschem print needs at least 1 more arguments: plot_type", TCL_STATIC);
@ -3079,12 +3082,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
h = atoi(argv[5]);
if(w == 0) w = xctx->xrect[0].width;
if(h == 0) h = xctx->xrect[0].height;
save_restore_zoom(1);
save_restore_zoom(1, &zi);
set_viewport_size(w, h, 1.0);
zoom_full(0, 0, 2 * tclgetboolvar("zoom_full_center"), 0.97);
resetwin(1, 1, 1, w, h);
print_image();
save_restore_zoom(0);
save_restore_zoom(0, &zi);
resetwin(1, 1, 1, 0, 0);
change_linewidth(-1.);
} else if(argc == 10) {
@ -3096,12 +3099,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
y2 = atof(argv[9]);
if(w == 0) w = (int) fabs(x2 - x1);
if(h == 0) h = (int) fabs(y2 - y1);
save_restore_zoom(1);
save_restore_zoom(1, &zi);
set_viewport_size(w, h, 1.0);
zoom_box(x1, y1, x2, y2, 1.0);
resetwin(1, 1, 1, w, h);
print_image();
save_restore_zoom(0);
save_restore_zoom(0, &zi);
resetwin(1, 1, 1, 0, 0);
change_linewidth(-1.);
} else {
@ -3109,16 +3112,21 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
else if(!strcmp(argv[2], "svg")) {
int w = 0, h = 0;
int w = 0, h = 0, save_change_lw;
double x1, y1, x2, y2;
if(argc == 6) {
w = atoi(argv[4]);
h = atoi(argv[5]);
save_restore_zoom(1);
if(w == 0) w = xctx->xrect[0].width;
if(h == 0) h = xctx->xrect[0].height;
save_restore_zoom(1, &zi);
set_viewport_size(w, h, xctx->lw);
zoom_full(0, 0, 2 * tclgetboolvar("zoom_full_center"), 0.97);
save_change_lw = tclgetintvar("change_lw");
tclsetintvar("change_lw", 0);
svg_draw();
save_restore_zoom(0);
tclsetintvar("change_lw", save_change_lw);
save_restore_zoom(0, &zi);
} else if(argc == 10) {
w = atoi(argv[4]);
h = atoi(argv[5]);
@ -3126,11 +3134,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
y1 = atof(argv[7]);
x2 = atof(argv[8]);
y2 = atof(argv[9]);
save_restore_zoom(1);
if(w == 0) w = (int) fabs(x2 - x1);
if(h == 0) h = (int) fabs(y2 - y1);
save_restore_zoom(1, &zi);
set_viewport_size(w, h, xctx->lw);
zoom_box(x1, y1, x2, y2, 1.0);
save_change_lw = tclgetintvar("change_lw");
tclsetintvar("change_lw", 0);
svg_draw();
save_restore_zoom(0);
tclsetintvar("change_lw", save_change_lw);
save_restore_zoom(0, &zi);
} else {
svg_draw();
}

View File

@ -871,6 +871,11 @@ typedef struct {
double linewidth_mult; /* multiply factor for waveforms line width */
} Graph_ctx;
typedef struct {
int savew, saveh;
double savexor, saveyor, savezoom, savelw;
} Zoom_info;
typedef struct {
xWire *wire;
xText *text;
@ -1493,7 +1498,7 @@ extern void find_inst_to_be_redrawn(int what);
extern void pan(int what, int mx, int my);
extern void zoom_rectangle(int what);
extern void zoom_box(double x1, double y1, double x2, double y2, double factor);
extern void save_restore_zoom(int save);
extern void save_restore_zoom(int save, Zoom_info *zi);
extern void select_rect(int what, int select);
extern void new_rect(int what);
extern void new_polygon(int what);

View File

@ -7805,6 +7805,7 @@ set_ne split_files 0
set_ne flat_netlist 0
set_ne netlist_show 0
set_ne color_ps 1
set_ne ps_page_title 1 ;# add a title in the top left page corner
set_ne crosshair_layer 3 ;# TEXTLAYER
set_ne ps_paper_size {a4 842 595}
set_ne transparent_svg 0

View File

@ -153,6 +153,9 @@
#### allow color postscript and svg exports. Default: 1, enable color
# set color_ps 1
#### add a page title in the top left corner of the ps/pdf page. Default: enabled (1)
# set ps_page_title 1
#### set paper size: name, height, width. Sizes in 1/72 of an inch (typographical points)
#### default: {a4 842 595}
# set ps_paper_size {a4 842 595}