diff options
author | Jeffrey H. Kingston <jeff@it.usyd.edu.au> | 2010-09-14 20:36:56 +0000 |
---|---|---|
committer | Jeffrey H. Kingston <jeff@it.usyd.edu.au> | 2010-09-14 20:36:56 +0000 |
commit | 162643f981292504f375a7f834d408a4a0fa7f46 (patch) | |
tree | a52e523ace2e98b57c761a8319f45b8aee208fce /z24.c | |
parent | b10d39aec443165093f8f28bc6f940530b89cdaf (diff) | |
download | lout-162643f981292504f375a7f834d408a4a0fa7f46.tar.gz |
Lout 3.22.
git-svn-id: http://svn.savannah.nongnu.org/svn/lout/trunk@13 9365b830-b601-4143-9ba8-b4a8e2c3339c
Diffstat (limited to 'z24.c')
-rw-r--r-- | z24.c | 1569 |
1 files changed, 7 insertions, 1562 deletions
@@ -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 */ |