home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / lout2.lzh / LOUT2 / z24.c < prev    next >
Text File  |  1994-01-23  |  34KB  |  695 lines

  1. /*@z24.c:Print Service:PrintInit()@*******************************************/
  2. /*                                                                           */
  3. /*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05)       */
  4. /*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  5. /*                                                                           */
  6. /*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  7. /*  Basser Department of Computer Science                                    */
  8. /*  The University of Sydney 2006                                            */
  9. /*  AUSTRALIA                                                                */
  10. /*                                                                           */
  11. /*  This program is free software; you can redistribute it and/or modify     */
  12. /*  it under the terms of the GNU General Public License as published by     */
  13. /*  the Free Software Foundation; either version 1, or (at your option)      */
  14. /*  any later version.                                                       */
  15. /*                                                                           */
  16. /*  This program is distributed in the hope that it will be useful,          */
  17. /*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  18. /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  19. /*  GNU General Public License for more details.                             */
  20. /*                                                                           */
  21. /*  You should have received a copy of the GNU General Public License        */
  22. /*  along with this program; if not, write to the Free Software              */
  23. /*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  24. /*                                                                           */
  25. /*  FILE:         z24.c                                                      */
  26. /*  MODULE:       Print Service                                              */
  27. /*  EXTERNS:      PrintInit(), PrintPrologue(), PrintOriginIncrement(),      */
  28. /*                PrintWord(), PrintClose(), CoordTranslate(),               */
  29. /*                CoordRotate(), CoordScale(), SaveGraphicState(),           */
  30. /*                RestoreGraphicState(), PrintGraphicObject(),               */
  31. /*                DefineGraphicNames(), PrintGraphicInclude()                */
  32. /*                                                                           */
  33. /*  This module implements the PostScript back end.                          */
  34. /*                                                                           */
  35. /*****************************************************************************/
  36. #include "externs"
  37. #define DEFAULT_XHEIGHT 500
  38. #define    NO_FONT    0            /* actually stolen from z37.c        */
  39.  
  40. #define printnum(x, fp)                            \
  41. { char buff[20];  register int i, y;                    \
  42.   if( x >= 0 )  y = x;                            \
  43.   else { y = -x; putc(CH_MINUS, fp); }                    \
  44.   i = 0;                                \
  45.   do { buff[i++] = numtodigitchar(y % 10);                \
  46.      } while( y = y / 10 );                        \
  47.   do { putc(buff[--i], fp);                        \
  48.      } while( i );                            \
  49. }
  50.  
  51. static FILE    *out_fp;        /* output file                       */
  52. static FONT_NUM    currentfont;        /* font of most recent atom          */
  53. static short    currentxheight2;    /* half xheight in current font      */
  54. static BOOLEAN    cpexists;        /* true if a current point exists    */
  55. static LENGTH    currenty;        /* if cpexists, its y coordinate     */
  56. static int    wordcount;        /* atoms printed since last newline  */
  57. static int    pagecount;        /* total number of pages printed     */
  58. static BOOLEAN    prologue_done;        /* TRUE after prologue is printed    */
  59. static OBJECT    needs;            /* Resource needs of included EPSFs  */
  60.  
  61.  
  62. /*****************************************************************************/
  63. /*                                                                           */
  64. /*  PrintInit(file_ptr)                                                      */
  65. /*                                                                           */
  66. /*  Initialise this module.  Output is to go to FILE file_ptr.               */
  67. /*                                                                           */
  68. /*****************************************************************************/
  69.  
  70. PrintInit(file_ptr)
  71. FILE *file_ptr;
  72. { debug0(DFT, D, "PrintInit()");
  73.   out_fp = file_ptr;  prologue_done = FALSE;
  74.   currentfont = NO_FONT;  cpexists = FALSE;
  75.   wordcount = pagecount = 0;  needs = New(ACAT);
  76.   debug0(DFT, D, "PrintInit returning.");
  77. }
  78.  
  79.  
  80. /*@::PrintPrologue@***********************************************************/
  81. /*                                                                           */
  82. /*  PrintPrologue(h, v)                                                      */
  83. /*                                                                           */
  84. /*  Generate the standard PostScript prologue, augmented with any @Prologue  */
  85. /*  or @SysPrologue files specified by the user.                             */
  86. /*  The first non-empty page has width h and height v in Lout units.         */
  87. /*  The following PostScript operators are defined:                          */
  88. /*                                                                           */
  89. /*      scale_factor  fnt       scale and set font                           */
  90. /*      x_coordinate  x         move to x_coordinate, current y coordinate   */
  91. /*      string        s         show string                                  */
  92. /*      number        in        result is number inches                      */
  93. /*      number        cm        result is number centimetres                 */
  94. /*      number        pt        result is number points                      */
  95. /*      number        sp        result is number spaces                      */
  96. /*      number        vs        result is number vspaces                     */
  97. /*      number        ft        result is number font-sizes                  */
  98. /*                                                                           */
  99. /*  as well as LoutGraphic, for use with the @Graphic operator:              */
  100. /*                                                                           */
  101. /*      xsize ysize xmark ymark fr vs sp LoutGraphic -                       */
  102. /*                                                                           */
  103. /*  Define xmark, ymark, xsize, ysize to be the positions of                 */
  104. /*  these features of x, and define symbols ft, vs and sp                    */
  105. /*  to be the current font size, line separation, and space width.           */
  106. /*                                                                           */
  107. /*****************************************************************************/
  108.  
  109. PrintPrologue(h, v)
  110. LENGTH h, v;
  111. { FILE_NUM fnum;
  112.   debug2(DGP, DD, "PrintPrologue: v = %d   h = %d", v, h);
  113.  
  114.   /* print header comments for PostScript DSC 3.0 output */
  115.   if( Encapsulated )
  116.     fprintf(out_fp, "%%%!PS-Adobe-3.0 EPSF-3.0\n");
  117.   else
  118.     fprintf(out_fp, "%%%!PS-Adobe-3.0\n");
  119.   fprintf(out_fp, "%%%%Creator: %s\n", LOUT_VERSION);
  120.   fprintf(out_fp, "%%%%CreationDate: %s", TimeString());
  121.   fprintf(out_fp, "%%%%DocumentNeededResources: (atend)\n");
  122.   fprintf(out_fp, "%%%%Pages: (atend)\n");
  123.   fprintf(out_fp, "%%%%BoundingBox: 0 0 %d %d\n", h/PT, v/PT);
  124.   fprintf(out_fp, "%%%%EndComments\n\n");
  125.  
  126.   /* print procedure definitions part of header */
  127.   fprintf(out_fp, "%%%%BeginProlog\n");
  128.   fprintf(out_fp, "%%%%BeginResource: procset LoutStartUp\n");
  129.   fprintf(out_fp, "/x { currentpoint exch pop moveto } def\n");
  130.   fprintf(out_fp, "/s { show } def\n");
  131.   fprintf(out_fp, "/in { %d mul } def\n", IN);
  132.   fprintf(out_fp, "/cm { %d mul } def\n", CM);
  133.   fprintf(out_fp, "/pt { %d mul } def\n", PT);
  134.   fprintf(out_fp, "/em { %d mul } def\n", EM);
  135.   fprintf(out_fp, "/sp { louts mul } def\n");
  136.   fprintf(out_fp, "/vs { loutv mul } def\n");
  137.   fprintf(out_fp, "/ft { loutf mul } def\n");
  138.   fprintf(out_fp, "/dg {           } def\n\n");
  139.  
  140.   fputs("/LoutGraphic {\n",                      out_fp);
  141.   fputs("  /louts exch def\n",                      out_fp);
  142.   fputs("  /loutv exch def\n",                      out_fp);
  143.   fputs("  /loutf exch def\n",                      out_fp);
  144.   fputs("  /ymark exch def\n",                      out_fp);
  145.   fputs("  /xmark exch def\n",                      out_fp);
  146.   fputs("  /ysize exch def\n",                      out_fp);
  147.   fputs("  /xsize exch def\n} def\n\n",                  out_fp);
  148.  
  149.   /* print definition used by Lout output to recode fonts                 */
  150.   /* adapted from PostScript Language Reference Manual (2nd Ed), page 275 */
  151.   /* usage: /<fullname> <encodingvector> /<originalname> LoutRecode -     */
  152.  
  153.   fputs("/LoutFont\n",                                            out_fp);
  154.   fputs("{ findfont exch scalefont setfont\n",                    out_fp);
  155.   fputs("} bind def\n\n",                      out_fp);
  156.  
  157.   fputs("/LoutRecode {\n",                                        out_fp);
  158.   fputs("  { findfont dup length dict begin\n",                   out_fp);
  159.   fputs("    {1 index /FID ne {def} {pop pop} ifelse} forall\n",  out_fp);
  160.   fputs("    /Encoding exch def\n",                               out_fp);
  161.   fputs("    currentdict end definefont pop\n",                   out_fp);
  162.   fputs("  }\n",                                                  out_fp);
  163.   fputs("  stopped {}\n",                                         out_fp);
  164.   fputs("} bind def\n\n",                                         out_fp);
  165.  
  166.   /* print definitions used by Lout output when including EPSF files      */
  167.   /* copied from PostScript Language Reference Manual (2nd Ed.), page 726 */
  168.  
  169.   fputs("/BeginEPSF {\n",                      out_fp);
  170.   fputs("  /LoutEPSFState save def\n",                  out_fp);
  171.   fputs("  /dict_count countdictstack def\n",              out_fp);
  172.   fputs("  /op_count count 1 sub def\n",              out_fp);
  173.   fputs("  userdict begin\n",                      out_fp);
  174.   fputs("  /showpage { } def\n",                  out_fp);
  175.   fputs("  0 setgray 0 setlinecap\n",                  out_fp);
  176.   fputs("  1 setlinewidth 0 setlinejoin\n",              out_fp);
  177.   fputs("  10 setmiterlimit [] 0 setdash newpath\n",          out_fp);
  178.   fputs("  /languagelevel where\n",                  out_fp);
  179.   fputs("  { pop languagelevel\n",                  out_fp);
  180.   fputs("    1 ne\n",                          out_fp);
  181.   fputs("    { false setstrokeadjust false setoverprint\n",      out_fp);
  182.   fputs("    } if\n",                          out_fp);
  183.   fputs("  } if\n",                          out_fp);
  184.   fputs("} bind def\n\n",                      out_fp);
  185.  
  186.   fputs("/EndEPSF {\n",                          out_fp);
  187.   fputs("  count op_count sub { pop } repeat\n",          out_fp);
  188.   fputs("  countdictstack dict_count sub { end } repeat\n",      out_fp);
  189.   fputs("  LoutEPSFState restore\n",                  out_fp);
  190.   fputs("} bind def\n",                          out_fp);
  191.  
  192.   fputs("%%EndResource\n\n",                      out_fp);
  193.  
  194.   /* print encoding vectors and font recoding commands */
  195.   EvPrintAll(out_fp);
  196.   FontPrintAll(out_fp);
  197.  
  198.   /* print prepend files (assumed to be organized as DSC 3.0 Resources) */
  199.   for( fnum=FirstFile(PREPEND_FILE);  fnum != NO_FILE;  fnum=NextFile(fnum) )
  200.   { FULL_CHAR buff[MAX_LINE];  FILE *fp;
  201.     if( (fp = OpenFile(fnum, FALSE, FALSE)) == null )
  202.       Error(WARN, PosOfFile(fnum), "cannot open %s file %s",
  203.     KW_PREPEND, FileName(fnum));
  204.     else if( StringFGets(buff, MAX_LINE, fp) == NULL )
  205.       Error(WARN, PosOfFile(fnum), "%s file %s is empty",
  206.     KW_PREPEND, FileName(fnum));
  207.     else
  208.     {
  209.       if( !StringBeginsWith(buff, AsciiToFull("%%BeginResource:")) )
  210.     Error(WARN, PosOfFile(fnum),
  211.       "%s file %s lacks PostScript DSC 3.0 \"%%%%BeginResource:\" comment",
  212.       KW_PREPEND, FileName(fnum));
  213.       StringFPuts(buff, out_fp);
  214.       fprintf(out_fp, "\n%% %s file %s\n", KW_PREPEND, FileName(fnum));
  215.       while( StringFGets(buff, MAX_LINE, fp) != NULL )
  216.     StringFPuts(buff, out_fp);
  217.     }
  218.   }
  219.  
  220.   fputs("\n%%EndProlog\n\n", out_fp);
  221.   fprintf(out_fp, "%%%%Page: ? %d\n", ++pagecount);
  222.   fprintf(out_fp, "%%%%BeginPageSetup\n");
  223.   fprintf(out_fp, "/pgsave save def\n");
  224.   fprintf(out_fp, "%.4f dup scale %d setlinewidth\n", 1.0 / PT, PT/2);
  225.   fprintf(out_fp, "%%%%EndPageSetup\n");
  226.   prologue_done = TRUE;
  227. } /* end PrintPrologue */
  228.  
  229.  
  230. /*@::PrintOriginIncrement(), EightBitsToPrintForm[]@**************************/
  231. /*                                                                           */
  232. /*  PrintOriginIncrement(y)                                                  */
  233. /*                                                                           */
  234. /*  Move current vertical origin down by y.                                  */
  235. /*                                                                           */
  236. /*****************************************************************************/
  237.  
  238. PrintOriginIncrement(y)
  239. LENGTH y;
  240. { debug1(DGP, D, "PrintOriginIncrement( %d )", y );
  241.   fprintf(out_fp, "\npgsave restore\nshowpage\n");
  242.   cpexists = FALSE;
  243.   currentfont = NO_FONT;
  244.   if( Encapsulated )
  245.   { PrintClose();
  246.     Error(FATAL, no_fpos, "truncating -EPS document at end of first page");
  247.   }
  248.   fprintf(out_fp, "\n%%%%Page: ? %d\n", ++pagecount);
  249.   fprintf(out_fp, "%%%%BeginPageSetup\n");
  250.   fprintf(out_fp, "/pgsave save def\n");
  251.   fprintf(out_fp, "%.4f dup scale %d setlinewidth\n", 1.0 / PT, PT/2);
  252.   fprintf(out_fp, "%%%%EndPageSetup\n");
  253.   wordcount = 0;
  254. }
  255.  
  256. /*@::EightBitToPrintForm()@***************************************************/
  257. /*                                                                           */
  258. /*  static char *EightBitToPrintForm[]                                       */
  259. /*                                                                           */
  260. /*  Given 8-bit character i, returns a string of characters that will be     */
  261. /*  interpreted by PostScript as character i when read within a string.      */
  262. /*                                                                           */
  263. /*      CHAR_OUT==1    Printable ASCII literal, others as escape sequences   */
  264. /*      CHAR_OUT==2    Printable ISO-LATIN-1 literal, others escaped         */
  265. /*                                                                           */
  266. /*****************************************************************************/
  267.  
  268. static char *EightBitToPrintForm[] = {
  269. #if CHAR_OUT==0
  270.     "",      "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
  271.     "\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017",
  272.     "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027",
  273.     "\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037",
  274.     " ",     "!",     "\"",    "#",     "$",     "%",     "&",     "'",
  275.     "\\(",   "\\)",   "*",     "+",     ",",     "-",     ".",     "/",
  276.     "0",     "1",     "2",     "3",     "4",     "5",     "6",     "7",
  277.     "8",     "9",     ":",     ";",     "<",     "=",     ">",     "?",
  278.     "@",     "A",     "B",     "C",     "D",     "E",     "F",     "G",
  279.     "H",     "I",     "J",     "K",     "L",     "M",     "N",     "O",
  280.     "P",     "Q",     "R",     "S",     "T",     "U",     "V",     "W",
  281.     "X",     "Y",     "Z",     "[",     "\\\\",  "]",     "^",     "_",
  282.     "`",     "a",     "b",     "c",     "d",     "e",     "f",     "g",
  283.     "h",     "i",     "j",     "k",     "l",     "m",     "n",     "o",
  284.     "p",     "q",     "r",     "s",     "t",     "u",     "v",     "w",
  285.     "x",     "y",     "z",     "{",     "|",     "}",     "~",     "\\177",
  286.     "\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
  287.     "\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
  288.     "\\220", "\\221", "\\222", "\\223", "\\224", "\\225", "\\226", "\\227",
  289.     "\\230", "\\231", "\\232", "\\233", "\\234", "\\235", "\\236", "\\237",
  290.     "\\240", "\\241", "\\242", "\\243", "\\244", "\\245", "\\246", "\\247",
  291.     "\\250", "\\251", "\\252", "\\253", "\\254", "\\255", "\\256", "\\257",
  292.     "\\260", "\\261", "\\262", "\\263", "\\264", "\\265", "\\266", "\\267",
  293.     "\\270", "\\271", "\\272", "\\273", "\\274", "\\275", "\\276", "\\277",
  294.     "\\300", "\\301", "\\302", "\\303", "\\304", "\\305", "\\306", "\\307",
  295.     "\\310", "\\311", "\\312", "\\313", "\\314", "\\315", "\\316", "\\317",
  296.     "\\320", "\\321", "\\322", "\\323", "\\324", "\\325", "\\326", "\\327",
  297.     "\\330", "\\331", "\\332", "\\333", "\\334", "\\335", "\\336", "\\337",
  298.     "\\340", "\\341", "\\342", "\\343", "\\344", "\\345", "\\346", "\\347",
  299.     "\\350", "\\351", "\\352", "\\353", "\\354", "\\355", "\\356", "\\357",
  300.     "\\360", "\\361", "\\362", "\\363", "\\364", "\\365", "\\366", "\\367",
  301.     "\\370", "\\371", "\\372", "\\373", "\\374", "\\375", "\\376", "\\377"
  302. #else
  303. #if CHAR_OUT==1
  304.     "",      "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
  305.     "\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017",
  306.     "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027",
  307.     "\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037",
  308.     " ",     "!",     "\"",    "#",     "$",     "%",     "&",     "'",
  309.     "\\(",   "\\)",   "*",     "+",     ",",     "-",     ".",     "/",
  310.     "0",     "1",     "2",     "3",     "4",     "5",     "6",     "7",
  311.     "8",     "9",     ":",     ";",     "<",     "=",     ">",     "?",
  312.     "@",     "A",     "B",     "C",     "D",     "E",     "F",     "G",
  313.     "H",     "I",     "J",     "K",     "L",     "M",     "N",     "O",
  314.     "P",     "Q",     "R",     "S",     "T",     "U",     "V",     "W",
  315.     "X",     "Y",     "Z",     "[",     "\\\\",  "]",     "^",     "_",
  316.     "`",     "a",     "b",     "c",     "d",     "e",     "f",     "g",
  317.     "h",     "i",     "j",     "k",     "l",     "m",     "n",     "o",
  318.     "p",     "q",     "r",     "s",     "t",     "u",     "v",     "w",
  319.     "x",     "y",     "z",     "{",     "|",     "}",     "~",     "\\177",
  320.     "\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
  321.     "\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
  322.     "\220",  "\221",  "\222",  "\223",  "\224",  "\225",  "\226",  "\227",
  323.     "\230",  "\\231", "\232",  "\233",  "\\234", "\235",  "\236",  "\237",
  324.     "\240",  "\241",  "\242",  "\243",  "\244",  "\245",  "\246",  "\247",
  325.     "\250",  "\251",  "\252",  "\253",  "\254",  "\255",  "\256",  "\257",
  326.     "\260",  "\261",  "\262",  "\263",  "\264",  "\265",  "\266",  "\267",
  327.     "\270",  "\271",  "\272",  "\273",  "\274",  "\275",  "\276",  "\277",
  328.     "\300",  "\301",  "\302",  "\303",  "\304",  "\305",  "\306",  "\307",
  329.     "\310",  "\311",  "\312",  "\313",  "\314",  "\315",  "\316",  "\317",
  330.     "\320",  "\321",  "\322",  "\323",  "\324",  "\325",  "\326",  "\327",
  331.     "\330",  "\331",  "\332",  "\333",  "\334",  "\335",  "\336",  "\337",
  332.     "\340",  "\341",  "\342",  "\343",  "\344",  "\345",  "\346",  "\347",
  333.     "\350",  "\351",  "\352",  "\353",  "\354",  "\355",  "\356",  "\357",
  334.     "\360",  "\361",  "\362",  "\363",  "\364",  "\365",  "\366",  "\367",
  335.     "\370",  "\371",  "\372",  "\373",  "\374",  "\375",  "\376",  "\377"
  336. #else
  337. If you are trying to compile this you have the wrong CHAR_OUT value!
  338. #endif
  339. #endif
  340. };
  341.  
  342. /*@::PrintWord()@*************************************************************/
  343. /*                                                                           */
  344. /*  PrintWord(x, hpos, vpos)                                                 */
  345. /*                                                                           */
  346. /*  Print word x; its marks cross at the point (hpos, vpos).                 */
  347. /*                                                                           */
  348. /*****************************************************************************/
  349.  
  350. PrintWord(x, hpos, vpos)
  351. OBJECT x;  int hpos, vpos;
  352. { FULL_CHAR *p;
  353.  
  354.   debug4(DGP, DD, "PrintWord( %s, %d, %d ) font %d", string(x),
  355.     hpos, vpos, word_font(x));
  356.  
  357.   /* if font is different to previous word then print change */
  358.   if( word_font(x) != currentfont )
  359.   { currentfont = word_font(x);
  360.     currentxheight2 = FontHalfXHeight(currentfont);
  361.     fprintf(out_fp, "\n%hd %s\n", FontSize(currentfont, x), FontName(currentfont));
  362.   }
  363.  
  364.   /* move to coordinate of x */
  365.   debug1(DGP, DDD, "  currentxheight2 = %d", currentxheight2);
  366.   vpos = vpos - currentxheight2;
  367.   if( cpexists && currenty == vpos )
  368.   { printnum(hpos, out_fp);
  369.     fputs(" x", out_fp);
  370.   }
  371.   else
  372.   { currenty = vpos;
  373.     printnum(hpos, out_fp);
  374.     fputs(" ", out_fp);
  375.     printnum(currenty, out_fp);
  376.     fputs(" moveto", out_fp);
  377.     cpexists = TRUE;
  378.   }
  379.  
  380.   /* show string(x) */
  381.   fputs("(", out_fp);
  382.   for( p = string(x);  *p;  p++ )  fputs(EightBitToPrintForm[*p], out_fp);
  383.   if( ++wordcount >= 5 )
  384.   { fputs(")s\n", out_fp);  wordcount = 0;
  385.   }
  386.   else fputs(")s ", out_fp);
  387.  
  388.   debug0(DGP, DDD, "PrintWord returning");
  389. } /* end PrintWord */
  390.  
  391.  
  392. /*@::PrintClose(), CoordTranslate()@******************************************/
  393. /*                                                                           */
  394. /*  PrintClose()                                                             */
  395. /*                                                                           */
  396. /*  Clean up this module and close output stream.                            */
  397. /*                                                                           */
  398. /*****************************************************************************/
  399.  
  400. PrintClose()
  401. { OBJECT x, link;  BOOLEAN first_need;
  402.   if( prologue_done )
  403.   { fprintf(out_fp, "\npgsave restore\nshowpage\n");
  404.     fprintf(out_fp, "%%%%Trailer\n");
  405.  
  406.     /* print document fonts line */
  407.     /* *** obsolete DSC 1.0 version
  408.     fprintf(out_fp, "%%%%DocumentFonts:");
  409.     for( link = Down(font_root); link != font_root; link = NextDown(link) )
  410.     { OBJECT flink, family, face;
  411.       Child(family, link);
  412.       for( flink = Down(family);  flink != family;  flink = NextDown(flink) )
  413.       {    Child(face, flink);
  414.     if( LastDown(face) != Down(face) )
  415.     { Child(x, LastDown(face));
  416.       fprintf(out_fp, " %s", string(x));
  417.     }
  418.       }
  419.     }
  420.     fprintf(out_fp, "\n");
  421.     *** */
  422.  
  423.     /* print resource requirements (DSC 3.0 version) - fonts */
  424.     first_need = FontNeeded(out_fp);
  425.  
  426.     /* print resource requirements (DSC 3.0 version) - included EPSFs  */
  427.     for( link = Down(needs); link != needs; link = NextDown(link) )
  428.     { Child(x, link);
  429.       assert(is_word(type(x)), "PrintClose: needs!" );
  430.       fprintf(out_fp, "%s %s",
  431.     first_need ? "%%DocumentNeededResources:" : "%%+", string(x));
  432.       first_need = FALSE;
  433.     }
  434.  
  435.     fprintf(out_fp, "%%%%Pages: %d\n", pagecount);
  436.     fprintf(out_fp, "%%%%EOF\n");
  437.   }
  438. } /* end PrintClose */
  439.  
  440.  
  441. /*****************************************************************************/
  442. /*                                                                           */
  443. /*  CoordTranslate(xdist, ydist)                                             */
  444. /*                                                                           */
  445. /*  Translate coordinate system by the given x and y distances.              */
  446. /*                                                                           */
  447. /*****************************************************************************/
  448.  
  449. CoordTranslate(xdist, ydist)
  450. LENGTH xdist, ydist;
  451. { debug2(DRS,D,"CoordTranslate(%s, %s)",
  452.     EchoLength(xdist), EchoLength(ydist));
  453.   fprintf(out_fp, "%d %d translate\n", xdist, ydist);
  454.   cpexists = FALSE;  currentfont = NO_FONT;
  455.   debug0(DRS, D, "CoordTranslate returning.");
  456. } /* end CoordTranslate */
  457.  
  458. /*@::CoordRotate(), CoordScale(), SaveGraphicsState(), etc.@******************/
  459. /*                                                                           */
  460. /*  CoordRotate(amount)                                                      */
  461. /*                                                                           */
  462. /*  Rotate coordinate system by given amount (in internal DG units)          */
  463. /*                                                                           */
  464. /*****************************************************************************/
  465.  
  466. CoordRotate(amount)
  467. LENGTH amount;
  468. { debug1(DRS, D, "CoordRotate(%.1f degrees)", (float) amount / DG);
  469.   fprintf(out_fp, "%.4f rotate\n", (float) amount / DG);
  470.   cpexists = FALSE;
  471.   currentfont = NO_FONT;
  472.   debug0(DRS, D, "CoordRotate returning.");
  473. } /* end CoordRotate */
  474.  
  475.  
  476. /*****************************************************************************/
  477. /*                                                                           */
  478. /*  CoordScale(ratio, dim)                                                   */
  479. /*                                                                           */
  480. /*  Scale coordinate system by ratio in the given dimension.                 */
  481. /*                                                                           */
  482. /*****************************************************************************/
  483.  
  484. CoordScale(hfactor, vfactor)
  485. float hfactor, vfactor;
  486. { char buff[20];
  487.   ifdebug(DRS, D, sprintf(buff, "%.3f, %.3f", hfactor, vfactor));
  488.   debug1(DRS, D, "CoordScale(%s)", buff);
  489.   fprintf(out_fp, "%.4f %.4f scale\n", hfactor, vfactor);
  490.   cpexists = FALSE;
  491.   currentfont = NO_FONT;
  492.   debug0(DRS, D, "CoordScale returning.");
  493. } /* end CoordScale */
  494.  
  495.  
  496. /*****************************************************************************/
  497. /*                                                                           */
  498. /*  SaveGraphicState()                                                       */
  499. /*                                                                           */
  500. /*  Save current coord system on stack for later restoration.                */
  501. /*                                                                           */
  502. /*****************************************************************************/
  503.  
  504. SaveGraphicState()
  505. { debug0(DRS, D, "SaveGraphicState()");
  506.   fprintf(out_fp, "gsave\n");
  507.   debug0(DRS, D, "SaveGraphicState returning.");
  508. } /* end SaveGraphicState */
  509.  
  510.  
  511. /*****************************************************************************/
  512. /*                                                                           */
  513. /*  RestoreGraphicState()                                                    */
  514. /*                                                                           */
  515. /*  Restore previously saved coordinate system.  NB we normally assume that  */
  516. /*  no white space is needed before any item of output, but since this       */
  517. /*  procedure is sometimes called immediately after PrintGraphicObject(),    */
  518. /*  which does not append a concluding space, we prepend one here.           */
  519. /*                                                                           */
  520. /*****************************************************************************/
  521.  
  522. RestoreGraphicState()
  523. { debug0(DRS, D, "RestoreGraphicState()");
  524.   fprintf(out_fp, "\ngrestore\n");
  525.   cpexists = FALSE;
  526.   currentfont = NO_FONT;
  527.   debug0(DRS, D, "RestoreGraphicState returning.");
  528. } /* end RestoreGraphicState */
  529.  
  530.  
  531. /*@::PrintGraphicObject(), DefineGraphicNames()@******************************/
  532. /*                                                                           */
  533. /*  PrintGraphicObject(x)                                                    */
  534. /*                                                                           */
  535. /*  Print object x on out_fp                                                 */
  536. /*                                                                           */
  537. /*****************************************************************************/
  538.  
  539. PrintGraphicObject(x)
  540. OBJECT x;
  541. { OBJECT y, link;
  542.   switch( type(x) )
  543.   {
  544.     case WORD:
  545.     case QWORD:
  546.     
  547.       StringFPuts(string(x), out_fp);
  548.       break;
  549.     
  550.  
  551.     case ACAT:
  552.     
  553.       for( link = Down(x);  link != x;  link = NextDown(link) )
  554.       {    Child(y, link);
  555.     if( type(y) == GAP_OBJ )
  556.     { if( vspace(y) > 0 )  fputs("\n", out_fp);
  557.       else if( hspace(y) > 0 ) fputs(" ", out_fp);
  558.     }
  559.     else if( is_word(type(y)) || type(y) == ACAT )  PrintGraphicObject(y);
  560.     else if( type(y) != WIDE && !is_index(type(y)) )
  561.         /* @Wide, indexes are sometimes inserted by Manifest */
  562.     { Error(WARN, &fpos(x), "error in left parameter of %s", KW_GRAPHIC);
  563.       debug1(DGP, D, "  type(y) = %s, y =", Image(type(y)));
  564.       ifdebug(DGP, D, DebugObject(y));
  565.     }
  566.       }
  567.       break;
  568.  
  569.  
  570.     default:
  571.     
  572.       Error(WARN, &fpos(x), "error in left parameter of %s", KW_GRAPHIC);
  573.       debug1(DGP, D, "  type(x) = %s, x =", Image(type(x)));
  574.       ifdebug(DGP, D, DebugObject(x));
  575.       break;
  576.   }
  577. } /* end PrintGraphicObject */
  578.  
  579.  
  580. /*****************************************************************************/
  581. /*                                                                           */
  582. /*  DefineGraphicNames(x)                                                    */
  583. /*                                                                           */
  584. /*  Generate PostScript for xsize, ysize etc. names of graphic object.       */
  585. /*                                                                           */
  586. /*****************************************************************************/
  587.  
  588. DefineGraphicNames(x)
  589. OBJECT x;
  590. { assert( type(x) == GRAPHIC, "PrintGraphic: type(x) != GRAPHIC!" );
  591.   debug1(DRS, D, "DefineGraphicNames( %s )", EchoObject(x));
  592.   debug1(DRS, DD, "  style = %s", EchoStyle(&save_style(x)));
  593.  
  594.   fprintf(out_fp, "%d %d %d %d %d %d %d LoutGraphic\n",
  595.     size(x, COL), size(x, ROW), back(x, COL), fwd(x, ROW),
  596.     font(save_style(x)) <= 0 ? 12*PT : FontSize(font(save_style(x)), x),
  597.     width(line_gap(save_style(x))), width(space_gap(save_style(x))));
  598.  
  599.   debug0(DRS, D, "DefineGraphicNames returning.");
  600. } /* end DefineGraphicNames */
  601.  
  602.  
  603. /*@::PrintGraphicIncldue()@***************************************************/
  604. /*                                                                           */
  605. /*  PrintGraphicInclude(x, colmark, rowmark)                                 */
  606. /*                                                                           */
  607. /*  Print graphic include file, with appropriate surrounds.  This code       */
  608. /*  closely follows the PostScript Language Reference Manual, 2n ed.,        */
  609. /*  pages 733-5, except we do not clip the included EPSF.                    */
  610. /*                                                                           */
  611. /*  Note to porters: Version 3.0 of the EPSF standard is not compatible      */
  612. /*  with previous versions.  Thus, this output may crash your system.        */
  613. /*  If you can find out which comment line(s) are causing the trouble,       */
  614. /*  you can add to procedure strip_out to strip them out during the          */
  615. /*  file inclusion step.  e.g. on my system %%EOF causes problems, so I      */
  616. /*  strip it out.                                                            */
  617. /*                                                                           */
  618. /*****************************************************************************/
  619. #define    SKIPPING    0
  620. #define    READING_DNR    1
  621. #define FINISHED    2
  622.  
  623. static BOOLEAN strip_out(buff)
  624. FULL_CHAR *buff;
  625. { if( StringBeginsWith(buff, AsciiToFull("%%EOF")) )  return TRUE;
  626.   return FALSE;
  627. } /* end strip_out */
  628.  
  629. PrintGraphicInclude(x, colmark, rowmark)
  630. OBJECT x; LENGTH colmark, rowmark;
  631. { OBJECT y, full_name;  FULL_CHAR buff[MAX_LINE];
  632.   FILE *fp;  int state;
  633.   debug0(DRS, D, "PrintGraphicInclude(x)");
  634.   assert(type(x)==INCGRAPHIC || type(x)==SINCGRAPHIC, "PrintGraphicInclude!");
  635.   assert(sparec(constraint(x)), "PrintGraphicInclude: sparec(constraint(x))!");
  636.  
  637.   /* open the include file and get its full path name */
  638.   Child(y, Down(x));
  639.   fp = OpenIncGraphicFile(string(y), type(x), &full_name, &fpos(y));
  640.   assert( fp != NULL, "PrintGraphicInclude: fp!" );
  641.  
  642.   /* generate appropriate header code */
  643.   fprintf(out_fp, "BeginEPSF\n");
  644.   CoordTranslate(colmark - back(x, COL), rowmark - fwd(x, ROW));
  645.   CoordScale( (float) PT, (float) PT );
  646.   CoordTranslate(-back(y, COL), -back(y, ROW));
  647.   fprintf(out_fp, "%%%%BeginDocument: %s\n", string(full_name));
  648.  
  649.   /* copy through the include file, except divert resources lines to needs */
  650.   /* and strip out some comment lines that cause problems                  */
  651.   state = (StringFGets(buff, MAX_LINE, fp) == NULL) ? FINISHED : SKIPPING;
  652.   while( state != FINISHED ) switch(state)
  653.   {
  654.     case SKIPPING:
  655.  
  656.       if( StringBeginsWith(buff, AsciiToFull("%%DocumentNeededResources:")) &&
  657.       !StringContains(buff, AsciiToFull("(atend)")) )
  658.       { x = MakeWord(WORD, &buff[StringLength("%%DocumentNeededResources:")],
  659.           no_fpos);
  660.         Link(needs, x);
  661.     state = (StringFGets(buff,MAX_LINE,fp)==NULL) ? FINISHED : READING_DNR;
  662.       }
  663.       else
  664.       { if( StringBeginsWith(buff, AsciiToFull("%%LanguageLevel:")) )
  665.       Error(WARN, &fpos(x), "ignoring \"%%%%LanguageLevel\" in %s file %s",
  666.         KW_INCGRAPHIC, string(full_name));
  667.     if( StringBeginsWith(buff, AsciiToFull("%%Extensions:")) )
  668.       Error(WARN, &fpos(x), "ignoring \"%%%%Extensions\" in %s file %s",
  669.         KW_INCGRAPHIC, string(full_name));
  670.     if( !strip_out(buff) )  StringFPuts(buff, out_fp);
  671.     state = (StringFGets(buff, MAX_LINE, fp) == NULL) ? FINISHED : SKIPPING;
  672.       }
  673.       break;
  674.  
  675.     case READING_DNR:
  676.  
  677.       if( StringBeginsWith(buff, AsciiToFull("%%+")) )
  678.       {    x = MakeWord(WORD, &buff[StringLength(AsciiToFull("%%+"))], no_fpos);
  679.     Link(needs, x);
  680.     state = (StringFGets(buff,MAX_LINE,fp)==NULL) ? FINISHED : READING_DNR;
  681.       }
  682.       else
  683.       { if( !strip_out(buff) )  StringFPuts(buff, out_fp);
  684.     state = (StringFGets(buff, MAX_LINE, fp) == NULL) ? FINISHED : SKIPPING;
  685.       }
  686.       break;
  687.   }
  688.  
  689.   /* wrapup */
  690.   DisposeObject(full_name);
  691.   fclose(fp);
  692.   fprintf(out_fp, "%%%%EndDocument\nEndEPSF\n");
  693.   debug0(DRS, D, "PrintGraphicInclude returning.");
  694. } /* end PrintGraphicInclude */
  695.