From cf675be8054222a68ec7ac680814455795d56667 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 13 Jul 2023 13:24:17 +0200 Subject: [PATCH] add "xschem print pdf_full" and "xschem print ps_full" commands to print full view properly fitting paper size, regardless of xschem window size, some fixes in circle postscript drawing (set newpath) and rectangle clipping. Add menu command "PDF/PS export full" --- doc/xschem_man/developer_info.html | 5 +- src/callback.c | 2 +- src/draw.c | 2 +- src/psprint.c | 168 +++++++++++++++++++++++++---- src/scheduler.c | 22 +++- src/spice_netlist.c | 8 +- src/xinit.c | 4 +- src/xschem.h | 4 +- src/xschem.tcl | 1 + 9 files changed, 184 insertions(+), 32 deletions(-) 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" +
  • abort_operation
  •     Resets UI state, unselect all and abort any pending operation 
  • add_symbol_pin
  • @@ -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
  • print_hilight_net show
  •     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+*}