diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index 251992f2..d909d784 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -497,6 +497,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" +
Resets UI state, unselect all and abort any pending operation
@@ -942,7 +943,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
xschem print png file.png 400 300 [ -300 -200 300 200 ]
xschem print svg file.svg 400 300 [ -300 -200 300 200 ]
xschem print ps file.ps
- xschem print pdf file.pdf
+ xschem print pdf file.pdf
+ xschem print ps_full file.ps
+ xschem print pdf_full file.pdf
from highlighted nets/pins/labels:
show == 0 ==> create pins from highlight nets
diff --git a/src/callback.c b/src/callback.c
index d84b1017..830baf9a 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -2017,7 +2017,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
if(key=='*' && state==ShiftMask ) /* postscript print */
{
if(xctx->semaphore >= 2) break;
- ps_draw(7);
+ ps_draw(7, 0);
break;
}
if(key=='*' && state==(ControlMask|ShiftMask) ) /* xpm print */
diff --git a/src/draw.c b/src/draw.c
index a935efb6..76a51d87 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -147,7 +147,7 @@ void print_image()
} else tcleval( "convert_to_png plot.xpm plot.png");
#else
char *psfile = NULL;
- create_ps(&psfile, 7);
+ create_ps(&psfile, 7, 0);
if (xctx->plotfile[0]) {
my_snprintf(cmd, S(cmd), "convert_to_png {%s} {%s}", psfile, xctx->plotfile);
tcleval(cmd);
diff --git a/src/psprint.c b/src/psprint.c
index ac74703b..41274c94 100644
--- a/src/psprint.c
+++ b/src/psprint.c
@@ -272,6 +272,8 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
set_viewport_size(rwi, rhi, xctx->lw);
zoom_box(rx1 - xctx->lw, ry1 - xctx->lw, rx2 + xctx->lw, ry2 + xctx->lw, 1.0);
resetwin(1, 1, 1, rwi, rhi);
+ change_linewidth(xctx->lw * 4.0);
+ dbg(1, "lw=%g\n", xctx->lw);
save_draw_grid = tclgetboolvar("draw_grid");
tclsetvar("draw_grid", "0");
save_draw_window = xctx->draw_window;
@@ -310,15 +312,15 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
cairo_surface_destroy(png_sfc);
xctx->draw_pixmap = 1;
- xctx->draw_window = save_draw_window;
- xctx->do_copy_area = save;
tclsetboolvar("draw_grid", save_draw_grid);
save_restore_zoom(0);
resetwin(1, 1, 1, 0, 0);
- change_linewidth(-1.);
+ change_linewidth(xctx->lw);
tclsetboolvar("dark_colorscheme", d_c);
build_colors(0, 0);
draw();
+ xctx->do_copy_area = save;
+ xctx->draw_window = save_draw_window;
fprintf(fd, "gsave\n");
fprintf(fd, "save\n");
fprintf(fd, "/RawData currentfile /ASCII85Decode filter def\n");
@@ -453,14 +455,14 @@ static void ps_drawpolygon(int c, int what, double *x, double *y, int points, in
static void ps_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2, int dash, int fill)
{
- double x1,y1,x2,y2;
+ double x1,y1,x2,y2, tmp;
double psdash;
x1=X_TO_PS(rectx1);
y1=Y_TO_PS(recty1);
x2=X_TO_PS(rectx2);
y2=Y_TO_PS(recty2);
- if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) )
+ if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&tmp,&tmp,&tmp,&tmp) )
{
psdash = dash / xctx->zoom;
if(dash) {
@@ -852,6 +854,7 @@ static void ps_draw_symbol(int n,int layer, int what, short tmp_flip, short rot,
}
}
+ if((xctx->inst[n].ptr+ xctx->sym)->arcs[layer]) fprintf(fd, "NP\n"); /* newpath */
for(j=0;j< (xctx->inst[n].ptr+ xctx->sym)->arcs[layer]; ++j)
{
double angle;
@@ -958,8 +961,7 @@ static void fill_ps_colors()
}
-/* #define A4 */
-void create_ps(char **psfile, int what)
+void create_ps(char **psfile, int what, int fullzoom)
{
double dx, dy, scale, scaley;
int landscape=1;
@@ -972,11 +974,23 @@ void create_ps(char **psfile, int what)
int c,i, textlayer;
int old_grid;
const char *textfont;
+ static double saveadjustedxorigin,saveadjustedyorigin, saveadjustedzoom, saveadjustedmooz, saveadjustedlw;
+ static double savexorigin, saveyorigin, savezoom, savemooz, savelw;
+ static int savex1, savey1, savex2, savey2, savew, saveh;
+ static int saveadjustedx1, saveadjustedy1, saveadjustedx2, saveadjustedy2, saveadjustedw, saveadjustedh;
+ static XRectangle savexrect, saveadjustedxrect;
+ dbg(1, "create_ps(): what = %d, fullzoom=%d\n", what, fullzoom);
if(tcleval("info exists ps_paper_size")[0] == '1') {
+ double tmp;
my_strncpy(papername, tcleval("lindex $ps_paper_size 0"), S(papername));
pagex = my_atod(tcleval("lindex $ps_paper_size 1"));
pagey = my_atod(tcleval("lindex $ps_paper_size 2"));
+ if(pagex < pagey) { /* start with landscape; later we decide paper orientation */
+ tmp = pagex;
+ pagex = pagey;
+ pagey = tmp;
+ }
}
if(what & 1) { /* prolog */
numpages = 0;
@@ -996,7 +1010,7 @@ void create_ps(char **psfile, int what)
old_grid=tclgetboolvar("draw_grid");
tclsetvar("draw_grid", "0");
-
+ /* xschem window aspect ratio decides if portrait or landscape */
boundbox.x1 = xctx->areax1;
boundbox.x2 = xctx->areax2;
boundbox.y1 = xctx->areay1;
@@ -1004,10 +1018,72 @@ void create_ps(char **psfile, int what)
dx=boundbox.x2-boundbox.x1;
dy=boundbox.y2-boundbox.y1;
- /* xschem window aspect ratio decides if portrait or landscape */
- if(dy > dx) landscape = 0;
- else landscape = 1;
- if(!landscape) {
+ /* xschem drawing bbox decides if portrait or landscape */
+ if(fullzoom) {
+ calc_drawing_bbox(&boundbox, 0);
+ dx=boundbox.x2-boundbox.x1;
+ dy=boundbox.y2-boundbox.y1;
+ }
+ if(dx >= dy) {
+ landscape = 1;
+ } else {
+ landscape = 0;
+ }
+ dbg(1, "dx=%g, dy=%g\n", dx, dy);
+
+
+ if(fullzoom) {
+ /* save size and zoom factor */
+ savexorigin = xctx->xorigin;
+ saveyorigin = xctx->yorigin;
+ savezoom = xctx->zoom;
+ savemooz = xctx->mooz;
+ savelw = xctx->lw;
+ savex1 = xctx->areax1;
+ savex2 = xctx->areax2;
+ savey1 = xctx->areay1;
+ savey2 = xctx->areay2;
+ savew = xctx->areaw;
+ saveh = xctx->areah;
+ savexrect = xctx->xrect[0];
+ /* this zoom only done to reset lw */
+ zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
+ /* adjust aspect ratio to paper size */
+ if(landscape)
+ xctx->xrect[0].height = (short unsigned int) (xctx->xrect[0].width * pagey / pagex);
+ else
+ xctx->xrect[0].width = (short unsigned int) (xctx->xrect[0].height * pagey / pagex);
+ saveadjustedxrect = xctx->xrect[0];
+ dbg(1, "xrect.width=%d, xrect.height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
+ xctx->areax1 = -2*INT_WIDTH(xctx->lw);
+ xctx->areay1 = -2*INT_WIDTH(xctx->lw);
+ xctx->areax2 = xctx->xrect[0].width+2*INT_WIDTH(xctx->lw);
+ xctx->areay2 = xctx->xrect[0].height+2*INT_WIDTH(xctx->lw);
+ xctx->areaw = xctx->areax2-xctx->areax1;
+ xctx->areah = xctx->areay2 - xctx->areay1;
+ dbg(1, "dx=%g, dy=%g\n", dx, dy);
+ /* fit schematic into adjusted size */
+ zoom_full(0, 0, 0 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
+ boundbox.x1 = xctx->areax1;
+ boundbox.x2 = xctx->areax2;
+ boundbox.y1 = xctx->areay1;
+ boundbox.y2 = xctx->areay2;
+ dx=boundbox.x2-boundbox.x1;
+ dy=boundbox.y2-boundbox.y1;
+ saveadjustedlw = xctx->lw;
+ saveadjustedx1 = xctx->areax1;
+ saveadjustedy1 = xctx->areay1;
+ saveadjustedx2 = xctx->areax2;
+ saveadjustedy2 = xctx->areay2;
+ saveadjustedw = xctx->areaw;
+ saveadjustedh = xctx->areah;
+ saveadjustedzoom = xctx->zoom;
+ saveadjustedmooz = xctx->mooz;
+ saveadjustedxorigin = xctx->xorigin;
+ saveadjustedyorigin = xctx->yorigin;
+ }
+
+ if(!landscape) { /* decide paper orientation for best schematic fit */
double tmp;
tmp = pagex;
pagex = pagey;
@@ -1146,20 +1222,43 @@ void create_ps(char **psfile, int what)
{
if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1024)) { /* image */
- xRect* r = &xctx->rect[c][i];
- /* PNG Code Here */
- ps_drawPNG(r, r->x1, r->y1, r->x2, r->y2,0 ,0);
- continue;
+ xRect* r = &xctx->rect[c][i];
+ /* PNG Code Here */
+ ps_drawPNG(r, r->x1, r->y1, r->x2, r->y2,0 ,0);
+ continue;
}
if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */
- xRect* r = &xctx->rect[c][i];
- ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2);
+ xRect* r = &xctx->rect[c][i];
+ ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2);
+ /* restore original size and zoom factor */
+ if(fullzoom) {
+ xctx->xorigin = saveadjustedxorigin;
+ xctx->yorigin = saveadjustedyorigin;
+ xctx->zoom = saveadjustedzoom;
+ xctx->mooz = saveadjustedmooz;
+ xctx->lw = saveadjustedlw;
+ xctx->areax1 = saveadjustedx1;
+ xctx->areax2 = saveadjustedx2;
+ xctx->areay1 = saveadjustedy1;
+ xctx->areay2 = saveadjustedy2;
+ xctx->areaw = saveadjustedw;
+ xctx->areah = saveadjustedh;
+ xctx->xrect[0] = saveadjustedxrect;
+ boundbox.x1 = xctx->areax1;
+ boundbox.x2 = xctx->areax2;
+ boundbox.y1 = xctx->areay1;
+ boundbox.y2 = xctx->areay2;
+ dx=boundbox.x2-boundbox.x1;
+ dy=boundbox.y2-boundbox.y1;
+ change_linewidth(xctx->lw);
+ }
}
if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) ) {
ps_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
xctx->rect[c][i].x2, xctx->rect[c][i].y2, xctx->rect[c][i].dash, xctx->rect[c][i].fill);
}
}
+ if(xctx->arcs[c]) fprintf(fd, "NP\n"); /* newpath */
for(i=0;iarcs[c]; ++i)
{
ps_drawarc(c, xctx->arc[c][i].fill, xctx->arc[c][i].x, xctx->arc[c][i].y,
@@ -1170,6 +1269,11 @@ void create_ps(char **psfile, int what)
xctx->poly[c][i].fill, xctx->poly[c][i].dash);
}
dbg(1, "create_ps(): starting drawing symbols on layer %d\n", c);
+ } /* for(c=0;cinstances; ++i)
ps_draw_symbol(i,c,what,0,0,0.0,0.0);
}
@@ -1183,6 +1287,7 @@ void create_ps(char **psfile, int what)
double x1, y1, x2, y2;
Wireentry *wireptr;
int i;
+ int first = 1;
Iterator_ctx ctx;
update_conn_cues(WIRELAYER, 0, 0);
/* draw connecting dots */
@@ -1191,6 +1296,10 @@ void create_ps(char **psfile, int what)
x2 = X_TO_XSCHEM(xctx->areax2);
y2 = Y_TO_XSCHEM(xctx->areay2);
for(init_wire_iterator(&ctx, x1, y1, x2, y2); ( wireptr = wire_iterator_next(&ctx) ) ;) {
+ if(first) {
+ fprintf(fd, "NP\n"); /* newpath */
+ first = 0;
+ }
i = wireptr->n;
if( xctx->wire[i].end1 >1 ) {
ps_drawarc(WIRELAYER, 1, xctx->wire[i].x1, xctx->wire[i].y1, cadhalfdotsize, 0, 360, 0);
@@ -1211,9 +1320,28 @@ void create_ps(char **psfile, int what)
}
tclsetboolvar("draw_grid", old_grid);
my_free(_ALLOC_ID_, &ps_colors);
+
+
+ /* restore original size and zoom factor */
+ if(fullzoom) {
+ xctx->xorigin = savexorigin;
+ xctx->yorigin = saveyorigin;
+ xctx->zoom = savezoom;
+ xctx->mooz = savemooz;
+ xctx->lw = savelw;
+ xctx->areax1 = savex1;
+ xctx->areax2 = savex2;
+ xctx->areay1 = savey1;
+ xctx->areay2 = savey2;
+ xctx->areaw = savew;
+ xctx->areah = saveh;
+ xctx->xrect[0] = savexrect;
+ change_linewidth(-1.);
+ }
+
}
-int ps_draw(int what)
+int ps_draw(int what, int fullzoom)
{
char tmp[2*PATH_MAX+40];
static char lastdir[PATH_MAX] = "";
@@ -1234,7 +1362,7 @@ int ps_draw(int what)
else return 0;
}
}
- create_ps(&psfile, what);
+ create_ps(&psfile, what, fullzoom);
if(what & 4) { /* trailer */
if(xctx->plotfile[0]) {
my_snprintf(tmp, S(tmp), "convert_to_pdf {%s} {%s}", psfile, xctx->plotfile);
diff --git a/src/scheduler.c b/src/scheduler.c
index fcd1b3f5..2201cfb8 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -1343,7 +1343,20 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
static char res[8192];
Tcl_ResetResult(interp);
my_snprintf(res, S(res), "*******global variables:*******\n"); Tcl_AppendResult(interp, res, NULL);
+
+ my_snprintf(res, S(res), "areax1=%d\n", xctx->areax1); Tcl_AppendResult(interp, res, NULL);
+ my_snprintf(res, S(res), "areay1=%d\n", xctx->areay1); Tcl_AppendResult(interp, res, NULL);
+ my_snprintf(res, S(res), "areax2=%d\n", xctx->areax2); Tcl_AppendResult(interp, res, NULL);
+ my_snprintf(res, S(res), "areay2=%d\n", xctx->areay2); Tcl_AppendResult(interp, res, NULL);
+ my_snprintf(res, S(res), "areaw=%d\n", xctx->areaw); Tcl_AppendResult(interp, res, NULL);
+ my_snprintf(res, S(res), "areah=%d\n", xctx->areah); Tcl_AppendResult(interp, res, NULL);
+ my_snprintf(res, S(res), "xrect[0].width=%d\n",
+ xctx->xrect[0].width); Tcl_AppendResult(interp, res, NULL);
+ my_snprintf(res, S(res), "xrect[0].height=%d\n",
+ xctx->xrect[0].height); Tcl_AppendResult(interp, res, NULL);
+
my_snprintf(res, S(res), "INT_WIDTH(lw)=%d\n", INT_WIDTH(xctx->lw)); Tcl_AppendResult(interp, res, NULL);
+ my_snprintf(res, S(res), "lw=%g\n", xctx->lw); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "wires=%d\n", xctx->wires); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "instances=%d\n", xctx->instances); Tcl_AppendResult(interp, res, NULL);
my_snprintf(res, S(res), "symbols=%d\n", xctx->symbols); Tcl_AppendResult(interp, res, NULL);
@@ -2541,6 +2554,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* xschem print svg file.svg 400 300 [ -300 -200 300 200 ]
* xschem print ps file.ps
* xschem print pdf file.pdf
+ * xschem print ps_full file.ps
+ * xschem print pdf_full file.pdf
*/
else if(!strcmp(argv[1], "print") )
{
@@ -2553,7 +2568,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
my_strncpy(xctx->plotfile, Tcl_GetStringResult(interp), S(xctx->plotfile));
}
if(!strcmp(argv[2], "pdf") || !strcmp(argv[2],"ps")) {
- ps_draw(7);
+ int fullzoom = 0;
+ ps_draw(7, fullzoom);
+ }
+ else if(!strcmp(argv[2], "pdf_full") || !strcmp(argv[2],"ps_full")) {
+ int fullzoom = 1;
+ ps_draw(7, fullzoom);
}
else if(!strcmp(argv[2], "png")) {
int w = 0, h = 0;
diff --git a/src/spice_netlist.c b/src/spice_netlist.c
index cb2e0a95..edad9d13 100644
--- a/src/spice_netlist.c
+++ b/src/spice_netlist.c
@@ -54,11 +54,11 @@ void hier_psprint(char **res, int what) /* netlister driver */
save = xctx->do_copy_area;
xctx->do_copy_area = 0;
- if((what & 1) && !ps_draw(1)) return; /* prolog */
+ if((what & 1) && !ps_draw(1, 1)) return; /* prolog */
xctx->push_undo();
str_hash_init(&subckt_table, HASHSIZE);
zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
- if(what & 1) ps_draw(2); /* page */
+ if(what & 1) ps_draw(2, 1); /* page */
if(what & 2) { /* print cellname */
my_strcat(_ALLOC_ID_, res, hier_psprint_mtime(xctx->sch[xctx->currsch]));
my_strcat(_ALLOC_ID_, res, " {");
@@ -99,7 +99,7 @@ void hier_psprint(char **res, int what) /* netlister driver */
load_schematic(1,filename, 0, 1);
get_additional_symbols(1);
zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
- if(what & 1) ps_draw(2); /* page */
+ if(what & 1) ps_draw(2, 1); /* page */
if(what & 2) { /* print cellname */
my_strcat(_ALLOC_ID_, res, hier_psprint_mtime(xctx->sch[xctx->currsch]));
my_strcat(_ALLOC_ID_, res, " {");
@@ -122,7 +122,7 @@ void hier_psprint(char **res, int what) /* netlister driver */
xctx->pop_undo(4, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
xctx->do_copy_area = save;
- if(what & 1) ps_draw(4); /* trailer */
+ if(what & 1) ps_draw(4, 1); /* trailer */
zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
draw();
}
diff --git a/src/xinit.c b/src/xinit.c
index ff185975..56cb07db 100644
--- a/src/xinit.c
+++ b/src/xinit.c
@@ -2096,7 +2096,7 @@ void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h)
XSetFillStyle(display,xctx->gctiled,FillTiled);
/* whenever a pixmap is recreated all GC attributes must be reissued */
resetcairo(1, 0, 1); /* create, clear, force */
- change_linewidth(-1.0);
+ /* change_linewidth(-1.0); */
}
}
}
@@ -2761,7 +2761,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
xctx->areaw = xctx->areax2-xctx->areax1;
xctx->areah = xctx->areay2-xctx->areay1;
zoom_full(0, 0, 2 * tclgetboolvar("zoom_full_center"), 0.97);
- ps_draw(7);
+ ps_draw(7, 0);
} else if(cli_opt_do_print == 2) {
if(!has_x) {
dbg(0, "xschem: can not do a png export if no X11 present / Xserver running (check if DISPLAY set).\n");
diff --git a/src/xschem.h b/src/xschem.h
index 73609a88..bba99950 100644
--- a/src/xschem.h
+++ b/src/xschem.h
@@ -1201,7 +1201,7 @@ extern Hilight_hashentry *hilight_lookup(const char *token, int value, int what)
extern int search(const char *tok, const char *val, int sub, int sel, int match_case);
extern int process_options(int argc, char **argv);
extern void calc_drawing_bbox(xRect *boundbox, int selected);
-extern int ps_draw(int what);
+extern int ps_draw(int what, int fullzoom);
extern void svg_draw(void);
extern void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2, double ry2);
extern void set_viewport_size(int w, int h, double lw);
@@ -1577,6 +1577,6 @@ extern void del_wire_table(void);
extern void del_object_table(void);
extern const char *create_tmpdir(char *prefix);
extern FILE *open_tmpfile(char *prefix, char **filename);
-extern void create_ps(char** psfile, int what);
+extern void create_ps(char** psfile, int what, int fullzoom);
extern void MyXCopyArea(Display* display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned int height, int dest_x, int dest_y);
#endif /*CADGLOBALS */
diff --git a/src/xschem.tcl b/src/xschem.tcl
index 6942b2e7..4ab8aec3 100644
--- a/src/xschem.tcl
+++ b/src/xschem.tcl
@@ -5847,6 +5847,7 @@ proc build_widgets { {topwin {} } } {
-command "xschem saveas {} symbol" -accelerator {Ctrl+Alt+S}
# added svg, png 20171022
$topwin.menubar.file.menu add command -label "PDF/PS Export" -command "xschem print pdf" -accelerator {*}
+ $topwin.menubar.file.menu add command -label "PDF/PS Export Full" -command "xschem print pdf_full" -accelerator {*}
$topwin.menubar.file.menu add command -label "Hierarchical PDF/PS Export" -command "xschem hier_psprint"
$topwin.menubar.file.menu add command -label "PNG Export" -command "xschem print png" -accelerator {Ctrl+*}
$topwin.menubar.file.menu add command -label "SVG Export" -command "xschem print svg" -accelerator {Alt+*}