diff options
Diffstat (limited to 'z49.c')
-rw-r--r-- | z49.c | 206 |
1 files changed, 162 insertions, 44 deletions
@@ -1,7 +1,7 @@ /*@z49.c:PostScript Back End:PS_BackEnd@**************************************/ /* */ -/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.36) */ -/* COPYRIGHT (C) 1991, 2007 Jeffrey H. Kingston */ +/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.37) */ +/* COPYRIGHT (C) 1991, 2008 Jeffrey H. Kingston */ /* */ /* Jeffrey H. Kingston (jeff@it.usyd.edu.au) */ /* School of Information Technologies */ @@ -487,8 +487,97 @@ static void PS_PrintMapping(MAPPING m) /*****************************************************************************/ /* */ +/* PS_BtoI(const unsigned char *buf) */ +/* */ +/* Decode a 4 byte value from an EPSF header */ +/* in a machine independent way. */ +/* */ +/*****************************************************************************/ + +static long PS_BtoI(const unsigned char *buf) +{ + return ((buf[ 0 ] & 0xFF)) | + ((buf[ 1 ] & 0xFF) << 8) | + ((buf[ 2 ] & 0xFF) << 16) | + ((buf[ 3 ] & 0xFF) << 24); +} + + +/*****************************************************************************/ +/* */ +/* PS_FindEPSSegment(FILE *fp, long *len) */ +/* */ +/* Find the EPS segment of an EPS file */ +/* If the file is an EPSF with a EPS segment */ +/* skip to the start of the EPS segment */ +/* set the length to the length of the EPS segment */ +/* Otherwise if the file is plain EPS */ +/* leave the file pointer at the start of the file */ +/* set the length to -1 */ +/* */ +/*****************************************************************************/ + +static void PS_FindEPSSegment(FILE *fp, long *len) +{ + enum epsf_header_enum { + HEADER_LEN = 30, /* length of header */ + HEADER_MAGIC_0 = 0xC5, /* E */ + HEADER_MAGIC_1 = 0xD0, /* P */ + HEADER_MAGIC_2 = 0xD3, /* S */ + HEADER_MAGIC_3 = 0xC6, /* F */ + HEADER_EPS_START_OFFSET = 4, /* offset of eps start */ + HEADER_EPS_LENGTH_OFFSET = 8 /* offset of eps length */ + }; + + unsigned char epsf_header[ HEADER_LEN ]; + long original_position; + long eps_start; + + *len = -1; + + /* check for a valid file pointer */ + if( fp == NULL ) + { + return; + } + + /* save the original file position */ + original_position = ftell(fp); + if( original_position < 0 ) + { + original_position = 0; + } + + /* read and parse the header */ + rewind(fp); + if( fread(epsf_header, 1, HEADER_LEN, fp) == HEADER_LEN && + epsf_header[0] == HEADER_MAGIC_0 && + epsf_header[1] == HEADER_MAGIC_1 && + epsf_header[2] == HEADER_MAGIC_2 && + epsf_header[3] == HEADER_MAGIC_3 && + (eps_start = PS_BtoI( &epsf_header[ HEADER_EPS_START_OFFSET ] )) > 0 && + (*len = PS_BtoI( &epsf_header[ HEADER_EPS_LENGTH_OFFSET ] )) >= 0 && + fseek(fp, eps_start, SEEK_SET) != -1 ) + { + /* success locating the EPS segment */ + } + else + { + /* this file has no preview */ + /* reset the file pointer */ + *len = -1; + fseek(fp, original_position, SEEK_SET); + } +} + + +/*****************************************************************************/ +/* */ /* void PS_PrintEPSFile(FILE *fp, FILE_POS *pos, BOOLEAN strip_all) */ /* */ +/* Original by Jeff Kingston, modified Jul 2008 by William Bader mainly */ +/* to allow EPS files to contain null characters. */ +/* */ /* Print EPS file fp to out_fp. */ /* */ /* If strip_all is TRUE, strip out all lines beginning with %%, else */ @@ -508,12 +597,14 @@ static BOOLEAN strip_out(FULL_CHAR *buff, BOOLEAN strip_all) } /* end strip_out */ static void PS_PrintEPSFile(FILE *fp, FILE_POS *pos, BOOLEAN strip_all) -{ int state, x; OBJECT y; +{ int state, x, count; OBJECT y; long len; FULL_CHAR buff[MAX_LINE]; - debug0(DPO, D, "[ PS_PrintEPSFile"); + debug0(DPO, DD, "[ PS_PrintEPSFile"); assert( fp != NULL, "PS_PrintEPSFile: fp!" ); - state = (ReadOneLine(fp, buff, MAX_LINE) == 0) ? FINISHED : SKIPPING; + /* state = (ReadOneLine(fp, buff, MAX_LINE) == 0) ? FINISHED : SKIPPING; */ + state = (ReadOneBinaryLine(fp, buff, MAX_LINE, &count, &len) == 0) ? + FINISHED : SKIPPING; while( state != FINISHED ) switch(state) { case SKIPPING: @@ -523,7 +614,11 @@ static void PS_PrintEPSFile(FILE *fp, FILE_POS *pos, BOOLEAN strip_all) { y = MakeWord(WORD, &buff[StringLength("%%DocumentNeededResources:")], no_fpos); Link(needs, y); + /* *** state = (ReadOneLine(fp, buff, MAX_LINE) == 0) ? FINISHED : READING_DNR; + *** */ + state = (ReadOneBinaryLine(fp, buff, MAX_LINE, &count, &len) == 0) ? + FINISHED : READING_DNR; } else { if( StringBeginsWith(buff, AsciiToFull("%%LanguageLevel:")) ) @@ -535,10 +630,17 @@ static void PS_PrintEPSFile(FILE *fp, FILE_POS *pos, BOOLEAN strip_all) Error(49, 11, "ignoring Extensions comment in EPS file", WARN, pos); if( !strip_out(buff, strip_all) ) { + /* *** StringFPuts(buff, out_fp); pnl; + *** */ + fwrite(buff, 1, count, out_fp); } + /* *** state = (ReadOneLine(fp, buff, MAX_LINE) == 0) ? FINISHED : SKIPPING; + *** */ + state = (ReadOneBinaryLine(fp, buff, MAX_LINE, &count, &len) == 0) ? + FINISHED : SKIPPING; } break; @@ -547,20 +649,32 @@ static void PS_PrintEPSFile(FILE *fp, FILE_POS *pos, BOOLEAN strip_all) if( StringBeginsWith(buff, AsciiToFull("%%+")) ) { y = MakeWord(WORD, &buff[StringLength(AsciiToFull("%%+"))], no_fpos); Link(needs, y); + /* *** state = (ReadOneLine(fp, buff, MAX_LINE) == 0) ? FINISHED : READING_DNR; + *** */ + state = (ReadOneBinaryLine(fp, buff, MAX_LINE, &count, &len) == 0) ? + FINISHED : READING_DNR; } else { if( !strip_out(buff, strip_all) ) { + /* *** StringFPuts(buff, out_fp); pnl; + *** */ + fwrite(buff, 1, count, out_fp); } + /* *** state = (ReadOneLine(fp, buff, MAX_LINE) == 0) ? FINISHED : SKIPPING; + *** */ + state = (ReadOneBinaryLine(fp, buff, MAX_LINE, &count, &len) == 0) ? + FINISHED : SKIPPING; } break; } + pnl; /* in case the last line does not end with a line terminator */ fclose(fp); - debug0(DPO, D, "] PS_PrintEPSFile returning."); + debug0(DPO, DD, "] PS_PrintEPSFile returning."); } /* end PS_PrintEPSFile */ @@ -653,7 +767,7 @@ static const char *MediaName(int h, int v) static void PS_PrintBeforeFirstPage(FULL_LENGTH h, FULL_LENGTH v, FULL_CHAR *label) { FILE_NUM fnum; FULL_CHAR *p; - debug2(DPO, DD, "PrintBeforeFirst(%d, %d)", h, v); + debug2(DPO, DD, "PrintBeforeFirst(%s, %s)", EchoLength(h), EchoLength(v)); /* print header comments for PostScript DSC 3.0 output */ p0(encapsulated ? "%!PS-Adobe-3.0 EPSF-3.0" : "%!PS-Adobe-3.0"); @@ -1200,10 +1314,10 @@ static void PS_PrintBetweenPages(FULL_LENGTH h, FULL_LENGTH v, FULL_CHAR *label) /*****************************************************************************/ static void PrintComposite(COMPOSITE *cp, BOOLEAN outline, FILE *fp) -{ debug1(DPO, D, "PrintComposite(cp, %s, fp)", bool(outline)); +{ debug1(DPO, DD, "PrintComposite(cp, %s, fp)", bool(outline)); while( cp->char_code != '\0' ) { - debug4(DPO, D, " cp = %d printing code %d (%d, %d)", (int) cp, + debug4(DPO, DD, " 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"); @@ -1225,7 +1339,7 @@ static void PS_PrintWord(OBJECT x, int hpos, int vpos) int ksize; char *command; MAPPING m; unsigned short *composite; COMPOSITE *cmp; - debug7(DPO, DD, "PrintWord( %s, %d, %d ) font %d colour %d texture %d%s", + debug7(DPO, D, "PrintWord( %s, %d, %d ) font %d colour %d texture %d%s", string(x), hpos, vpos, word_font(x), word_colour(x), word_texture(x), word_outline(x) ? " outline":""); TotalWordCount++; @@ -1286,7 +1400,7 @@ static void PS_PrintWord(OBJECT x, int hpos, int vpos) if( composite[*p] ) { fprintf(out_fp, ")%s ", command); - debug3(DPO, D, + debug3(DPO, DD, " 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); @@ -1307,7 +1421,7 @@ static void PS_PrintWord(OBJECT x, int hpos, int vpos) } if( composite[*p] ) { fprintf(out_fp, ")%s ", command); - debug3(DPO, D, + debug3(DPO, DD, " 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); @@ -1322,7 +1436,7 @@ static void PS_PrintWord(OBJECT x, int hpos, int vpos) wordcount = 0; } else fprintf(out_fp, ")%s ", command); - debug0(DPO, DDD, "PrintWord returning"); + debug0(DPO, DD, "PrintWord returning"); } /* end PS_PrintWord */ @@ -1374,11 +1488,11 @@ static void PS_PrintUnderline(FONT_NUM fnum, COLOUR_NUM col, /*****************************************************************************/ static void PS_CoordTranslate(FULL_LENGTH xdist, FULL_LENGTH ydist) -{ debug2(DPO, D, "PS_CoordTranslate(%s, %s)", +{ debug2(DPO, DD, "PS_CoordTranslate(%s, %s)", EchoLength(xdist), EchoLength(ydist)); p2("%d %d translate", xdist, ydist); cpexists = FALSE; - debug0(DPO, D, "PS_CoordTranslate returning."); + debug0(DPO, DD, "PS_CoordTranslate returning."); } /* end PS_CoordTranslate */ @@ -1391,10 +1505,10 @@ static void PS_CoordTranslate(FULL_LENGTH xdist, FULL_LENGTH ydist) /*****************************************************************************/ static void PS_CoordRotate(FULL_LENGTH amount) -{ debug1(DPO, D, "PS_CoordRotate(%.1f degrees)", (float) amount / DG); +{ debug1(DPO, DD, "PS_CoordRotate(%.1f degrees)", (float) amount / DG); p1("%.4f rotate", (float) amount / DG); cpexists = FALSE; - debug0(DPO, D, "CoordRotate returning."); + debug0(DPO, DD, "CoordRotate returning."); } /* end PS_CoordRotate */ @@ -1411,11 +1525,11 @@ static void PS_CoordScale(float hfactor, float vfactor) #if DEBUG_ON char buff[20]; #endif - ifdebug(DPO, D, sprintf(buff, "%.3f, %.3f", hfactor, vfactor)); - debug1(DPO, D, "CoordScale(%s)", buff); + ifdebug(DPO, DD, sprintf(buff, "%.3f, %.3f", hfactor, vfactor)); + debug1(DPO, DD, "CoordScale(%s)", buff); p2("%.4f %.4f scale", hfactor, vfactor); cpexists = FALSE; - debug0(DPO, D, "CoordScale returning."); + debug0(DPO, DD, "CoordScale returning."); } /* end PS_CoordScale */ @@ -1429,10 +1543,10 @@ static void PS_CoordScale(float hfactor, float vfactor) static void PS_CoordHMirror(void) { - debug0(DPO, D, "CoordHMirror()"); + debug0(DPO, DD, "CoordHMirror()"); cpexists = FALSE; p0("[-1 0 0 1 0 0] concat"); - debug0(DPO, D, "CoordHMirror returning."); + debug0(DPO, DD, "CoordHMirror returning."); } @@ -1446,10 +1560,10 @@ static void PS_CoordHMirror(void) static void PS_CoordVMirror(void) { - debug0(DPO, D, "CoordVMirror()"); + debug0(DPO, DD, "CoordVMirror()"); cpexists = FALSE; p0("[1 0 0 -1 0 0] concat"); - debug0(DPO, D, "CoordVMirror returning."); + debug0(DPO, DD, "CoordVMirror returning."); } @@ -1463,7 +1577,7 @@ static void PS_CoordVMirror(void) /*****************************************************************************/ static void PS_SaveGraphicState(OBJECT x) -{ debug0(DPO, D, "SaveGraphicState()"); +{ debug0(DPO, DD, "SaveGraphicState()"); p0("gsave"); gs_stack_top++; if( gs_stack_top >= MAX_GS ) @@ -1476,7 +1590,7 @@ static void PS_SaveGraphicState(OBJECT x) 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(DPO, D, "PS_SaveGraphicState returning."); + debug0(DPO, DD, "PS_SaveGraphicState returning."); } /* end PS_SaveGraphicState */ @@ -1492,7 +1606,7 @@ static void PS_SaveGraphicState(OBJECT x) /*****************************************************************************/ static void PS_RestoreGraphicState(void) -{ debug0(DPO, D, "PS_RestoreGraphicState()"); +{ debug0(DPO, DD, "PS_RestoreGraphicState()"); pnl; p0("grestore"); currentfont = gs_stack[gs_stack_top].gs_font; @@ -1503,7 +1617,7 @@ static void PS_RestoreGraphicState(void) currenty = gs_stack[gs_stack_top].gs_currenty; currentxheight2 = gs_stack[gs_stack_top].gs_xheight2; gs_stack_top--; - debug0(DPO, D, "PS_RestoreGraphicState returning."); + debug0(DPO, DD, "PS_RestoreGraphicState returning."); } /* end PS_RestoreGraphicState */ @@ -1517,7 +1631,7 @@ static void PS_RestoreGraphicState(void) void PS_PrintGraphicObject(OBJECT x) { OBJECT y, link; - debug3(DPO, D, "PS_PrintGraphicObject(%s %s %s)", + debug3(DPO, DD, "PS_PrintGraphicObject(%s %s %s)", EchoFilePos(&fpos(x)), Image(type(x)), EchoObject(x)); switch( type(x) ) { @@ -1546,8 +1660,8 @@ void PS_PrintGraphicObject(OBJECT x) else { Error(49, 8, "error in left parameter of %s", WARN, &fpos(x), KW_GRAPHIC); - debug1(DPO, D, " type(y) = %s, y =", Image(type(y))); - ifdebug(DPO, D, DebugObject(y)); + debug1(DPO, DD, " type(y) = %s, y =", Image(type(y))); + ifdebug(DPO, DD, DebugObject(y)); } } break; @@ -1556,12 +1670,12 @@ void PS_PrintGraphicObject(OBJECT x) default: Error(49, 9, "error in left parameter of %s", WARN, &fpos(x), KW_GRAPHIC); - debug1(DPO, D, " type(x) = %s, x =", Image(type(x))); - ifdebug(DPO, D, DebugObject(x)); + debug1(DPO, DD, " type(x) = %s, x =", Image(type(x))); + ifdebug(DPO, DD, DebugObject(x)); break; } - debug0(DPO, D, "PS_PrintGraphicObject returning"); + debug0(DPO, DD, "PS_PrintGraphicObject returning"); } /* end PS_PrintGraphicObject */ @@ -1575,7 +1689,7 @@ void PS_PrintGraphicObject(OBJECT x) void PS_DefineGraphicNames(OBJECT x) { assert( type(x) == GRAPHIC, "PrintGraphic: type(x) != GRAPHIC!" ); - debug1(DPO, D, "PS_DefineGraphicNames( %s )", EchoObject(x)); + debug1(DPO, DD, "PS_DefineGraphicNames( %s )", EchoObject(x)); debug1(DPO, DD, " style = %s", EchoStyle(&save_style(x))); SetBaseLineMarkAndFont(baselinemark(save_style(x)), font(save_style(x))); @@ -1587,7 +1701,7 @@ void PS_DefineGraphicNames(OBJECT x) currentfont <= 0 ? 12*PT : FontSize(currentfont, x), width(line_gap(save_style(x))), width(space_gap(save_style(x))), (char *) STR_NEWLINE); - debug0(DPO, D, "PS_DefineGraphicNames returning."); + debug0(DPO, DD, "PS_DefineGraphicNames returning."); } /* end PS_DefineGraphicNames */ @@ -1670,6 +1784,7 @@ static void PS_SaveTranslateDefineSave(OBJECT x, FULL_LENGTH xdist, BOOLEAN PS_FindBoundingBox(FILE *fp, FILE_POS *pos, FULL_LENGTH *llx, FULL_LENGTH *lly, FULL_LENGTH *urx, FULL_LENGTH *ury) { FULL_CHAR buff[MAX_LINE]; + long len; float fllx, flly, furx, fury; *llx = *lly = *urx = *ury = 0; @@ -1680,6 +1795,9 @@ BOOLEAN PS_FindBoundingBox(FILE *fp, FILE_POS *pos, FULL_LENGTH *llx, return FALSE; } + /* skip to the EPS if this file has a preview */ + PS_FindEPSSegment(fp, &len); + /* if the file is empty, say so and return failure */ if( ReadOneLine(fp, buff, MAX_LINE) == 0 ) { @@ -1749,7 +1867,7 @@ BOOLEAN PS_FindBoundingBox(FILE *fp, FILE_POS *pos, FULL_LENGTH *llx, static void PS_PrintGraphicInclude(OBJECT x, FULL_LENGTH colmark, FULL_LENGTH rowmark) { OBJECT y, full_name; FILE *fp; BOOLEAN compressed; int fnum; - debug0(DPO, D, "PS_PrintGraphicInclude(x)"); + debug0(DPO, DD, "PS_PrintGraphicInclude(x)"); assert(type(x)==INCGRAPHIC || type(x)==SINCGRAPHIC, "PrintGraphicInclude!"); assert(incgraphic_ok(x), "PrintGraphicInclude: !incgraphic_ok(x)!"); @@ -1799,7 +1917,7 @@ static void PS_PrintGraphicInclude(OBJECT x, FULL_LENGTH colmark, cpexists = FALSE; currentfont = NO_FONT; /* added by JeffK 31/10/06 */ wordcount = 0; - debug0(DPO, D, "PS_PrintGraphicInclude returning."); + debug0(DPO, DD, "PS_PrintGraphicInclude returning."); } /* end PS_PrintGraphicInclude */ @@ -1850,7 +1968,7 @@ char *ConvertToPDFName(OBJECT name) static void PS_LinkSource(OBJECT name, FULL_LENGTH llx, FULL_LENGTH lly, FULL_LENGTH urx, FULL_LENGTH ury) -{ debug5(DPO, D, "PS_LinkSource(%s, %d, %d, %d, %d)", EchoObject(name), +{ debug5(DPO, DD, "PS_LinkSource(%s, %d, %d, %d, %d)", EchoObject(name), llx, lly, urx, ury); /* print the link source point */ @@ -1862,7 +1980,7 @@ static void PS_LinkSource(OBJECT name, FULL_LENGTH llx, FULL_LENGTH lly, /* remember it so that at end of run can check if it has an dest point */ Link(link_source_list, name); - debug0(DPO, D, "PS_LinkSource returning."); + debug0(DPO, DD, "PS_LinkSource returning."); } /* end PS_LinkSource */ @@ -1909,7 +2027,7 @@ static void PS_LinkDest(OBJECT name, FULL_LENGTH llx, FULL_LENGTH lly, static void PS_LinkURL(OBJECT url, FULL_LENGTH llx, FULL_LENGTH lly, FULL_LENGTH urx, FULL_LENGTH ury) -{ debug5(DPO, D, "PS_LinkURL(%s, %d, %d, %d, %d)", EchoObject(url), +{ debug5(DPO, DD, "PS_LinkURL(%s, %d, %d, %d, %d)", EchoObject(url), llx, lly, urx, ury); if( is_word(type(url)) ) @@ -1924,7 +2042,7 @@ static void PS_LinkURL(OBJECT url, FULL_LENGTH llx, FULL_LENGTH lly, Error(49, 22, "%s ignored; left parameter not a simple word", WARN, &fpos(url), KW_LINK_URL); - debug0(DPO, D, "PS_LinkURL returning."); + debug0(DPO, DD, "PS_LinkURL returning."); } /* end PS_LinkSource */ @@ -1939,7 +2057,7 @@ static void PS_LinkURL(OBJECT url, FULL_LENGTH llx, FULL_LENGTH lly, static void PS_LinkCheck(void) { OBJECT y, link; - debug0(DPO, D, "PS_LinkCheck()"); + debug0(DPO, DD, "PS_LinkCheck()"); for( link=Down(link_source_list); link!=link_source_list; link=NextDown(link) ) { Child(y, link); @@ -1949,7 +2067,7 @@ static void PS_LinkCheck(void) string(y)); } - debug0(DPO, D, "PS_LinkCheck returning."); + debug0(DPO, DD, "PS_LinkCheck returning."); } /* end PS_LinkCheck */ |