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> <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> <li><kbd> preview_window create|draw|destroy [winpath] [file]</kbd></li><pre>
Used in fileselector to show a schematic preview.</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> <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. Export current schematic to image.
img x y size xschem area to export img x y size xschem area to export
0 1 2 3 4 5 6 7 8 9 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> </ul>

View File

@ -2558,34 +2558,31 @@ void set_viewport_size(int w, int h, double lw)
xctx->areah = xctx->areay2-xctx->areay1; 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) { if(save) {
savew = xctx->xrect[0].width; zi->savew = xctx->xrect[0].width;
saveh = xctx->xrect[0].height; zi->saveh = xctx->xrect[0].height;
savelw = xctx->lw; zi->savelw = xctx->lw;
savexor = xctx->xorigin; zi->savexor = xctx->xorigin;
saveyor = xctx->yorigin; zi->saveyor = xctx->yorigin;
savezoom = xctx->zoom; zi->savezoom = xctx->zoom;
} else { } else {
xctx->xrect[0].x = 0; xctx->xrect[0].x = 0;
xctx->xrect[0].y = 0; xctx->xrect[0].y = 0;
xctx->xrect[0].width = (unsigned short)savew; xctx->xrect[0].width = (unsigned short)zi->savew;
xctx->xrect[0].height = (unsigned short)saveh; xctx->xrect[0].height = (unsigned short)zi->saveh;
xctx->areax2 = savew+2*INT_WIDTH(savelw); xctx->areax2 = zi->savew+2*INT_WIDTH(zi->savelw);
xctx->areay2 = saveh+2*INT_WIDTH(savelw); xctx->areay2 = zi->saveh+2*INT_WIDTH(zi->savelw);
xctx->areax1 = -2*INT_WIDTH(savelw); xctx->areax1 = -2*INT_WIDTH(zi->savelw);
xctx->areay1 = -2*INT_WIDTH(savelw); xctx->areay1 = -2*INT_WIDTH(zi->savelw);
xctx->lw = savelw; xctx->lw = zi->savelw;
xctx->areaw = xctx->areax2-xctx->areax1; xctx->areaw = xctx->areax2-xctx->areax1;
xctx->areah = xctx->areay2-xctx->areay1; xctx->areah = xctx->areay2-xctx->areay1;
xctx->xorigin = savexor; xctx->xorigin = zi->savexor;
xctx->yorigin = saveyor; xctx->yorigin = zi->saveyor;
xctx->zoom = savezoom; xctx->zoom = zi->savezoom;
xctx->mooz = 1 / 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) void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2, double ry2)
{ {
#if HAS_CAIRO==1 #if HAS_CAIRO==1
Zoom_info zi;
char *ptr = NULL; char *ptr = NULL;
double x1, y1, x2, y2, w, h, rw, rh, scale; double x1, y1, x2, y2, w, h, rw, rh, scale;
char transform[150]; 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; cairo_surface_t *png_sfc;
int save, save_draw_window, save_draw_grid, rwi, rhi; int save, save_draw_window, save_draw_grid, rwi, rhi;
size_t olength; size_t olength;
const double max_size = 2000.0; const double max_size = 5000.0;
if(!has_x) return; if(!has_x) return;
rw = fabs(rx2 -rx1); 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); rwi = (int) (rw * scale + 1.0);
rhi = (int) (rh * 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); 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); resetwin(1, 1, 1, rwi, rhi);
save_draw_grid = tclgetboolvar("draw_grid"); save_draw_grid = tclgetboolvar("draw_grid");
tclsetvar("draw_grid", "0"); 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->draw_window=save_draw_window;
xctx->do_copy_area=save; xctx->do_copy_area=save;
tclsetboolvar("draw_grid", save_draw_grid); tclsetboolvar("draw_grid", save_draw_grid);
save_restore_zoom(0); save_restore_zoom(0, &zi);
resetwin(1, 1, 1, 0, 0); resetwin(1, 1, 1, 0, 0);
x1=X_TO_SVG(rx1); 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) void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
{ {
#if defined(HAS_LIBJPEG) && HAS_CAIRO==1 #if defined(HAS_LIBJPEG) && HAS_CAIRO==1
Zoom_info zi;
double rw, rh, scale; double rw, rh, scale;
cairo_surface_t* png_sfc; cairo_surface_t* png_sfc;
int save, save_draw_window, save_draw_grid, rwi, rhi; 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; int d_c;
unsigned char* jpgData = NULL; unsigned char* jpgData = NULL;
size_t fileSize = 0; 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); rwi = (int)(rw * scale + 1.0);
rhi = (int)(rh * scale + 1.0); rhi = (int)(rh * scale + 1.0);
dbg(1, "graph size: %dx%d\n", rwi, rhi); 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); 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); resetwin(1, 1, 1, rwi, rhi);
change_linewidth(xctx->lw * 1.0);
dbg(1, "lw=%g\n", xctx->lw); dbg(1, "lw=%g\n", xctx->lw);
save_draw_grid = tclgetboolvar("draw_grid"); save_draw_grid = tclgetboolvar("draw_grid");
tclsetvar("draw_grid", "0"); 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); tclsetboolvar("dark_colorscheme", 0);
build_colors(0, 0); build_colors(0, 0);
draw(); draw();
dbg(1, "width=%d, rwi=%d height=%d rhi=%d\n", xctx->xrect[0].width, rwi, xctx->xrect[0].height, rhi);
#ifdef __unix__ #ifdef __unix__
png_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, png_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual,
xctx->xrect[0].width, xctx->xrect[0].height); 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); cairo_surface_destroy(png_sfc);
xctx->draw_pixmap = 1; xctx->draw_pixmap = 1;
tclsetboolvar("draw_grid", save_draw_grid); tclsetboolvar("draw_grid", save_draw_grid);
save_restore_zoom(0); save_restore_zoom(0, &zi);
resetwin(1, 1, 1, 0, 0); resetwin(1, 1, 1, 0, 0);
change_linewidth(xctx->lw); change_linewidth(xctx->lw);
tclsetboolvar("dark_colorscheme", d_c); 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 savex1, savey1, savex2, savey2, savew, saveh;
static int saveadjustedx1, saveadjustedy1, saveadjustedx2, saveadjustedy2, saveadjustedw, saveadjustedh; static int saveadjustedx1, saveadjustedy1, saveadjustedx2, saveadjustedy2, saveadjustedw, saveadjustedh;
static XRectangle savexrect, saveadjustedxrect; static XRectangle savexrect, saveadjustedxrect;
int save_change_lw;
dbg(1, "create_ps(): what = %d, fullzoom=%d\n", what, fullzoom); dbg(1, "create_ps(): what = %d, fullzoom=%d\n", what, fullzoom);
if(tcleval("info exists ps_paper_size")[0] == '1') { 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"); fprintf(fd, "%%%%EndPageSetup\n");
/* add small page title */ /* 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 */ /* Add anchor for pdfmarks */
fprintf(fd, fprintf(fd,
@ -1216,6 +1226,8 @@ void create_ps(char **psfile, int what, int fullzoom)
xctx->text[i].xscale, xctx->text[i].yscale); xctx->text[i].xscale, xctx->text[i].yscale);
} }
} }
save_change_lw = tclgetintvar("change_lw");
tclsetintvar("change_lw", 0);
for(c=0;c<cadlayers; ++c) for(c=0;c<cadlayers; ++c)
{ {
set_ps_colors(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); dbg(1, "create_ps(): starting drawing symbols on layer %d\n", c);
} /* for(c=0;c<cadlayers; ++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() */ /* bring outside previous for(c=0...) loop since ps_embedded_graph() calls ps_draw_symbol() */
for(c=0;c<cadlayers; ++c) { 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] /* 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. * Export current schematic to image.
* img x y size xschem area to export * img x y size xschem area to export
* 0 1 2 3 4 5 6 7 8 9 * 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") ) else if(!strcmp(argv[1], "print") )
{ {
Zoom_info zi;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc < 3) { if(argc < 3) {
Tcl_SetResult(interp, "xschem print needs at least 1 more arguments: plot_type", TCL_STATIC); 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]); h = atoi(argv[5]);
if(w == 0) w = xctx->xrect[0].width; if(w == 0) w = xctx->xrect[0].width;
if(h == 0) h = xctx->xrect[0].height; if(h == 0) h = xctx->xrect[0].height;
save_restore_zoom(1); save_restore_zoom(1, &zi);
set_viewport_size(w, h, 1.0); set_viewport_size(w, h, 1.0);
zoom_full(0, 0, 2 * tclgetboolvar("zoom_full_center"), 0.97); zoom_full(0, 0, 2 * tclgetboolvar("zoom_full_center"), 0.97);
resetwin(1, 1, 1, w, h); resetwin(1, 1, 1, w, h);
print_image(); print_image();
save_restore_zoom(0); save_restore_zoom(0, &zi);
resetwin(1, 1, 1, 0, 0); resetwin(1, 1, 1, 0, 0);
change_linewidth(-1.); change_linewidth(-1.);
} else if(argc == 10) { } else if(argc == 10) {
@ -3096,12 +3099,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
y2 = atof(argv[9]); y2 = atof(argv[9]);
if(w == 0) w = (int) fabs(x2 - x1); if(w == 0) w = (int) fabs(x2 - x1);
if(h == 0) h = (int) fabs(y2 - y1); if(h == 0) h = (int) fabs(y2 - y1);
save_restore_zoom(1); save_restore_zoom(1, &zi);
set_viewport_size(w, h, 1.0); set_viewport_size(w, h, 1.0);
zoom_box(x1, y1, x2, y2, 1.0); zoom_box(x1, y1, x2, y2, 1.0);
resetwin(1, 1, 1, w, h); resetwin(1, 1, 1, w, h);
print_image(); print_image();
save_restore_zoom(0); save_restore_zoom(0, &zi);
resetwin(1, 1, 1, 0, 0); resetwin(1, 1, 1, 0, 0);
change_linewidth(-1.); change_linewidth(-1.);
} else { } else {
@ -3109,16 +3112,21 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
} }
} }
else if(!strcmp(argv[2], "svg")) { else if(!strcmp(argv[2], "svg")) {
int w = 0, h = 0; int w = 0, h = 0, save_change_lw;
double x1, y1, x2, y2; double x1, y1, x2, y2;
if(argc == 6) { if(argc == 6) {
w = atoi(argv[4]); w = atoi(argv[4]);
h = atoi(argv[5]); 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); set_viewport_size(w, h, xctx->lw);
zoom_full(0, 0, 2 * tclgetboolvar("zoom_full_center"), 0.97); zoom_full(0, 0, 2 * tclgetboolvar("zoom_full_center"), 0.97);
save_change_lw = tclgetintvar("change_lw");
tclsetintvar("change_lw", 0);
svg_draw(); svg_draw();
save_restore_zoom(0); tclsetintvar("change_lw", save_change_lw);
save_restore_zoom(0, &zi);
} else if(argc == 10) { } else if(argc == 10) {
w = atoi(argv[4]); w = atoi(argv[4]);
h = atoi(argv[5]); h = atoi(argv[5]);
@ -3126,11 +3134,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
y1 = atof(argv[7]); y1 = atof(argv[7]);
x2 = atof(argv[8]); x2 = atof(argv[8]);
y2 = atof(argv[9]); 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); set_viewport_size(w, h, xctx->lw);
zoom_box(x1, y1, x2, y2, 1.0); zoom_box(x1, y1, x2, y2, 1.0);
save_change_lw = tclgetintvar("change_lw");
tclsetintvar("change_lw", 0);
svg_draw(); svg_draw();
save_restore_zoom(0); tclsetintvar("change_lw", save_change_lw);
save_restore_zoom(0, &zi);
} else { } else {
svg_draw(); svg_draw();
} }

View File

@ -871,6 +871,11 @@ typedef struct {
double linewidth_mult; /* multiply factor for waveforms line width */ double linewidth_mult; /* multiply factor for waveforms line width */
} Graph_ctx; } Graph_ctx;
typedef struct {
int savew, saveh;
double savexor, saveyor, savezoom, savelw;
} Zoom_info;
typedef struct { typedef struct {
xWire *wire; xWire *wire;
xText *text; 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 pan(int what, int mx, int my);
extern void zoom_rectangle(int what); extern void zoom_rectangle(int what);
extern void zoom_box(double x1, double y1, double x2, double y2, double factor); 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 select_rect(int what, int select);
extern void new_rect(int what); extern void new_rect(int what);
extern void new_polygon(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 flat_netlist 0
set_ne netlist_show 0 set_ne netlist_show 0
set_ne color_ps 1 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 crosshair_layer 3 ;# TEXTLAYER
set_ne ps_paper_size {a4 842 595} set_ne ps_paper_size {a4 842 595}
set_ne transparent_svg 0 set_ne transparent_svg 0

View File

@ -153,6 +153,9 @@
#### allow color postscript and svg exports. Default: 1, enable color #### allow color postscript and svg exports. Default: 1, enable color
# set color_ps 1 # 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) #### set paper size: name, height, width. Sizes in 1/72 of an inch (typographical points)
#### default: {a4 842 595} #### default: {a4 842 595}
# set ps_paper_size {a4 842 595} # set ps_paper_size {a4 842 595}