aboutsummaryrefslogtreecommitdiffstats
path: root/z24.c
diff options
context:
space:
mode:
Diffstat (limited to 'z24.c')
-rw-r--r--z24.c1569
1 files changed, 7 insertions, 1562 deletions
diff --git a/z24.c b/z24.c
index 5128f78..2bb2abb 100644
--- a/z24.c
+++ b/z24.c
@@ -1,6 +1,6 @@
/*@z24.c:Print Service:PrintInit()@*******************************************/
/* */
-/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.21) */
+/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.22) */
/* COPYRIGHT (C) 1991, 2000 Jeffrey H. Kingston */
/* */
/* Jeffrey H. Kingston (jeff@cs.usyd.edu.au) */
@@ -26,71 +26,19 @@
/* */
/* FILE: z24.c */
/* MODULE: Print Service */
-/* EXTERNS: PrintInit(), PrintBeforeFirst(), PrintBetween(), */
-/* PrintWord(), PrintAfterLast(), CoordTranslate(), */
-/* CoordRotate(), CoordScale(), SaveGraphicState(), */
-/* RestoreGraphicState(), PrintGraphicObject(), */
-/* DefineGraphicNames(), PrintGraphicInclude() */
+/* EXTERNS: EightBitToPrintForm */
/* */
-/* This module implements the PostScript back end. */
+/* This module used to be a combined implementation of all the back */
+/* ends. Now these have been split off into separate files, there is */
+/* very little left in this module. */
/* */
/*****************************************************************************/
-#include <math.h> /* for fabs() */
-
#include "externs.h"
-#define StartUpResource "LoutStartUp"
-#define DEFAULT_XHEIGHT 500
-#define NO_FONT 0 /* actually stolen from z37.c */
-#define NO_COLOUR 0
-#define MAX_GS 50 /* maximum depth of graphics states */
-
-#define printnum(x, fp) \
-{ char buff[20]; register int i, y; \
- if( x >= 0 ) y = x; \
- else { y = -x; putc(CH_MINUS, fp); } \
- i = 0; \
- do { buff[i++] = numtodigitchar(y % 10); \
- } while( (y = (y / 10)) > 0 ); \
- do { --i; putc(buff[i], fp); \
- } while( i ); \
-}
-
-static FILE *out_fp; /* output file */
-
-/* these variables used by PLAINTEXT back end only */
-static int hsize; /* horizontal size of page in chars */
-static int vsize; /* vertical size of page in chars */
-static FULL_CHAR *page; /* the page (two-dim array of chars) */
-
-/* these types and variables used by POSTSCRIPT back end only */
-typedef struct
-{
- FONT_NUM gs_font; /* font number of this state */
- COLOUR_NUM gs_colour; /* colour number of this state */
- BOOLEAN gs_cpexists; /* TRUE if a current point exists */
- FULL_LENGTH gs_currenty; /* if cpexists, its y coordinate */
- short gs_xheight2; /* of font exists, half xheight */
-} GRAPHICS_STATE;
-
-static GRAPHICS_STATE gs_stack[MAX_GS];/* graphics state stack */
-static int gs_stack_top; /* top of graphics state stack */
-
-static FONT_NUM currentfont; /* font of most recent atom */
-static COLOUR_NUM currentcolour; /* colour of most recent atom */
-static short currentxheight2;/* half xheight in current font */
-static BOOLEAN cpexists; /* true if a current point exists */
-static FULL_LENGTH currenty; /* if cpexists, its y coordinate */
-
-static int wordcount; /* atoms printed since last newline */
-static int pagecount; /* total number of pages printed */
-static BOOLEAN prologue_done; /* TRUE after prologue is printed */
-static OBJECT needs; /* Resource needs of included EPSFs */
-static OBJECT supplied; /* Resources supplied by this file */
/*@::EightBitToPrintForm()@***************************************************/
/* */
-/* static char *EightBitToPrintForm[] */
+/* char *EightBitToPrintForm[] */
/* */
/* Given 8-bit character i, returns a string of characters that will be */
/* interpreted by PostScript as character i when read within a string. */
@@ -100,7 +48,7 @@ static OBJECT supplied; /* Resources supplied by this file */
/* */
/*****************************************************************************/
-static char *EightBitToPrintForm[] = {
+char *EightBitToPrintForm[] = {
#if CHAR_OUT==0
"", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
"\\010", "\\011", "\\012", "\\013", "\\014", "\\015", "\\016", "\\017",
@@ -173,1506 +121,3 @@ If you are trying to compile this you have the wrong CHAR_OUT value!
#endif
#endif
};
-
-/*****************************************************************************/
-/* */
-/* char *MediaName(int h, int v) */
-/* */
-/* Return the PostScript MediaName attribute appropriate to a page of */
-/* width h and height v. */
-/* */
-/* Communicated by Valeriy E. Ushakov, who wrote: */
-/* */
-/* "Attached is a patch to recognize known paper sizes and emit them as */
-/* media name in DocumentMedia comment. GhostView and other PostScript */
-/* viewers recognize these names and display them to the user. Thus user */
-/* knows what paper size document uses without having to know the magic */
-/* numbers." */
-/* */
-/*****************************************************************************/
-
-static const char *MediaName(int h, int v)
-{
- struct paper {
- const char *name;
- FULL_LENGTH width, height;
- };
-
- /* names for known paper sizes */
- static const struct paper paper_map[] = {
- { "Letter", 612*PT, 792*PT },
- { "Tabloid", 792*PT, 1224*PT },
- { "Ledger", 1224*PT, 792*PT },
- { "Legal", 612*PT, 1008*PT },
- { "Statement", 396*PT, 612*PT },
- { "Executive", 540*PT, 720*PT },
- { "A3", 842*PT, 1190*PT },
- { "A4", 595*PT, 842*PT },
- { "A5", 420*PT, 595*PT },
- { "B4", 729*PT, 1032*PT },
- { "B5", 516*PT, 729*PT },
- { "Folio", 612*PT, 936*PT },
- { "Quarto", 610*PT, 780*PT },
- { "10x14", 720*PT, 1008*PT },
- { NULL, 0, 0 }
- };
-
- /* default media name */
- static const char *user_defined = "Plain";
-
- const struct paper *p;
- for (p = paper_map; p->name; ++p) {
- if ((h == p->width) && (v == p->height)) {
- return p->name;
- }
- }
- return user_defined;
-}
-
-
-/*****************************************************************************/
-/* */
-/* PrintInit(file_ptr) */
-/* */
-/* Initialise this module. Output is to go to FILE file_ptr. */
-/* */
-/*****************************************************************************/
-
-void PrintInit(FILE *file_ptr)
-{ debug0(DGP, DD, "PrintInit()");
- out_fp = file_ptr; prologue_done = FALSE;
- gs_stack_top = -1;
- currentfont = NO_FONT;
- currentcolour = NO_COLOUR;
- cpexists = FALSE;
- wordcount = pagecount = 0;
- New(needs, ACAT);
- New(supplied, ACAT);
- debug0(DGP, DD, "PrintInit returning.");
-}
-
-
-/*@::PrintBeforeFirst@********************************************************/
-/* */
-/* PrintBeforeFirst(h, v, label) */
-/* */
-/* This procedure is called just before starting to print the first */
-/* component of the output. Its size is h, v, and label is the page */
-/* label to attach to the %%Page comment. */
-/* */
-/* If BackEnd is PLAINTEXT, this procedure obtains a two-dimensional array */
-/* of characters large enough to hold the first component, and clears it. */
-/* */
-/* If BackEnd is POSTSCRIPT, this procedure generates the PostScript */
-/* prologue, augmented with any @PrependGraphic or @SysPrependGraphic */
-/* files specified by the user. The following PostScript operators are */
-/* defined: */
-/* */
-/* scale_factor fnt scale and set font */
-/* x_coordinate x move to x_coordinate, current y coordinate */
-/* string s show string */
-/* number in result is number inches */
-/* number cm result is number centimetres */
-/* number pt result is number points */
-/* number sp result is number spaces */
-/* number vs result is number vspaces */
-/* number ft result is number font-sizes */
-/* */
-/* as well as LoutGraphic, for use with the @Graphic operator: */
-/* */
-/* xsize ysize xmark ymark fr vs sp LoutGraphic - */
-/* */
-/* Define xmark, ymark, xsize, ysize to be the positions of */
-/* these features of x, and define symbols ft, vs and sp */
-/* to be the current font size, line separation, and space width. */
-/* */
-/*****************************************************************************/
-
-void PrintBeforeFirst(FULL_LENGTH h, FULL_LENGTH v, FULL_CHAR *label)
-{ FILE_NUM fnum; int i, j; FULL_CHAR *p;
- debug2(DGP, DD, "PrintBeforeFirst(%d, %d)", h, v);
-
- switch( BackEnd )
- {
- case PLAINTEXT:
-
- /* get a new page[] and clear it */
- hsize = ceiling(h, PlainCharWidth);
- vsize = ceiling(v, PlainCharHeight);
- debug2(DGP, DD, " PlainCharWidth: %d; PlainCharHeight: %d",
- PlainCharWidth, PlainCharHeight);
- ifdebug(DMA, D, DebugRegisterUsage(MEM_PAGES, 1,
- hsize * vsize * sizeof(FULL_CHAR)));
- debug2(DGP, DD, " PrintBeforeFirst allocating %d by %d", hsize, vsize);
- page = (FULL_CHAR *) malloc(hsize * vsize * sizeof(FULL_CHAR));
- for( i = 0; i < vsize; i++ )
- for( j = 0; j < hsize; j++ )
- page[i*hsize + j] = ' ';
- break;
-
-
- case POSTSCRIPT:
-
- /* print header comments for PostScript DSC 3.0 output */
- if( Encapsulated )
- fprintf(out_fp, "%%!PS-Adobe-3.0 EPSF-3.0\n");
- else
- fprintf(out_fp, "%%!PS-Adobe-3.0\n");
- fprintf(out_fp, "%%%%Creator: %s\n", LOUT_VERSION);
- fprintf(out_fp, "%%%%CreationDate: %s", TimeString());
- fprintf(out_fp, "%%%%DocumentData: Binary\n");
- fprintf(out_fp, "%%%%DocumentNeededResources: (atend)\n");
- fprintf(out_fp, "%%%%DocumentSuppliedResources: (atend)\n");
- fprintf(out_fp, "%%%%DocumentMedia: %s %d %d 0 white ()\n",
- MediaName(h, v), h/PT, v/PT);
- fprintf(out_fp, "%%%%PageOrder: Ascend\n");
- fprintf(out_fp, "%%%%Pages: (atend)\n");
- fprintf(out_fp, "%%%%BoundingBox: 0 0 %d %d\n", h/PT, v/PT);
- fprintf(out_fp, "%%%%EndComments\n\n");
-
- /* print procedure definitions part of header */
- fprintf(out_fp, "%%%%BeginProlog\n");
- fprintf(out_fp, "%%%%BeginResource: procset %s\n", StartUpResource);
- fprintf(out_fp, "/save_cp { currentpoint /cp_y exch def /cp_x exch def } def\n");
- fprintf(out_fp, "/restore_cp { cp_x cp_y moveto } def\n");
- fprintf(out_fp, "/outline { gsave 1 1 1 setrgbcolor dup show save_cp\n");
- fprintf(out_fp, " grestore true charpath stroke restore_cp } bind def\n");
- fprintf(out_fp, "/m { 3 1 roll moveto show } bind def\n");
- fprintf(out_fp, "/mo { 3 1 roll moveto outline } bind def\n");
- fprintf(out_fp, "/s { exch currentpoint exch pop moveto show } bind def\n");
- fprintf(out_fp, "/so { exch currentpoint exch pop moveto outline } bind def\n");
- fprintf(out_fp, "/k { exch neg 0 rmoveto show } bind def\n");
- fprintf(out_fp, "/ko { exch neg 0 rmoveto outline } bind def\n");
- fprintf(out_fp, "/r { exch 0 rmoveto show } bind def\n");
- fprintf(out_fp, "/ro { exch 0 rmoveto outline } bind def\n");
- fprintf(out_fp, "/c { gsave 3 1 roll rmoveto show grestore } bind def\n");
- fprintf(out_fp, "/co { gsave 3 1 roll rmoveto outline grestore } bind def\n");
- fprintf(out_fp, "/ul { gsave setlinewidth dup 3 1 roll\n");
- fprintf(out_fp, " moveto lineto stroke grestore } bind def\n");
- fprintf(out_fp, "/in { %d mul } def\n", IN);
- fprintf(out_fp, "/cm { %d mul } def\n", CM);
- fprintf(out_fp, "/pt { %d mul } def\n", PT);
- fprintf(out_fp, "/em { %d mul } def\n", EM);
- fprintf(out_fp, "/sp { louts mul } def\n");
- fprintf(out_fp, "/vs { loutv mul } def\n");
- fprintf(out_fp, "/ft { loutf mul } def\n");
- fprintf(out_fp, "/dg { } def\n\n");
-
- fputs("/LoutGraphic {\n", out_fp);
- fputs(" /louts exch def\n", out_fp);
- fputs(" /loutv exch def\n", out_fp);
- fputs(" /loutf exch def\n", out_fp);
- fputs(" /ymark exch def\n", out_fp);
- fputs(" /xmark exch def\n", out_fp);
- fputs(" /ysize exch def\n", out_fp);
- fputs(" /xsize exch def\n} def\n\n", out_fp);
-
- fputs("/LoutGr2 { gsave translate LoutGraphic gsave } def\n\n", out_fp);
-
- /* print definition used by Lout output to recode fonts */
- /* adapted from PostScript Language Reference Manual (2nd Ed), p. 275 */
- /* usage: /<fullname> <encodingvector> /<originalname> LoutRecode - */
-
- fputs("/LoutFont\n", out_fp);
- fputs("{ findfont exch scalefont setfont\n", out_fp);
- fputs("} bind def\n\n", out_fp);
-
- fputs("/LoutRecode {\n", out_fp);
- fputs(" { findfont dup length dict begin\n", out_fp);
- fputs(" {1 index /FID ne {def} {pop pop} ifelse} forall\n", out_fp);
- fputs(" /Encoding exch def\n", out_fp);
- fputs(" currentdict end definefont pop\n", out_fp);
- fputs(" }\n", out_fp);
- fputs(" stopped pop\n", out_fp);
- fputs("} bind def\n\n", out_fp);
-
- /* print definitions used by Lout output when including EPSF files */
- /* copied from PostScript Language Reference Manual (2nd Ed.), p. 726 */
-
- fputs("/BeginEPSF {\n", out_fp);
- fputs(" /LoutEPSFState save def\n", out_fp);
- fputs(" /dict_count countdictstack def\n", out_fp);
- fputs(" /op_count count 1 sub def\n", out_fp);
- fputs(" userdict begin\n", out_fp);
- fputs(" /showpage { } def\n", out_fp);
- fputs(" 0 setgray 0 setlinecap\n", out_fp);
- fputs(" 1 setlinewidth 0 setlinejoin\n", out_fp);
- fputs(" 10 setmiterlimit [] 0 setdash newpath\n", out_fp);
- fputs(" /languagelevel where\n", out_fp);
- fputs(" { pop languagelevel\n", out_fp);
- fputs(" 1 ne\n", out_fp);
- fputs(" { false setstrokeadjust false setoverprint\n", out_fp);
- fputs(" } if\n", out_fp);
- fputs(" } if\n", out_fp);
- fputs("} bind def\n\n", out_fp);
-
- fputs("/EndEPSF {\n", out_fp);
- fputs(" count op_count sub { pop } repeat\n", out_fp);
- fputs(" countdictstack dict_count sub { end } repeat\n", out_fp);
- fputs(" LoutEPSFState restore\n", out_fp);
- fputs("} bind def\n", out_fp);
-
- fputs("%%EndResource\n\n", out_fp);
-
- /* print encoding vectors as resources */
- /* MapPrintEncodings(out_fp); obsolete now */
-
- /* print prepend files (assumed to be organized as DSC 3.0 Resources) */
- for( fnum=FirstFile(PREPEND_FILE); fnum!=NO_FILE; fnum=NextFile(fnum) )
- { FULL_CHAR buff[MAX_BUFF]; FILE *fp;
- if( (fp = OpenFile(fnum, FALSE, FALSE)) == null )
- Error(24, 1, "cannot open %s file %s",
- WARN, PosOfFile(fnum), KW_PREPEND, FileName(fnum));
- else if( StringFGets(buff, MAX_BUFF, fp) == NULL )
- Error(24, 2, "%s file %s is empty",
- WARN, PosOfFile(fnum), KW_PREPEND, FileName(fnum));
- else
- {
- if( StringBeginsWith(buff, AsciiToFull("%%BeginResource:")) )
- { OBJECT tmp;
- tmp = MakeWord(WORD, &buff[strlen("%%BeginResource:")], no_fpos);
- Link(supplied, tmp);
- }
- else
- Error(24, 3, "%s file %s lacks PostScript BeginResource comment",
- WARN, PosOfFile(fnum), KW_PREPEND, FileName(fnum));
- StringFPuts(buff, out_fp);
- fprintf(out_fp, "%% %s file %s\n", KW_PREPEND, FileName(fnum));
- while( StringFGets(buff, MAX_BUFF, fp) != NULL )
- StringFPuts(buff, out_fp);
- fprintf(out_fp, "\n");
- fclose(fp);
- }
- }
-
- fputs("%%EndProlog\n\n", out_fp);
- fputs("%%BeginSetup\n", out_fp);
- FontPrintPageSetup(out_fp);
- fputs("%%EndSetup\n\n", out_fp);
- fprintf(out_fp, "%%%%Page: ");
- for( p = label; *p != '\0'; p++ )
- fputs(EightBitToPrintForm[*p], out_fp);
- fprintf(out_fp, " %d\n", ++pagecount);
- fprintf(out_fp, "%%%%BeginPageSetup\n");
- FontPrintPageResources(out_fp);
- FontAdvanceCurrentPage();
- fprintf(out_fp, "/pgsave save def\n");
- fprintf(out_fp, "%.4f dup scale %d setlinewidth\n", 1.0 / PT, PT/2);
- fprintf(out_fp, "%%%%EndPageSetup\n\n");
- break;
-
- case PDF:
-
- PDFFile_Init(out_fp, h/PT, v/PT, IN, CM, PT, EM);
-
- /* print encoding vectors as resources */
- /* MapPrintEncodings(out_fp); obsolete now */
-
- FontPrintPageSetup(out_fp);
-
- PDFPage_Init(out_fp, 1.0 / PT, PT/2);
-
- FontPrintPageResources(out_fp); /* write out font objects */
- FontAdvanceCurrentPage();
- break;
-
- } /* end switch */
- prologue_done = TRUE;
-} /* end PrintBeforeFirst */
-
-
-/*@::PrintBetween()@**********************************************************/
-/* */
-/* PrintBetween(h, v, label) */
-/* */
-/* Start a new output component, of size h by v; label is the page label */
-/* to attach to the %%Page comment. */
-/* */
-/*****************************************************************************/
-
-void PrintBetween(FULL_LENGTH h, FULL_LENGTH v, FULL_CHAR *label)
-{ int new_hsize, new_vsize, i, j, jmax; FULL_CHAR *p;
- debug2(DGP, DD, "PrintBetween(%d, %d)", h, v);
-
- switch( BackEnd )
- {
- case PLAINTEXT:
-
- /* print the page that has just ended */
- ifdebug(DGP, D,
- putc('+', out_fp);
- for( j = 0; j < hsize; j++ ) putc('-', out_fp);
- putc('+', out_fp);
- putc('\n', out_fp);
- );
- for( i = vsize - 1; i >= 0; i-- )
- { ifdebug(DGP, D, putc('|', out_fp));
- for( jmax = hsize-1; jmax >= 0 && page[i*hsize+jmax] == ' '; jmax--);
- ifdebug(DGP, D, jmax = hsize - 1);
- for( j = 0; j <= jmax; j++ )
- putc(page[i*hsize + j], out_fp);
- ifdebug(DGP, D, putc('|', out_fp));
- putc('\n', out_fp);
- }
- ifdebug(DGP, D,
- putc('+', out_fp);
- for( j = 0; j < hsize; j++ ) putc('-', out_fp);
- putc('+', out_fp);
- putc('\n', out_fp);
- );
-
- /* separate the page from the next one with a form-feed if required */
- if( PlainFormFeed ) putc('\f', out_fp);
-
- /* if page size has changed, get a new page[] array */
- new_hsize = ceiling(h, PlainCharWidth);
- new_vsize = ceiling(v, PlainCharHeight);
- if( new_hsize != hsize || new_vsize != vsize )
- {
- ifdebug(DMA, D, DebugRegisterUsage(MEM_PAGES, -1,
- -hsize * vsize * sizeof(FULL_CHAR)));
- free(page);
- hsize = new_hsize;
- vsize = new_vsize;
- debug2(DGP, DD, " PrintBetween allocating %d by %d", hsize, vsize);
- ifdebug(DMA, D, DebugRegisterUsage(MEM_PAGES, 1,
- hsize * vsize * sizeof(FULL_CHAR)));
- page = (FULL_CHAR *) malloc(hsize * vsize * sizeof(FULL_CHAR));
- }
-
- /* clear page[] for the new page just beginning */
- for( i = 0; i < vsize; i++ )
- for( j = 0; j < hsize; j++ )
- page[i*hsize + j] = ' ';
- break;
-
-
- case POSTSCRIPT:
-
- fprintf(out_fp, "\npgsave restore\nshowpage\n");
- gs_stack_top = 0;
- cpexists = FALSE;
- currentfont = NO_FONT;
- currentcolour = NO_COLOUR;
- if( Encapsulated )
- { PrintAfterLast();
- Error(24, 4, "truncating -EPS document at end of first page",
- FATAL, no_fpos);
- }
- fprintf(out_fp, "\n%%%%Page: ");
- for( p = label; *p != '\0'; p++ )
- fputs(EightBitToPrintForm[*p], out_fp);
- fprintf(out_fp, " %d\n", ++pagecount);
- fprintf(out_fp, "%%%%BeginPageSetup\n");
- FontPrintPageResources(out_fp);
- fprintf(out_fp, "/pgsave save def\n");
- FontPrintPageSetup(out_fp);
- FontAdvanceCurrentPage();
- fprintf(out_fp, "%.4f dup scale %d setlinewidth\n", 1.0 / PT, PT/2);
- fprintf(out_fp, "%%%%EndPageSetup\n");
- wordcount = 0;
- break;
-
- case PDF:
-
- /* write out page objects */
- PDFPage_Cleanup(out_fp);
- PDFPage_Init(out_fp, 1.0 / PT, PT/2);
-
- /* write out font objects */
- FontPrintPageResources(out_fp);
- FontPrintPageSetup(out_fp);
- FontAdvanceCurrentPage();
- break;
-
- } /* end switch */
-} /* end PrintBetween */
-
-
-/*****************************************************************************/
-/* */
-/* KernLength(fnum, ch1, ch2, res) */
-/* */
-/* Set res to the kern length between ch1 and ch2 in font fnum, or 0 if */
-/* none. */
-/* */
-/*****************************************************************************/
-
-#define KernLength(fnum, mp, ch1, ch2, res) \
-{ int ua_ch1 = mp[ch1]; \
- int ua_ch2 = mp[ch2]; \
- int i = finfo[fnum].kern_table[ua_ch1], j; \
- if( i == 0 ) res = 0; \
- else \
- { FULL_CHAR *kc = finfo[fnum].kern_chars; \
- for( j = i; kc[j] > ua_ch2; j++ ); \
- res = (kc[j] == ua_ch2) ? \
- finfo[fnum].kern_sizes[finfo[fnum].kern_value[j]] : 0; \
- } \
-} /* end KernLength */
-
-
-/*****************************************************************************/
-/* */
-/* static void PrintComposite(COMPOSITE *cp, BOOLEAN outline, FILE *fp) */
-/* */
-/* Print composite character cp, assuming that the current point is */
-/* set to the correct origin. If outline is true, we want to print the */
-/* composite character in outline. */
-/* */
-/*****************************************************************************/
-
-static void PrintComposite(COMPOSITE *cp, BOOLEAN outline, FILE *fp)
-{ debug1(DGP, D, "PrintComposite(cp, %s, fp)", bool(outline));
- while( cp->char_code != '\0' )
- {
- debug4(DGP, D, " cp = %d printing code %d (%d, %d)", (int) cp,
- cp->char_code, cp->x_offset, cp->y_offset);
- fprintf(fp, "%d %d (%c)%s ", cp->x_offset, cp->y_offset,
- cp->char_code, outline ? "co" : "c");
- cp++;
- }
-} /* end PrintComposite */
-
-
-/*@::PrintWord()@*************************************************************/
-/* */
-/* PrintWord(x, hpos, vpos) */
-/* */
-/* Print non-empty word x; its marks cross at the point (hpos, vpos). */
-/* */
-/*****************************************************************************/
-
-void PrintWord(OBJECT x, int hpos, int vpos)
-{ FULL_CHAR *p, *q, *a, *b, *lig, *unacc;
- int i, h, v, ksize; char *command; MAPPING m;
- unsigned short *composite; COMPOSITE *cmp;
-
- debug6(DGP, DD, "PrintWord( %s, %d, %d ) font %d colour %d%s", string(x),
- hpos, vpos, word_font(x), word_colour(x),
- word_outline(x) ? " outline" : "");
- TotalWordCount++;
-
- switch( BackEnd )
- {
- case PLAINTEXT:
-
- h = ((float) hpos / PlainCharWidth) + 0.5;
- v = ((float) vpos / PlainCharHeight);
- debug3(DGP, DD, "PrintWord(%s at h = %d, v = %d)", string(x), h, v);
- if( h >= 0 && h + StringLength(string(x)) < hsize && v >= 0 && v < vsize )
- {
- assert( h >= 0, "PrintWord: h < 0!" );
- assert( h < hsize, "PrintWord: h >= hsize!" );
- assert( v >= 0, "PrintWord: v < 0!" );
- assert( v < vsize, "PrintWord: v >= vsize!" );
- p = &page[v*hsize + h];
- for( i = 0; string(x)[i] != '\0'; i++ )
- *p++ = string(x)[i];
- }
- else
- {
- Error(24, 11, "word %s deleted (internal error, off page at %d,%d)",
- WARN, &fpos(x), string(x), h, v);
- }
- break;
-
-
- case POSTSCRIPT:
-
- /* if font is different to previous word then print change */
- if( word_font(x) != currentfont )
- { currentfont = word_font(x);
- currentxheight2 = FontHalfXHeight(currentfont);
- fprintf(out_fp, "%hd %s", FontSize(currentfont, x),
- FontName(currentfont));
- if( ++wordcount >= 5 )
- { putc('\n', out_fp);
- wordcount = 0;
- }
- else putc(' ', out_fp);
- }
-
- /* if colour is different to previous word then print change */
- if( word_colour(x) != currentcolour )
- { currentcolour = word_colour(x);
- if( currentcolour > 0 )
- { fprintf(out_fp, "%s", ColourCommand(currentcolour));
- if( ++wordcount >= 5 )
- { putc('\n', out_fp);
- wordcount = 0;
- }
- else putc(' ', out_fp);
- }
- }
-
- /* convert ligature sequences into ligature characters */
- lig = finfo[word_font(x)].lig_table;
- p = q = string(x);
- do
- {
- /* check for missing glyph (lig[] == 1) or ligatures (lig[] > 1) */
- if( lig[*q++ = *p++] )
- {
- if( lig[*(q-1)] == 1 ) continue;
- else
- { a = &lig[ lig[*(p-1)] + MAX_CHARS ];
- while( *a++ == *(p-1) )
- { b = p;
- while( *a == *b && *(a+1) != '\0' && *b != '\0' ) a++, b++;
- if( *(a+1) == '\0' )
- { *(q-1) = *a;
- p = b;
- break;
- }
- else
- { while( *++a );
- a++;
- }
- }
- }
- }
- } while( *p );
- *q = '\0';
-
- /* move to coordinate of x */
- cmp = finfo[word_font(x)].cmp_table;
- composite = finfo[word_font(x)].composite;
- debug1(DGP, DDD, " currentxheight2 = %d", currentxheight2);
- vpos = vpos - currentxheight2;
- if( cpexists && currenty == vpos )
- { printnum(hpos, out_fp);
- command = word_outline(x) ? "so" : "s";
- }
- else
- { currenty = vpos;
- printnum(hpos, out_fp);
- putc(' ', out_fp);
- printnum(currenty, out_fp);
- command = word_outline(x) ? "mo" : "m";
- cpexists = TRUE;
- }
-
- /* show string(x) */
- putc('(', out_fp);
- p = string(x);
- if( composite[*p] )
- {
- fprintf(out_fp, ")%s ", command);
- debug3(DGP, D,
- " calling PrintComposite(&cmp[composite[%d] = %d]); cmp_top = %d",
- (int) *p, composite[*p], finfo[word_font(x)].cmp_top);
- PrintComposite(&cmp[composite[*p]], word_outline(x), out_fp);
- printnum(finfo[word_font(x)].size_table[*p].right, out_fp);
- putc('(', out_fp);
- command = word_outline(x) ? "ro" : "r";
- }
- else fputs(EightBitToPrintForm[*p], out_fp);
- m = font_mapping(finfo[word_font(x)].font_table);
- unacc = MapTable[m]->map[MAP_UNACCENTED];
- /* acc = MapTable[m]->map[MAP_ACCENT]; */
- for( p++; *p; p++ )
- { KernLength(word_font(x), unacc, *(p-1), *p, ksize);
- if( ksize != 0 )
- { fprintf(out_fp, ")%s %d(", command, -ksize);
- ++wordcount;
- command = word_outline(x) ? "ko" : "k";
- }
- if( composite[*p] )
- { fprintf(out_fp, ")%s ", command);
- debug3(DGP, D,
- " calling PrintComposite(&cmp[composite[%d] = %d]); cmp_top = %d",
- (int) *p, composite[*p], finfo[word_font(x)].cmp_top);
- PrintComposite(&cmp[composite[*p]], word_outline(x), out_fp);
- printnum(finfo[word_font(x)].size_table[*p].right, out_fp);
- putc('(', out_fp);
- command = word_outline(x) ? "ro" : "r";
- }
- else fputs(EightBitToPrintForm[*p], out_fp);
- }
- if( ++wordcount >= 5 )
- { fprintf(out_fp, ")%s\n", command);
- wordcount = 0;
- }
- else fprintf(out_fp, ")%s ", command);
-
-
- /* move to coordinate of x */
- /* *** old version
- debug1(DGP, DDD, " currentxheight2 = %d", currentxheight2);
- vpos = vpos - currentxheight2;
- if( cpexists && currenty == vpos )
- { printnum(hpos, out_fp);
- command = word_outline(x) ? "so" : "s";
- }
- else
- { currenty = vpos;
- printnum(hpos, out_fp);
- fputs(" ", out_fp);
- printnum(currenty, out_fp);
- command = word_outline(x) ? "mo" : "m";
- cpexists = TRUE;
- }
- *** */
-
- /* show string(x) */
- /* *** old version
- fputs("(", out_fp);
- p = string(x);
- fputs(EightBitToPrintForm[*p], out_fp);
- m = font_mapping(finfo[word_font(x)].font_table);
- unacc = MapTable[m]->map[MAP_UNACCENTED];
- for( p++; *p; p++ )
- { KernLength(word_font(x), unacc, *(p-1), *p, ksize);
- if( ksize != 0 )
- { fprintf(out_fp, ")%s %d(", command, -ksize);
- ++wordcount;
- command = word_outline(x) ? "ko" : "k";
- }
- fputs(EightBitToPrintForm[*p], out_fp);
- }
- if( ++wordcount >= 5 )
- { fprintf(out_fp, ")%s\n", command);
- wordcount = 0;
- }
- else fprintf(out_fp, ")%s ", command);
- *** */
-
- /* ordinary printing moves current point; outlining destroys it */
- /* *** changed the outline commands now so that they move the current
- point the same way ordinary printing does
- if( word_outline(x) )
- cpexists = FALSE;
- *** */
- break;
-
-
-
- case PDF:
- {
-
- static int last_hpos; /* does not need to be initialised */
- static int next_hpos = -1;
-#if 0
- struct metrics *fnt;
-#endif
- /* if font is different to previous word then print change */
- if( word_font(x) != currentfont )
- { currentfont = word_font(x);
- currentxheight2 = FontHalfXHeight(currentfont);
- PDFFont_Set(out_fp, FontSize(currentfont, x), FontName(currentfont));
- }
-
- /* if colour is different to previous word then print change */
- if( word_colour(x) != currentcolour )
- {
- currentcolour = word_colour(x);
- if( currentcolour > 0 )
- {
- char str[256];
-
- sprintf(str, "%s ", ColourCommand(currentcolour));
- PDFPage_Write(out_fp, str);
- }
- }
-
- /* move to coordinate of x */
- debug1(DGP, DDD, " currentxheight2 = %d", currentxheight2);
- vpos = vpos - currentxheight2;
- if( cpexists && (currenty == vpos) && PDFHasValidTextMatrix() )
- { /* printnum(hpos, out_fp); */
- command = "s";
-/*
- Note: I calculate the width of the space char here in case the font has
- changed. This prevents subtle spacing errors from occurring.
- */
-#if 0
- fnt = finfo[currentfont].size_table;
-
- if ( (next_hpos + fnt[' '].right /* width of space char */ ) == hpos )
- command = " ";
-#endif
- }
- else
- { currenty = vpos;
- /* printnum(hpos, out_fp);
- fputs(" ", out_fp);
- printnum(currenty, out_fp); */
- command = "m";
- cpexists = TRUE;
- }
-
- /* convert ligature sequences into ligature characters */
- lig = finfo[word_font(x)].lig_table;
- p = q = string(x);
- do
- {
- /* check for missing glyph (lig[] == 1) or ligatures (lig[] > 1) */
- if( lig[*q++ = *p++] )
- {
- if( lig[*(q-1)] == 1 ) continue;
- else
- { a = &lig[ lig[*(p-1)] + MAX_CHARS ];
- while( *a++ == *(p-1) )
- { b = p;
- while( *a == *b && *(a+1) != '\0' && *b != '\0' ) a++, b++;
- if( *(a+1) == '\0' )
- { *(q-1) = *a;
- p = b;
- break;
- }
- else
- { while( *++a );
- a++;
- }
- }
- }
- }
- } while( *p );
- *q = '\0';
-
- /* show string(x) */
- /* FontWordSize(x); - this should not be necessary */
-
- switch (command[0])
- {
- case 'm':
-
- PDFText_OpenXY(out_fp, hpos, vpos);
- last_hpos = hpos;
- next_hpos = hpos + fwd(x, COLM); /* fwd(x, COLM) = width of wd */
- break;
-
- case 's':
-#if 0
- PDFText_Open(out_fp);
- PDFText_Kern(out_fp, hpos - next_hpos);
-#else
- PDFText_OpenX(out_fp, hpos - last_hpos);
-#endif
- last_hpos = hpos;
- next_hpos = hpos + fwd(x, COLM); /* fwd(x, COLM) = width of wd */
- break;
-#if 0
- case ' ':
-
- PDFText_Open(out_fp);
-#if 1
- /* try kerning to get correct position */
- PDFText_Kern(out_fp, fnt[' '].right);
-#else
- PDFPage_Write(out_fp, EightBitToPrintForm[' ']);
-#endif
- next_hpos += fwd(x, COLM) + fnt[' '].right; /* width of space ch */
- break;
-#endif
- }
-
- p = string(x);
- PDFPage_Write(out_fp, EightBitToPrintForm[*p]);
-
- m = font_mapping(finfo[word_font(x)].font_table);
- unacc = MapTable[m]->map[MAP_UNACCENTED];
- /* acc = MapTable[m]->map[MAP_ACCENT]; */
- for( p++; *p; p++ )
- {
- /* KernLength(word_font(x), unacc, *(p-1), *p, ksize); */
- KernLength(font_num(finfo[word_font(x)].original_font),
- unacc, *(p-1), *p, ksize);
- if ( ksize != 0 )
- {
- PDFText_Kern(out_fp, ksize);
- }
- PDFPage_Write(out_fp, EightBitToPrintForm[*p]);
- }
- PDFText_Close(out_fp);
- break;
- }
-
-
- } /* end switch */
- debug0(DGP, DDD, "PrintWord returning");
-} /* end PrintWord */
-
-
-/*****************************************************************************/
-/* */
-/* PrintPlainGraphicObject(x, xmk, ymk, z) */
-/* */
-/* Print plain graphic object x at xmk, ymk with the size of z. */
-/* */
-/*****************************************************************************/
-
-void PrintPlainGraphicObject(OBJECT x, FULL_LENGTH xmk,FULL_LENGTH ymk,OBJECT z)
-{ int i, len, starth, startv, stoph, stopv, h, v;
- debug2(DGP, D, "PrintPlainGraphicObject(x, xmk %s, ymk %s)",
- EchoLength(xmk), EchoLength(ymk));
-
- assert( BackEnd == PLAINTEXT, "PrintPlainGraphicObject: back end!" );
- if( type(x) != WORD && type(x) != QWORD )
- {
- Error(24, 12, "left parameter of %s must be a simple word",
- WARN, &fpos(x), KW_PLAINGRAPHIC);
- return;
- }
- len = StringLength(string(x));
- if( StringLength(string(x)) == 0 )
- {
- Error(24, 13, "left parameter of %s must be a non-empty word",
- WARN, &fpos(x), KW_PLAINGRAPHIC);
- return;
- }
- starth = (((float) xmk ) / PlainCharWidth) + 0.5;
- startv = (((float) ymk ) / PlainCharHeight);
- stoph = (((float) xmk + size(z, COLM)) / PlainCharWidth) + 0.5;
- stopv = (((float) ymk - size(z, ROWM)) / PlainCharHeight); /* NB - not + */
- SetLengthDim(COLM);
- debug5(DGP, D, " xmk %s bk %s fwd %s -> %d,%d",
- EchoLength(xmk), EchoLength(back(z, COLM)), EchoLength(fwd(z, COLM)),
- starth, stoph);
- SetLengthDim(ROWM);
- debug5(DGP, D, " ymk %s bk %s fwd %s -> %d,%d",
- EchoLength(ymk), EchoLength(back(z, ROWM)), EchoLength(fwd(z, ROWM)),
- startv, stopv);
- if( starth >= 0 && stoph < hsize && startv >= 0 && stopv < vsize )
- { i = 0;
- for( v = startv-1; v >= stopv; v-- )
- {
- for( h = starth; h < stoph; h++ )
- {
- if( i == len ) i = 0;
- page[v*hsize + h] = string(x)[i++];
- }
- }
- }
- else
- {
- Error(24, 14, "fill %s deleted (internal error, off page at %d,%d)",
- WARN, &fpos(x), string(x), h, v);
- }
-} /* end PrintPlainGraphicObject */
-
-
-/*****************************************************************************/
-/* */
-/* PrintUnderline(fnum, xstart, xstop, ymk) */
-/* */
-/* Draw an underline suitable for font fnum, from xstart to xstop at the */
-/* appropriate distance below mark ymk. */
-/* */
-/*****************************************************************************/
-
-void PrintUnderline(FONT_NUM fnum, FULL_LENGTH xstart, FULL_LENGTH xstop,
- FULL_LENGTH ymk)
-{
-
- debug4(DGP, DD, "PrintUnderline(fnum %d, xstart %s, xstop %s, ymk %s )",
- fnum, EchoLength(xstart), EchoLength(xstop), EchoLength(ymk));
-
- switch( BackEnd )
- {
- case PLAINTEXT:
-
- /* do nothing */
- break;
-
-
- case POSTSCRIPT:
-
- fprintf(out_fp, "%d %d %d %d ul\n", xstart, xstop,
- ymk - finfo[fnum].underline_pos, finfo[fnum].underline_thick);
- break;
-
- case PDF:
- PDFPage_PrintUnderline(out_fp, xstart, xstop,
- ymk - finfo[fnum].underline_pos, finfo[fnum].underline_thick);
- break;
- }
- debug0(DGP, DD, "PrintUnderline returning.");
-} /* end PrintUnderline */
-
-
-/*@::PrintAfterLast(), CoordTranslate()@**************************************/
-/* */
-/* PrintAfterLast() */
-/* */
-/* Clean up this module and close output stream. */
-/* */
-/*****************************************************************************/
-
-void PrintAfterLast(void)
-{ OBJECT x, link; BOOLEAN first_need; int i, j, jmax;
- if( prologue_done )
- {
- switch( BackEnd )
- {
- case PLAINTEXT:
-
- /* print the page that has just ended (exists since prologue_done) */
- ifdebug(DGP, D,
- putc('+', out_fp);
- for( j = 0; j < hsize; j++ ) putc('-', out_fp);
- putc('+', out_fp);
- putc('\n', out_fp);
- );
- for( i = vsize - 1; i >= 0; i-- )
- { ifdebug(DGP, D, putc('|', out_fp));
- for( jmax = hsize-1; jmax >= 0 && page[i*hsize+jmax] == ' '; jmax--);
- ifdebug(DGP, D, jmax = hsize - 1);
- for( j = 0; j <= jmax; j++ )
- putc(page[i*hsize + j], out_fp);
- ifdebug(DGP, D, putc('|', out_fp));
- putc('\n', out_fp);
- }
- ifdebug(DGP, D,
- putc('+', out_fp);
- for( j = 0; j < hsize; j++ ) putc('-', out_fp);
- putc('+', out_fp);
- putc('\n', out_fp);
- );
- break;
-
-
- case POSTSCRIPT:
-
- fprintf(out_fp, "\npgsave restore\nshowpage\n");
- fprintf(out_fp, "\n%%%%Trailer\n");
-
- /* print resource requirements (DSC 3.0 version) - fonts */
- first_need = FontNeeded(out_fp);
-
- /* print resource requirements (DSC 3.0 version) - included EPSFs */
- for( link = Down(needs); link != needs; link = NextDown(link) )
- { Child(x, link);
- assert(is_word(type(x)), "PrintAfterLast: needs!" );
- fprintf(out_fp, "%s %s",
- first_need ? "%%DocumentNeededResources:" : "%%+", string(x));
- first_need = FALSE;
- }
-
- /* print resources supplied */
- fprintf(out_fp,
- "%%%%DocumentSuppliedResources: procset %s\n", StartUpResource);
- for( link = Down(supplied); link != supplied; link = NextDown(link) )
- { Child(x, link);
- fprintf(out_fp, "%%%%+ %s", string(x));
- }
- MapPrintResources(out_fp);
-
- fprintf(out_fp, "%%%%Pages: %d\n", pagecount);
- fprintf(out_fp, "%%%%EOF\n");
- break;
-
- case PDF:
-
- PDFPage_Cleanup(out_fp); /* write out page objects */
- /* MapPrintResources(out_fp); not needed */
- PDFFile_Cleanup(out_fp);
- break;
-
- } /* end switch */
- } /* end if prologue_done */
-} /* end PrintAfterLast */
-
-
-/*****************************************************************************/
-/* */
-/* CoordTranslate(xdist, ydist) */
-/* */
-/* Translate coordinate system by the given x and y distances. */
-/* */
-/*****************************************************************************/
-
-void CoordTranslate(FULL_LENGTH xdist, FULL_LENGTH ydist)
-{ debug2(DRS,D,"CoordTranslate(%s, %s)",
- EchoLength(xdist), EchoLength(ydist));
- assert( BackEnd != PLAINTEXT, "CoordTranslate: BackEnd!" );
- if (BackEnd == POSTSCRIPT)
- fprintf(out_fp, "%d %d translate\n", xdist, ydist);
- else if (BackEnd == PDF)
- {
- if ((xdist != 0) || (ydist != 0))
- {
-#if 1
- PDFPage_Translate(out_fp, xdist, ydist);
-#else
- char temp_str[64];
- sprintf(temp_str, "1 0 0 1 %d %d cm\n", xdist, ydist);
- PDFPage_Write(out_fp, temp_str);
-#endif
- }
- }
- cpexists = FALSE;
- /***
- currentfont = NO_FONT;
- currentcolour = NO_COLOUR;
- ***/
- debug0(DRS, D, "CoordTranslate returning.");
-} /* end CoordTranslate */
-
-
-/*@::CoordRotate(), CoordScale(), SaveGraphicsState(), etc.@******************/
-/* */
-/* CoordRotate(amount) */
-/* */
-/* Rotate coordinate system by given amount (in internal DG units) */
-/* */
-/*****************************************************************************/
-
-void CoordRotate(FULL_LENGTH amount)
-{ debug1(DRS, D, "CoordRotate(%.1f degrees)", (float) amount / DG);
- assert( BackEnd != PLAINTEXT, "CoordRotate: BackEnd!" );
- if (BackEnd == POSTSCRIPT)
- fprintf(out_fp, "%.4f rotate\n", (float) amount / DG);
- else if (BackEnd == PDF)
- {
- int theAmount = ((amount / DG) % 360);
- if ( theAmount != 0 )
- {
- #define PI 3.1415926535897931160
-
- PDFPage_Rotate(out_fp, (double) theAmount * (double) PI / (double) 180.0);
- }
- }
- cpexists = FALSE;
- /***
- currentfont = NO_FONT;
- currentcolour = NO_COLOUR;
- ***/
- debug0(DRS, D, "CoordRotate returning.");
-} /* end CoordRotate */
-
-
-/*****************************************************************************/
-/* */
-/* CoordScale(ratio, dim) */
-/* */
-/* Scale coordinate system by ratio in the given dimension. */
-/* */
-/*****************************************************************************/
-
-void CoordScale(float hfactor, float vfactor)
-{
-#if DEBUG_ON
- char buff[20];
-#endif
- assert( BackEnd != PLAINTEXT, "CoordScale: BackEnd!" );
- ifdebug(DRS, D, sprintf(buff, "%.3f, %.3f", hfactor, vfactor));
- debug1(DRS, D, "CoordScale(%s)", buff);
- if (BackEnd == POSTSCRIPT)
- fprintf(out_fp, "%.4f %.4f scale\n", hfactor, vfactor);
- else if (BackEnd == PDF)
- {
- if ( (fabs(hfactor - 1.0) > 0.01) || (fabs(vfactor - 1.0) > 0.01) )
- {
-#if 1
- PDFPage_Scale(out_fp, hfactor, vfactor);
-#else
- char temp_str[64];
- sprintf(temp_str, "%.2f 0 0 %.2f 0 0 cm\n", hfactor, vfactor);
- PDFPage_Write(out_fp, temp_str);
-#endif
- }
- }
- cpexists = FALSE;
- /***
- currentfont = NO_FONT;
- currentcolour = NO_COLOUR;
- ***/
- debug0(DRS, D, "CoordScale returning.");
-} /* end CoordScale */
-
-
-/*****************************************************************************/
-/* */
-/* SaveGraphicState(x) */
-/* */
-/* Save current coord system on stack for later restoration. */
-/* Object x is just for error reporting, not really used at all. */
-/* */
-/*****************************************************************************/
-
-void SaveGraphicState(OBJECT x)
-{ debug0(DRS, D, "SaveGraphicState()");
- assert( BackEnd != PLAINTEXT, "SaveGraphicState: BackEnd!" );
- if (BackEnd == POSTSCRIPT)
- fprintf(out_fp, "gsave\n");
- else if (BackEnd == PDF)
- PDFPage_Push(out_fp);
- gs_stack_top++;
- if( gs_stack_top >= MAX_GS )
- Error(24, 5, "rotations, graphics etc. too deeply nested (max is %d)",
- FATAL, &fpos(x), MAX_GS);
- gs_stack[gs_stack_top].gs_font = currentfont;
- gs_stack[gs_stack_top].gs_colour = currentcolour;
- gs_stack[gs_stack_top].gs_cpexists = cpexists;
- gs_stack[gs_stack_top].gs_currenty = currenty;
- gs_stack[gs_stack_top].gs_xheight2 = currentxheight2;
- debug0(DRS, D, "SaveGraphicState returning.");
-} /* end SaveGraphicState */
-
-
-/*****************************************************************************/
-/* */
-/* RestoreGraphicState() */
-/* */
-/* Restore previously saved coordinate system. NB we normally assume that */
-/* no white space is needed before any item of output, but since this */
-/* procedure is sometimes called immediately after PrintGraphicObject(), */
-/* which does not append a concluding space, we prepend one here. */
-/* */
-/*****************************************************************************/
-
-void RestoreGraphicState(void)
-{ debug0(DRS, D, "RestoreGraphicState()");
- assert( BackEnd != PLAINTEXT, "RestoreGraphicState: BackEnd!" );
- if( BackEnd == POSTSCRIPT )
- fprintf(out_fp, "\ngrestore\n");
- else if( BackEnd == PDF )
- PDFPage_Pop(out_fp);
- currentfont = gs_stack[gs_stack_top].gs_font;
- currentcolour = gs_stack[gs_stack_top].gs_colour;
- cpexists = gs_stack[gs_stack_top].gs_cpexists;
- currenty = gs_stack[gs_stack_top].gs_currenty;
- currentxheight2 = gs_stack[gs_stack_top].gs_xheight2;
- gs_stack_top--;
- /* ***
- cpexists = FALSE;
- currentfont = NO_FONT;
- currentcolour = NO_COLOUR;
- *** */
- debug0(DRS, D, "RestoreGraphicState returning.");
-} /* end RestoreGraphicState */
-
-
-/*@::PrintGraphicObject(), DefineGraphicNames()@******************************/
-/* */
-/* PrintGraphicObject(x) */
-/* */
-/* Print object x on out_fp */
-/* */
-/*****************************************************************************/
-
-void PrintGraphicObject(OBJECT x)
-{ OBJECT y, link;
- assert( BackEnd != PLAINTEXT, "PrintGraphicObject: BackEnd!" );
- debug3(DPS, D, "PrintGraphicObject(%s %s %s)",
- EchoFilePos(&fpos(x)), Image(type(x)), EchoObject(x));
- switch( type(x) )
- {
- case WORD:
- case QWORD:
-#if 1
- if (BackEnd == POSTSCRIPT)
- StringFPuts(string(x), out_fp);
- else if (BackEnd == PDF)
- {
- PDFPage_WriteGraphic(out_fp, string(x));
- }
-#else
- StringFPuts(string(x), out_fp);
-#endif
- break;
-
-
- case ACAT:
-
- for( link = Down(x); link != x; link = NextDown(link) )
- { Child(y, link);
- if( type(y) == GAP_OBJ )
- {
- if( BackEnd == POSTSCRIPT )
- {
- if( vspace(y) > 0 ) fputs("\n", out_fp);
- else if( hspace(y) > 0 ) fputs(" ", out_fp);
- }
- else if( BackEnd == PDF )
- {
- if( vspace(y) > 0 ) PDFPage_Write(out_fp, "\n");
- else if( hspace(y) > 0 ) PDFPage_Write(out_fp, " ");
- }
- }
- else if( is_word(type(y)) || type(y) == ACAT )
- PrintGraphicObject(y);
- else if( type(y) != WIDE && !is_index(type(y)) )
- /* @Wide, indexes are sometimes inserted by Manifest */
- { Error(24, 6, "error in left parameter of %s",
- WARN, &fpos(x), KW_GRAPHIC);
- debug1(DGP, D, " type(y) = %s, y =", Image(type(y)));
- ifdebug(DGP, D, DebugObject(y));
- }
- }
- break;
-
-
- default:
-
- Error(24, 7, "error in left parameter of %s", WARN, &fpos(x), KW_GRAPHIC);
- debug1(DGP, D, " type(x) = %s, x =", Image(type(x)));
- ifdebug(DGP, D, DebugObject(x));
- break;
-
- }
- debug0(DPS, D, "PrintGraphicObject returning");
-} /* end PrintGraphicObject */
-
-
-/*****************************************************************************/
-/* */
-/* DefineGraphicNames(x) */
-/* */
-/* Generate PostScript for xsize, ysize etc. names of graphic object. */
-/* */
-/*****************************************************************************/
-
-void DefineGraphicNames(OBJECT x)
-{ assert( type(x) == GRAPHIC, "PrintGraphic: type(x) != GRAPHIC!" );
- assert( BackEnd != PLAINTEXT, "DefineGraphicNames: BackEnd!" );
- debug1(DRS, D, "DefineGraphicNames( %s )", EchoObject(x));
- debug1(DRS, DD, " style = %s", EchoStyle(&save_style(x)));
-
- /* if font is different to previous word then print change */
- if( font(save_style(x)) != currentfont )
- { currentfont = font(save_style(x));
- if( currentfont > 0 )
- { currentxheight2 = FontHalfXHeight(currentfont);
-#if 1 /* VT 98/01/04: modified for PDF */
- if (BackEnd == POSTSCRIPT)
- fprintf(out_fp, "%hd %s ", FontSize(currentfont, x), FontName(currentfont));
- else if (BackEnd == PDF)
- PDFFont_Set(out_fp, FontSize(currentfont, x), FontName(currentfont));
-#else
- fprintf(out_fp, "%hd %s ", FontSize(currentfont, x),
- FontName(currentfont));
-#endif
- }
- }
-
- /* if colour is different to previous word then print change */
- if( colour(save_style(x)) != currentcolour )
- { currentcolour = colour(save_style(x));
- if( currentcolour > 0 )
- {
-#if 1
- if( BackEnd == POSTSCRIPT )
- fprintf(out_fp, "%s ", ColourCommand(currentcolour));
- else if (BackEnd == PDF)
- {
- char str[256];
- sprintf(str, "%s ", ColourCommand(currentcolour));
- PDFPage_Write(out_fp, str);
- }
-#else
- fprintf(out_fp, "%s ", ColourCommand(currentcolour));
-#endif
- }
- }
-
- if (BackEnd == POSTSCRIPT)
- fprintf(out_fp, "%d %d %d %d %d %d %d LoutGraphic\n",
- size(x, COLM), size(x, ROWM), back(x, COLM), fwd(x, ROWM),
- currentfont <= 0 ? 12*PT : FontSize(currentfont, x),
- width(line_gap(save_style(x))), width(space_gap(save_style(x))));
- else if( BackEnd == PDF )
- {
- PDFPage_SetVars(size(x, COLM), size(x, ROWM), back(x, COLM), fwd(x, ROWM),
- currentfont <= 0 ? 12*PT : FontSize(currentfont, x),
- width(line_gap(save_style(x))), width(space_gap(save_style(x))));
- }
-
- debug0(DRS, D, "DefineGraphicNames returning.");
-} /* end DefineGraphicNames */
-
-
-/*****************************************************************************/
-/* */
-/* SaveTranslateDefineSave(x, xdist, ydist) */
-/* */
-/* Equivalent to the sequence of calls */
-/* */
-/* SaveGraphicState(x) */
-/* CoordTranslate(xdist, ydist) */
-/* DefineGraphicNames(x) */
-/* SaveGraphicState(x) */
-/* */
-/* but generates less PostScript. */
-/* */
-/*****************************************************************************/
-
-void SaveTranslateDefineSave(OBJECT x, FULL_LENGTH xdist, FULL_LENGTH ydist)
-{
- if( BackEnd == PDF )
- {
- /* do it bit by bit */
- SaveGraphicState(x);
- CoordTranslate(xdist, ydist);
- DefineGraphicNames(x);
- SaveGraphicState(x);
- return;
- }
-
- assert( BackEnd == POSTSCRIPT, "SaveTranslateDefineSave: BackEnd!" );
- if( gs_stack_top >= MAX_GS - 1 || font(save_style(x)) != currentfont ||
- colour(save_style(x))!=currentcolour )
- {
- /* do it bit by bit, will be rare anyway */
- SaveGraphicState(x);
- CoordTranslate(xdist, ydist);
- DefineGraphicNames(x);
- SaveGraphicState(x);
- }
- else
- {
- /* no font or colour changes, no stack overflow, so can optimize */
-
- /* from Save */
- gs_stack_top++;
- gs_stack[gs_stack_top].gs_font = currentfont;
- gs_stack[gs_stack_top].gs_colour = currentcolour;
- gs_stack[gs_stack_top].gs_cpexists = cpexists;
- gs_stack[gs_stack_top].gs_currenty = currenty;
- gs_stack[gs_stack_top].gs_xheight2 = currentxheight2;
-
- /* from CoordTranslate */
- cpexists = FALSE;
-
- /* from Save */
- gs_stack_top++;
- gs_stack[gs_stack_top].gs_font = currentfont;
- gs_stack[gs_stack_top].gs_colour = currentcolour;
- gs_stack[gs_stack_top].gs_cpexists = cpexists;
- gs_stack[gs_stack_top].gs_currenty = currenty;
- gs_stack[gs_stack_top].gs_xheight2 = currentxheight2;
-
- /* accumulated output from all four calls, repackaged */
- fprintf(out_fp, "%d %d %d %d %d %d %d %d %d LoutGr2\n",
- size(x, COLM), size(x, ROWM), back(x, COLM), fwd(x, ROWM),
- currentfont <= 0 ? 12*PT : FontSize(currentfont, x),
- width(line_gap(save_style(x))), width(space_gap(save_style(x))),
- xdist, ydist);
-
- }
-} /* end SaveTranslateDefineSave */
-
-
-/*@::PrintGraphicInclude()@***************************************************/
-/* */
-/* PrintGraphicInclude(x, colmark, rowmark) */
-/* */
-/* Print graphic include file, with appropriate surrounds. This code */
-/* closely follows the PostScript Language Reference Manual, 2n ed., */
-/* pages 733-5, except we do not clip the included EPSF. */
-/* */
-/* Note to porters: Version 3.0 of the EPSF standard is not compatible */
-/* with previous versions. Thus, this output may crash your system. */
-/* If you can find out which comment line(s) are causing the trouble, */
-/* you can add to procedure strip_out to strip them out during the */
-/* file inclusion step. e.g. on my system %%EOF causes problems, so I */
-/* strip it out. */
-/* */
-/* May 1994: I've just discovered that %%Trailer causes problems for */
-/* the mpage Unix utility, so now I'm stripping it out as well. */
-/* */
-/*****************************************************************************/
-#define SKIPPING 0
-#define READING_DNR 1
-#define FINISHED 2
-
-static BOOLEAN strip_out(FULL_CHAR *buff)
-{ if( StringBeginsWith(buff, AsciiToFull("%%EOF")) ) return TRUE;
- if( StringBeginsWith(buff, AsciiToFull("%%Trailer")) ) return TRUE;
- return FALSE;
-} /* end strip_out */
-
-void PrintGraphicInclude(OBJECT x, FULL_LENGTH colmark, FULL_LENGTH rowmark)
-{ OBJECT y, full_name; FULL_CHAR buff[MAX_BUFF];
- FILE *fp; int state; BOOLEAN compressed;
- debug0(DRS, D, "PrintGraphicInclude(x)");
-
- if (BackEnd == PDF)
- {
- Error(24, 8, "PrintGraphicInclude: cannot include EPSF in a PDF file. File ignored.",
- WARN, &fpos(x));
- return;
- }
-
- assert( BackEnd == POSTSCRIPT, "PrintGraphicInclude: BackEnd!" );
- assert(type(x)==INCGRAPHIC || type(x)==SINCGRAPHIC, "PrintGraphicInclude!");
- assert(incgraphic_ok(x), "PrintGraphicInclude: !incgraphic_ok(x)!");
-
- /* open the include file and get its full path name */
- Child(y, Down(x));
- fp = OpenIncGraphicFile(string(y), type(x), &full_name,&fpos(y),&compressed);
- assert( fp != NULL, "PrintGraphicInclude: fp!" );
-
- /* if font is different to previous word then print change */
- if( font(save_style(x)) != currentfont )
- { currentfont = font(save_style(x));
- currentxheight2 = FontHalfXHeight(currentfont);
- fprintf(out_fp, "%hd %s\n", FontSize(currentfont,x), FontName(currentfont));
- }
-
- /* if colour is different to previous word then print change */
- if( colour(save_style(x)) != currentcolour )
- { currentcolour = colour(save_style(x));
- if( currentcolour > 0 )
- {
- fprintf(out_fp, "%s\n", ColourCommand(currentcolour));
- }
- }
-
- /* generate appropriate header code */
- fprintf(out_fp, "BeginEPSF\n");
- CoordTranslate(colmark - back(x, COLM), rowmark - fwd(x, ROWM));
- CoordScale( (float) PT, (float) PT );
- CoordTranslate(-back(y, COLM), -back(y, ROWM));
- fprintf(out_fp, "%%%%BeginDocument: %s\n", string(full_name));
-
- /* copy through the include file, except divert resources lines to needs */
- /* and strip out some comment lines that cause problems */
- state = (StringFGets(buff, MAX_BUFF, fp) == NULL) ? FINISHED : SKIPPING;
- while( state != FINISHED ) switch(state)
- {
- case SKIPPING:
-
- if( StringBeginsWith(buff, AsciiToFull("%%DocumentNeededResources:")) &&
- !StringContains(buff, AsciiToFull("(atend)")) )
- { y = MakeWord(WORD, &buff[StringLength("%%DocumentNeededResources:")],
- no_fpos);
- Link(needs, y);
- state = (StringFGets(buff,MAX_BUFF,fp)==NULL) ? FINISHED : READING_DNR;
- }
- else
- { if( StringBeginsWith(buff, AsciiToFull("%%LanguageLevel:")) )
- Error(24, 9, "ignoring LanguageLevel comment in %s file %s",
- WARN, &fpos(x), KW_INCGRAPHIC, string(full_name));
- if( StringBeginsWith(buff, AsciiToFull("%%Extensions:")) )
- Error(24, 10, "ignoring Extensions comment in %s file %s",
- WARN, &fpos(x), KW_INCGRAPHIC, string(full_name));
- if( !strip_out(buff) ) StringFPuts(buff, out_fp);
- state = (StringFGets(buff, MAX_BUFF, fp) == NULL) ? FINISHED : SKIPPING;
- }
- break;
-
- case READING_DNR:
-
- if( StringBeginsWith(buff, AsciiToFull("%%+")) )
- { x = MakeWord(WORD, &buff[StringLength(AsciiToFull("%%+"))], no_fpos);
- Link(needs, x);
- state = (StringFGets(buff,MAX_BUFF,fp)==NULL) ? FINISHED : READING_DNR;
- }
- else
- { if( !strip_out(buff) ) StringFPuts(buff, out_fp);
- state = (StringFGets(buff, MAX_BUFF, fp) == NULL) ? FINISHED : SKIPPING;
- }
- break;
- }
-
- /* wrapup */
- DisposeObject(full_name);
- fclose(fp);
- if( compressed ) StringRemove(AsciiToFull(LOUT_EPS));
- fprintf(out_fp, "\n%%%%EndDocument\nEndEPSF\n");
- wordcount = 0;
- debug0(DRS, D, "PrintGraphicInclude returning.");
-} /* end PrintGraphicInclude */