[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-user: PostScript patch for Windows ps.c attached



Here is my patch for hid/ps/ps.c that fixes the error
and naviagation issues with PostScript on Windows.
As far as I can tell it did not break anything on Linux either.
Most of the changes relate to PostScript headers,
and footers.  I'll add my fabnote idea as an other patch.

The patch also adds a "1. Table of Contents (This Page)"
and the time on the index page, which is the only
visible change to someone looking at the printout.

A couple of things in the patch need to be changed,
before commiting.  The headers <stdarg.h> and <assert.h> are not actually
used in ps.c.  Didn't know if there was a reason to
keep them?  Delete them or the 'not used' comments.
I also have Peter's GL change commented out as
I did not know if it was compatible with then none
GL version.

I could not duplicate Mark's problem with random
outline layers being inserted, with either the GL
or GTK version.

======Cut Here=====
--- ps.c.org	2009-03-10 06:11:06.000000000 -0400
+++ ps.c	2009-03-08 17:56:27.000000000 -0400
@@ -5,10 +5,11 @@
 #endif

 #include <stdio.h>
-#include <stdarg.h>
+#include <stdarg.h> /* not used */
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
+#include <assert.h> /* not used */
+#include <time.h>

 #include "global.h"
 #include "data.h"
@@ -55,13 +56,13 @@
 static int multi_file = 0;
 static double media_width, media_height, ps_width, ps_height;

-static const char *medias[] = {
+static const char *medias[] = {
   "A0", "A1", "A2", "A3", "A4", "A5",
   "A6", "A7", "A8", "A9", "A10",
   "B0", "B1", "B2", "B3", "B4", "B5",
   "B6", "B7", "B8", "B9", "B10",
   "Letter", "11x17", "Ledger",
-  "Legal", "Executive",
+  "Legal", "Executive",
   "A-Size", "B-size",
   "C-Size", "D-size", "E-size",
   "US-Business_Card", "Intl-Business_Card",
@@ -270,13 +271,118 @@
 void
 ps_start_file (FILE *f)
 {
-  fprintf (f, "%%!PS-Adobe-3.0\n\n");
+  time_t currenttime = time( NULL );
+
+  fprintf (f, "%%!PS-Adobe-3.0\n");
+
+  /* Document Structuring Conventions (DCS): */
+
+  /* Start General Header Comments: */
+
+  fprintf (f, "%%%%Title: %s\n", PCB->Filename);
+  /*
+   * %%Title DCS provides a text title for the document that is useful
+   * for printing banner pages and for routing or recognizing
+   * documents.
+   */
+
+  fprintf (f, "%%%%CreationDate: %s", asctime (localtime (&currenttime)));
+
+  /*
+   * %%CreationDate DCS indicates the date and time the document was
+   * created. Neither the date nor time need be in any standard
+   * format. This comment is meant to be used purely for informational
+   * purposes, such as printing on banner pages.
+   */
+
+  fprintf (f, "%%%%Creator: PCB release: %s " VERSION "\n", Progname);
+  /*
+   * %%Creator DCS indicates the document creator, usually the name of
+   * the document composition software.
+   */
+
+  fprintf (f, "%%%%Version: (PCB %s " VERSION ") 0.0 0\n", Progname );
+  /*
+   * %%Version DCS comment can be used to note the version and
+   * revision number of a document or resource. A document manager may
+   * wish to provide version control services, or allow substitution
+   * of compatible versions/revisions of a resource or document.
+   *
+   * The format should be in the form of 'procname':
+   *  <procname>::= < name> < version> < revision>
+   *  < name> ::= < text>
+   *  < version> ::= < real>
+   *  < revision> ::= < uint>
+   *
+   * If a version numbering scheme is not used, these fields should
+   * still be filled with a dummy value of 0.
+   *
+   * There is currently no code in PCB to manage this revision number.
+   *
+   */
+
+  fprintf (f, "%%%%PageOrder: Ascend\n" );
+  /*
+   * %%PageOrder DCS is intended to help document managers determine
+   * the order of pages in the document file, which in turn enables a
+   * document manager optionally to reorder the pages.  'Ascend'-The
+   * pages are in ascending order-for example, 1-2-3-4-5.
+   */
+
+  fprintf (f, "%%%%Pages: (atend)\n" );
+  /*
+   * %%Pages: < numpages> | (atend) < numpages> ::= < uint> (Total
+   * %%number of pages)
+   *
+   * Pages DCS defines the number of virtual pages
+   * %%that a document will image.
+   */
+
+  /* End General Header Comments. */
+
+  /* General Body Comments go here. Currently there are none. */
+
+  fprintf (f, "%%%%EndComments\n\n" );
+  /*
+   * %%EndComments DCS indicates an explicit end to the header
+   * comments of the document.  All global DCS's must preceded
+   * this.
+   */
+}
+
+static void
+ps_end_file (FILE *f)
+{
+  fprintf (f, "%%%%Trailer\n" );
+  /*
+   * %%Trailer DCS must only occur once at the end of the document script.
+   * Any post-processing or cleanup should be contained in the trailer of
+   * the document, which is anything that follows the %%Trailer
+   * comment. Any of the document-level structure comments that were
+   * deferred by using the (atend) convention must be mentioned in the
+   * trailer of the document after the %%Trailer comment.
+   */
+
+  fprintf (f, "%%%%Pages: %d\n", pagecount );
+  /*
+   * %%Pages was deferred until the end of the document via the
+   * (atend) mentioned, in the General Header section.
+   */
+
+  fprintf (f, "%%%%EOF\n" );
+  /*
+   * %%EOF DCS signifies the end of the document. When the document
+   * manager sees this comment, it issues an end-of-file signal to the
+   * PostScript interpreter. This is done so system-dependent file
+   * endings, such as Control-D and end-of-file packets, do not
+   * confuse the PostScript interpreter.
+   */
 }

 static FILE *
 psopen (const char *base, const char *which)
 {
-  FILE *f;
+  FILE *ps_open_file;
   char *buf, *suff, *buf2;

   if (!multi_file)
@@ -296,9 +402,9 @@
       sprintf(buf, "%s.%s.ps", base, which);
     }
   printf("PS: open %s\n", buf);
-  f = fopen(buf, "w");
+  ps_open_file = fopen(buf, "w");
   free (buf);
-  return f;
+  return ps_open_file;
 }

 static BoxType region;
@@ -405,19 +511,20 @@

   if (! multi_file)
     {
-      pagecount = 1;
-      fprintf (f, "%%%%Page: 1\n");
+      fprintf (f, "%%%%Page: TableOfContents 1\n");  /* %%Page DSC
requires both a label and an ordinal */
       fprintf (f, "/Times-Roman findfont 24 scalefont setfont\n");
       fprintf (f,
 	       "/rightshow { /s exch def s stringwidth pop -1 mul 0 rmoveto
s show } def\n");
       fprintf (f,
 	       "/y 72 9 mul def /toc { 100 y moveto show /y y 24 sub def }
bind def\n");
       fprintf (f, "/tocp { /y y 12 sub def 90 y moveto rightshow }
bind def\n");
+
       doing_toc = 1;
+      pagecount = 1;      /* 'pagecount' is modified by
hid_expose_callback() call */
       hid_expose_callback (&ps_hid, &region, 0);
     }

-  pagecount = 1;
+  pagecount = 1; /* Reset 'pagecount' if single file */
   doing_toc = 0;
   lastgroup = -1;
   hid_expose_callback (&ps_hid, &region, 0);
@@ -468,7 +575,10 @@

   multi_file = 0;
   if (f)
-   fclose (f);
+    {
+      ps_end_file (f);
+      fclose (f);
+    }
 }

 extern void hid_parse_command_line (int *argc, char ***argv);
@@ -493,6 +603,14 @@
   int len2 = 20000;
 #endif
   int thick = 0;
+  /*
+   * Originally 'thick' used thicker lines.  Currently is uses
+   * Postscript's "device thin" line - i.e. zero width means one
+   * device pixel.  The code remains in case you want to make them
+   * thicker - it needs to offset everything so that the *edge* of the
+   * thick line lines up with the edge of the board, not the *center*
+   * of the thick line.
+   */

   fprintf (f, "gsave %d setlinewidth %d %d translate %d %d scale\n",
 	   thick * 2, x, y, dx, dy);
@@ -513,6 +631,7 @@
 static int
 ps_set_layer (const char *name, int group, int empty)
 {
+  time_t currenttime;
   int idx = (group >= 0
 	     && group <
 	     max_layer) ? PCB->LayerGroups.Entries[group][0] : group;
@@ -542,6 +661,18 @@
     {
       if (group < 0 || group != lastgroup)
 	{
+          if( 1 == pagecount )
+            {
+              currenttime = time( NULL );
+              fprintf (f, "30 30 moveto (%s) show\n", PCB->Filename);
+
+              fprintf (f, "(%d.) tocp\n", pagecount);
+              fprintf (f, "(Table of Contents \\(This Page\\)) toc\n" );
+
+              fprintf (f, "(Created on %s) toc\n", asctime (localtime
(&currenttime)));
+              fprintf (f, "( ) tocp\n" );
+            }
+
 	  pagecount++;
 	  lastgroup = group;
 	  fprintf (f, "(%d.) tocp\n", pagecount);
@@ -564,17 +695,30 @@
       if (multi_file)
 	{
 	  if (f)
-	    fclose (f);
+            {
+              ps_end_file (f);
+              fclose (f);
+            }
 	  f = psopen (filename, layer_type_to_file_name (idx));
 	  if (!f)
 	  {
 	    perror(filename);
 	    return 0;
 	  }
-		
+
 	  ps_start_file (f);
 	}
-      fprintf (f, "%%%%Page: %d\n", pagecount);
+
+      fprintf (f, "%%%%Page: %s %d\n", layer_type_to_file_name(idx),
pagecount);
+      /*
+       * %%Page DSC comment marks the beginning of the PostScript
+       * language instructions that describe a particular
+       * page. %%Page: requires two arguments: a page label and a
+       * sequential page number. The label may be anything, but the
+       * ordinal page number must reflect the position of that page in
+       * the body of the PostScript language file and must start with
+       * 1, not 0.
+       */

       if (mirror)
 	mirror_this = 1 - mirror_this;
@@ -585,7 +729,7 @@
 	mirror_this = 1 - mirror_this;

       fprintf (f, "/Helvetica findfont 10 scalefont setfont\n");
-      if (legend)
+      if (legend)
 	{
 	  fprintf (f, "30 30 moveto (%s) show\n", PCB->Filename);
 	  if (PCB->Name)
@@ -596,16 +740,16 @@
 		     layer_type_to_file_name (idx));
 	  if (mirror_this)
 	    fprintf (f, "( \\(mirrored\\)) show\n");
-	
+
 	  if (fillpage)
 	    fprintf (f, "(, not to scale) show\n");
 	  else
 	    fprintf (f, "(, scale = 1:%.3f) show\n", scale_value);
 	}
       fprintf (f, "newpath\n");
-
+
       fprintf (f, "72 72 scale %g %g translate\n", 0.5*media_width,
0.5*media_height);
-
+
       boffset = 0.5*media_height;
       if (PCB->MaxWidth > PCB->MaxHeight)
 	{
@@ -950,15 +1094,11 @@
   use_gc (gc);
   if (x1 > x2)
     {
-      int t = x1;
-      x2 = x2;
-      x2 = t;
+      x2 = x1;
     }
   if (y1 > y2)
     {
-      int t = y1;
-      y2 = y2;
-      y2 = t;
+      y2 = y1;
     }
 #if 0
   /* See comment in ps_draw_line.  */
@@ -984,8 +1124,13 @@
 };

 static const char * const calib_lines[] = {
-  "%!PS-Adobe\n",
+  "%!PS-Adobe-3.0\n",
+  "%%Title: Calibration Page\n",
+  "%%PageOrder: Ascend\n",
+  "%%Pages: 1\n",
+  "%%EndComments\n",
   "\n",
+  "%%Page: Calibrate 1\n",
   "72 72 scale\n",
   "\n",
   "0 setlinewidth\n",
@@ -1070,7 +1215,7 @@
 ps_calibrate_1 (double xval, double yval, int use_command)
 {
   HID_Attr_Val vals[3];
-  FILE *f;
+  FILE *ps_cal_file;
   int used_popen = 0, c;

   if (xval > 0 && yval > 0)
@@ -1113,29 +1258,31 @@
       char *cmd = vals[0].str_value;
       while (*cmd == ' ' || *cmd == '|')
 	cmd ++;
-      f = popen (cmd, "w");
+      ps_cal_file = popen (cmd, "w");
       used_popen = 1;
     }
   else
-    f = fopen (vals[0].str_value, "w");
+    ps_cal_file = fopen (vals[0].str_value, "w");

   for (c=0; calib_lines[c]; c++)
-    fputs(calib_lines[c], f);
+    fputs(calib_lines[c], ps_cal_file);
+
+  fprintf (ps_cal_file, "4 in 0.5 (Y in) cbar\n");
+  fprintf (ps_cal_file, "20 cm 1.5 (Y cm) cbar\n");
+  fprintf (ps_cal_file, "10 in 2.5 (Y in) cbar\n");
+  fprintf (ps_cal_file, "-90 rotate\n");
+  fprintf (ps_cal_file, "4 in -0.5 (X in) cbar\n");
+  fprintf (ps_cal_file, "15 cm -1.5 (X cm) cbar\n");
+  fprintf (ps_cal_file, "7.5 in -2.5 (X in) cbar\n");

-  fprintf (f, "4 in 0.5 (Y in) cbar\n");
-  fprintf (f, "20 cm 1.5 (Y cm) cbar\n");
-  fprintf (f, "10 in 2.5 (Y in) cbar\n");
-  fprintf (f, "-90 rotate\n");
-  fprintf (f, "4 in -0.5 (X in) cbar\n");
-  fprintf (f, "15 cm -1.5 (X cm) cbar\n");
-  fprintf (f, "7.5 in -2.5 (X in) cbar\n");
+  fprintf (ps_cal_file, "showpage\n");

-  fprintf (f, "showpage\n");
+  fprintf (ps_cal_file, "%%%%EOF\n");

   if (used_popen)
-    pclose (f);
+    pclose (ps_cal_file);
   else
-    fclose (f);
+    fclose (ps_cal_file);
 }

 static void


_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user