/* $Xorg: psout.c,v 1.9 2001/03/26 15:25:12 coskrey Exp $ */ /* Copyright 1996, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* * (c) Copyright 1996 Hewlett-Packard Company * (c) Copyright 1996 International Business Machines Corp. * (c) Copyright 1996, 2000 Sun Microsystems, Inc. All Rights Reserved. * (c) Copyright 1996 Novell, Inc. * (c) Copyright 1996 Digital Equipment Corp. * (c) Copyright 1996 Fujitsu Limited * (c) Copyright 1996 Hitachi, Ltd. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject * to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the names of the copyright holders * shall not be used in advertising or otherwise to promote the sale, use * or other dealings in this Software without prior written authorization * from said copyright holders. */ /******************************************************************* ** ** ********************************************************* ** * ** * File: psout.c ** * ** * Contents: Code to output PostScript to file ** * ** * Created By: Roger Helmendach (Liberty Systems) ** * ** * Copyright: Copyright 1996 The Open Group, Inc. ** * ** ********************************************************* ** ********************************************************************/ #include #include #include "os.h" #define USE_PSOUT_PRIVATE 1 #include "psout.h" /* For VENDOR_STRING and VENDOR_RELEASE */ #include "site.h" extern PsElmPtr PsCloneFillElementList(int nElms, PsElmPtr elms); extern void PsDestroyFillElementList(int nElms, PsElmPtr elms); /* * Standard definitions */ static char *S_StandardDefs = "\ /d{def}bind def\ /b{bind}bind d\ /bd{b d}b d\ /x{exch}bd\ /xd{x d}bd\ /dp{dup}bd\ /t{true}bd\ /f{false}bd\ /p{pop}bd\ /r{roll}bd\ /c{copy}bd\ /i{index}bd\ /rp{repeat}bd\ /n{newpath}bd\ /w{setlinewidth}bd\ /lc{setlinecap}bd\ /lj{setlinejoin}bd\ /sml{setmiterlimit}bd\ /ds{setdash}bd\ /ie{ifelse}bd\ /len{length}bd\ /m{moveto}bd\ /rm{rmoveto}bd\ /l{lineto}bd\ /rl{rlineto}bd\ /a{arc}bd\ /an{arcn}bd\ /st{stroke}bd\ /fl{fill}bd\ /ef{eofill}bd\ /sp{showpage}bd\ /cp{closepath}bd\ /clp{clippath}bd\ /cl{clip}bd\ /pb{pathbbox}bd\ /tr{translate}bd\ /rt{rotate}bd\ /dv{div}bd\ /ml{mul}bd\ /ad{add}bd\ /ng{neg}bd\ /scl{scale}bd\ /sc{setrgbcolor}bd\ /g{setgray}bd\ /gs{gsave}bd\ /gr{grestore}bd\ /sv{save}bd\ /rs{restore}bd\ /mx{matrix}bd\ /cm{currentmatrix}bd\ /sm{setmatrix}bd\ /ccm{concatmatrix}bd\ /cc{concat}bd\ /ff{findfont}bd\ /mf{makefont}bd\ /sf{setfont}bd\ /cft{currentfont}bd\ /fd{FontDirectory}bd\ /sh{show}bd\ /stw{stringwidth}bd\ /ci{colorimage}bd\ /ig{image}bd\ /im{imagemask}bd\ /cf{currentfile}bd\ /rh{readhexstring}bd\ /str{string}bd\ /al{aload}bd\ /wh{where}bd\ /kn{known}bd\ /stp{stopped}bd\ /bg{begin}bd\ /ed{end}bd\ /fa{forall}bd\ /pi{putinterval}bd\ /mk{mark}bd\ /ctm{cleartomark}bd\ /df{definefont}bd\ /cd{currentdict}bd\ /db{20 dict dp bg}bd\ /de{ed}bd\ /languagelevel wh{p languagelevel}{1}ie\ 1 eq{/makepattern{p}bd/setpattern{p}bd/setpagedevice{p}bd}if\ /mp{makepattern}bd\ /spt{setpattern}bd\ /spd{setpagedevice}bd\ " #ifdef XP_USE_FREETYPE "/trmoveto{currentfont /FontMatrix get transform rm}d" #endif /* XP_USE_FREETYPE */ ; /* * Composite definitions * * * XYr - Return X/Y dpi for device * * XYr * * Cs - Coordinate setup (for origin upper left) * * Cs * * P - Draw a point * * P * * R - Add rectangle to path * * R * * Ac - Add arc to path * * Ac * * An - Add arc to path (counterclockwise) * * An * * Tf - Set font * * Tf * * Tfm - Set font with matrix * * Tfm * * T - Draw text * * T * * Tb - Draw text with background color * * Tb * * Im1 - Image 1 bit monochrome imagemask * * Im1 * * Im24 - Image 24 bit RGB color * * Im24 * * Im1t - Image 1 bit monochrome imagemask (in tile) * * Im1t * * Im24t - Image 24 bit RGB color (in tile) * * Im24t */ static char *S_CompositeDefs = "\ /XYr{/currentpagedevice wh\ {p currentpagedevice dp /HWResolution kn\ {/HWResolution get al p}{p 300 300}ie}{300 300}ie}bd\ /Cs{dp 0 eq{0 pHt tr XYr -1 x dv 72 ml x 1 x dv 72 ml x scl}if\ dp 1 eq{90 rt XYr -1 x dv 72 ml x 1 x dv 72 ml x scl}if\ dp 2 eq{pWd 0 tr XYr 1 x dv 72 ml x -1 x dv 72 ml x scl}if\ 3 eq{pHt pWd tr 90 rt XYr 1 x dv 72 ml x -1 x dv 72 ml x scl}if}bd\ /P{gs 1 w [] 0 ds 2 c m .1 ad x .1 ad x l st gr}bd\ /R{4 2 r m 1 i 0 rl 0 x rl ng 0 rl cp}bd\ /Ac{mx_ cm p 6 -2 r tr 4 2 r ng scl 0 0 .5 5 3 r a mx_ sm}bd\ /An{mx_ cm p 6 -2 r tr 4 2 r ng scl 0 0 .5 5 3 r an mx_ sm}bd\ /ISO{dp len dict bg{1 i/FID ne{d}{p p}ie}fa\ /Encoding ISOLatin1Encoding d cd ed df}bd\ /iN{dp len str cvs dp len x 1 i 3 ad str 2 c c p x p dp 3 -1 r(ISO)pi}bd\ /Tp{{x dp iN dp fd x kn{x p dp/f_ x d ff}{dp/f_ x d x ff ISO}ie x}\ {x dp/f_ x d ff x}ie}bd\ /Tf{Tp[x 0 0 2 i ng 0 0] dp/fm_ x d mf sf}bd\ /Tfm{Tp 1 -1 tm1_ scl tm2_ ccm dp/fm_ x d mf sf}bd\ /T{m sh}bd\ /Tb{gs sc f_ ff sf cft/FontMatrix get 3 get\ cft/FontBBox get dp 1 get x 3 get 2 i ml 3 1 r ml\ 0 0 m 4 i stw p 4 i 4 i m fm_ cc\ 0 2 i rl dp 0 rl 0 2 i ng rl 0 3 i rl ng 0 rl cp fl p p\ gr T}bd\ /Im1{6 4 r tr scl t [3 i 0 0 5 i 0 0]{cf str1 rh p} im}bd\ /Im1rev{6 4 r tr scl f [3 i 0 0 5 i 0 0]{cf str1 rh p} im}bd\ /Im24{gs 6 4 r tr scl 8 [3 i 0 0 5 i 0 0]{cf str3 rh p} f 3 ci}bd\ /Im1t{6 4 r tr scl t [3 i 0 0 5 i 0 0]{} im}bd\ /Im24t{gs 6 4 r tr scl 8 [3 i 0 0 5 i 0 0]{} f 3 ci}bd\ /ck2{/currentpagedevice wh \ {p dp currentpagedevice dp 3 -1 r kn \ {x get al p 3 -1 r eq 3 1 r eq and } \ {p p p p t}ie} \ {p p p t}ie}bd \ /ck1{/currentpagedevice wh \ {p dp currentpagedevice dp 3 -1 r kn \ {x get eq} {p p p t}ie} \ {p p t}ie}bd \ /mtx{scl t [3 i 0 0 5 i 0 0]}bd \ "; char *pg_orient[] = {"Portrait","Landscape","Reverse Portrait","Reverse Landscape"}; /* * Setup definitions */ static char *S_SetupDefs = "\ /mx_ mx d\ /im_ mx d\ /tm1_ mx d\ /tm2_ mx d\ /str3 3 str d\ /str1 1 str d\ "; /******************************************************************* * PRIVATE FUNCTIONS * *******************************************************************/ void S_Flush(PsOutPtr self) { if( self->Buf[0] ) { if( self->Buf[strlen(self->Buf)-1]!='\n' ) strcat(self->Buf, "\n"); if (!ferror(self->Fp)) { (void) fputs(self->Buf, self->Fp); } self->Buf[0] = '\0'; } } static void S_Comment(PsOutPtr self, char *comment) { S_Flush(self); strcpy(self->Buf, comment); S_Flush(self); } static void S_OutDefs(PsOutPtr self, char *defs) { int i, k=0; S_Flush(self); memset(self->Buf, 0, sizeof(self->Buf)); for( i=0 ; defs[i]!='\0' ;) { if( k>70 && (i==0 || (i && defs[i-1]!='/')) && (defs[i]==' ' || defs[i]=='/' || defs[i]=='{') ) { S_Flush(self); k = 0; memset(self->Buf, 0, sizeof(self->Buf)); } if( k && self->Buf[k-1]==' ' && defs[i]==' ' ) { i++; continue; } self->Buf[k] = defs[i]; k++; i++; } S_Flush(self); } void S_OutNum(PsOutPtr self, float num) { int i; char buf[64]; sprintf(buf, "%.3f", num); for( i=strlen(buf)-1 ; buf[i]=='0' ; i-- ); buf[i+1] = '\0'; if( buf[strlen(buf)-1]=='.' ) buf[strlen(buf)-1] = '\0'; if( self->Buf[0] ) strcat(self->Buf, " "); strcat(self->Buf, buf); if( strlen(self->Buf)>70 ) S_Flush(self); } static void S_OutStr(PsOutPtr self, char *txt, int txtl) { int i, k; char buf[1024]; for( i=0,k=0 ; i=' ' && txt[i]<='~') && txt[i]!='(' && txt[i]!=')' && txt[i]!='\\' ) { buf[k] = txt[i]; k++; continue; } buf[k] = '\\'; k++; sprintf(&buf[k], "%03o", txt[i]&0xFF); /* Skip to the end of the buffer */ while( buf[k] != '\0' ) k++; } strcat(self->Buf, "("); i = strlen(self->Buf); memcpy(&self->Buf[i], buf, k); self->Buf[i+k] = '\0'; strcat(self->Buf, ")"); if( strlen(self->Buf)>70 ) S_Flush(self); } /* Same as S_OutStr() but takes |short *| instead of |char *| */ static void S_OutStr16(PsOutPtr self, unsigned short *txt, int txtl) { int i, k; char buf[2048]; for( i=0,k=0 ; i=' ' && txt[i]<='~') && txt[i]!='(' && txt[i]!=')' && txt[i]!='\\' ) { buf[k] = txt[i]; k++; continue; } buf[k] = '\\'; k++; sprintf(&buf[k], "%03o", txt[i]&0xFFFF); /* Skip to the end of the buffer */ while( buf[k] != '\0' ) k++; } strcat(self->Buf, "("); i = strlen(self->Buf); memcpy(&self->Buf[i], buf, k); self->Buf[i+k] = '\0'; strcat(self->Buf, ")"); if( strlen(self->Buf)>70 ) S_Flush(self); } void S_OutTok(PsOutPtr self, char *tok, int cr) { if( self->Buf[0] ) strcat(self->Buf, " "); strcat(self->Buf, tok); if( cr ) S_Flush(self); } static void S_Color(PsOutPtr self, int clr) { int ir, ig, ib; ir = clr>>16; ig = (clr>>8)&0xFF; ib = clr&0xFF; if( ir==ig && ig==ib ) { S_OutNum(self, (float)ir/255.); S_OutTok(self, "g", 1); } else { S_OutNum(self, (float)ir/255.); S_OutNum(self, (float)ig/255.); S_OutNum(self, (float)ib/255.); S_OutTok(self, "sc", 1); } } static void S_SetPageDevice(PsOutPtr self, int orient, int count, int plex, int res, int wd, int ht, int isPage) { float fwd = ((float)wd/(float)res)*72.; float fht = ((float)ht/(float)res)*72.; #define USE_WORKAROUND_COPY_COUNT_BUG 1 #ifdef USE_WORKAROUND_COPY_COUNT_BUG /* Workaround (see http://xprint.mozdev.org/bugs/show_bug.cgi?id=1861 - * 'Need workaround for bug 1378 ...') to avoid that we print n^2 copies * instead of n copies. * The problem is that we use both /NumCopies here but pass the * %copy-count% to the spooler, too. * But we only have to use _one_ way... * * The final fix for bug 1378 (http://xprint.mozdev.org/bugs/show_bug.cgi?id=1378 - * "PS DDX creates n^2 copies of a job instead of n copies") will back this * workaround out and replace it with a better solution. * (see mozilla.org bug 140030 * (http://bugzilla.mozilla.org/show_bug.cgi?id=140030 - "Setting number * of copies causes too many copies to print") for the initial report for * this issue...) */ count = 1; #endif /* USE_WORKAROUND_COPY_COUNT_BUG */ S_OutTok(self, "/pWd", 0); S_OutNum(self, fwd); S_OutTok(self, "d /pHt", 0); S_OutNum(self, fht); S_OutTok(self, "d", 1); /* * if these are page attributes, have PostScript check to see if they * have changed. If not, don't do setpagedevice, since it will cause * a page flush and screw up duplex printing. Having PostScript check * means we don't have to keep track ourselves. */ if(isPage) { S_OutNum(self, (float) orient); S_OutTok(self, "/Orientation ck1", 0); S_OutTok(self, "pWd pHt /PageSize ck2 and not {", 1); } S_OutTok(self, "{db", 0); S_OutTok(self, "/Orientation", 0); S_OutNum(self, (float) orient); S_OutTok(self, " d ", 0); S_OutTok(self, "/PageSize [pWd pHt] d", 0); S_OutTok(self, " de spd", 0); /* * save a flag to show if we failed to set orientation... determined * by both/either Orientation and/or PageSize, use this * later to set/not set orientation using Cs command. */ S_OutTok(self,"}stp /orientationFailed x d", 1); /* * if these are page attributes, have PostScript check to see if they * have changed. If not, don't do setpagedevice, since it will cause * a page flush and screw up duplex printing. Having PostScript check * means we don't have to keep track ourselves. */ if(isPage) { S_OutTok(self,"}if",1); S_OutTok(self, (plex==0)?"f":"t", 0); S_OutTok(self, "/Duplex ck1 ", 0); S_OutTok(self, (plex==2)?"t":"f", 0); S_OutTok(self, "/Tumble ck1 and ", 0); S_OutNum(self, (float)res); S_OutNum(self, (float)res); S_OutTok(self, " /HWResolution ck2 and", 0); if( count>1 ) { S_OutNum(self, (float)count); S_OutTok(self, " /NumCopies", 0); S_OutTok(self, " ck1 and ", 0); } S_OutTok(self," not {",1); } S_OutTok(self, "{db", 0); S_OutTok(self, "/Duplex ", 0); S_OutTok(self, (plex==0)?"f":"t", 0); S_OutTok(self, " d ", 0); S_OutTok(self, "/Tumble ", 0); S_OutTok(self, (plex==2)?"t":"f", 0); S_OutTok(self, " d ", 0); S_OutTok(self, " /HWResolution [", 0); S_OutNum(self, (float)res); S_OutNum(self, (float)res); S_OutTok(self, "] d ", 0); if( count>1 ) { S_OutTok(self, " /NumCopies", 0); S_OutNum(self, (float)count); S_OutTok(self, " d ", 0); } S_OutTok(self, " de spd}stp p", 1); if(isPage) { S_OutTok(self, "}if", 1); } } /******************************************************************* * PUBLIC FUNCTIONS * *******************************************************************/ FILE * PsOut_ChangeFile(PsOutPtr self, FILE *fp) { FILE *nfp; nfp = self->Fp; self->Fp = fp; return nfp; } PsOutPtr PsOut_BeginFile(FILE *fp, char *title, int orient, int count, int plex, int res, int wd, int ht, Bool raw) { int i; char buffer[256+32]; /* enougth space for a title with 256 chars... */ /* * Get ready to output PostScript header */ PsOutPtr psout; psout = (PsOutPtr)xalloc(sizeof(PsOutRec)); memset(psout, 0, sizeof(PsOutRec)); psout->Fp = fp; psout->isRaw = raw; psout->pagenum = 0; if (!raw) { /* * Output PostScript header */ /* GhostScript will rant about the missing BoundingBox if we use * "%!PS-Adobe-3.0 EPSF-3.0" here... */ S_Comment(psout, "%!PS-Adobe-3.0"); sprintf(buffer, "%%%%Creator: The X Print Server's PostScript DDX (%s, release %d)", VENDOR_STRING, VENDOR_RELEASE); S_Comment(psout, buffer); if (title) { sprintf(buffer, "%%%%Title: %.256s", title); S_Comment(psout, buffer); } S_Comment(psout, "%%EndComments"); S_Comment(psout, "%%BeginProlog"); S_Comment(psout, "%%BeginProcSet: XServer_PS_Functions"); S_OutDefs(psout, S_StandardDefs); S_OutDefs(psout, S_CompositeDefs); S_Comment(psout, "%%EndProcSet"); S_Comment(psout, "%%EndProlog"); S_Comment(psout, "%%BeginSetup"); /* set document level page attributes */ S_SetPageDevice(psout, orient, count, plex, res, wd, ht, 0); S_Comment(psout, "%%Pages: atend"); S_OutDefs(psout, S_SetupDefs); S_Comment(psout, "%%EndSetup"); } /* * Initialize the structure */ psout->CurColor = 0xFFFFFFFF; psout->LineWidth = 1; psout->LineCap = PsCButt; psout->LineJoin = PsJMiter; psout->NDashes = 0; psout->Dashes = (int *)0; psout->FontName = (char *)0; psout->FontSize = 0; psout->start_image = 0; for( i=0 ; i<4 ; i++ ) psout->FontMtx[i] = 0.; psout->ImageFormat = 0; return(psout); } void PsOut_EndFile(PsOutPtr self, int closeFile) { char coms[50]; int i; if (!self) return; if (!self->isRaw) { S_Comment(self,"%%Trailer"); sprintf(coms,"%%%%Pages: %d", self->pagenum); S_Comment(self, coms); S_Comment(self, "%%EOF"); } if( self->NDashes && self->Dashes ) xfree(self->Dashes); if( self->FontName ) xfree(self->FontName); if( self->Patterns ) xfree(self->Patterns); if( self->Clip.rects ) xfree(self->Clip.rects); if( closeFile ) fclose(self->Fp); xfree(self); } void PsOut_BeginPage(PsOutPtr self, int orient, int count, int plex, int res, int wd, int ht) { char coms[50]; /*** comment for pagenumbers *****/ S_Comment(self,"%%PageHeader"); self->pagenum++; sprintf(coms,"%%%%Page: %d %d", self->pagenum, self->pagenum); S_Comment(self, coms); sprintf(coms,"%%%%PageOrientation: %s",pg_orient[orient]); S_Comment(self, coms); /*** end comment *****************/ /* set page level page attributes */ S_SetPageDevice(self, orient, count, plex, res, wd, ht, 1); S_OutTok(self, "gs ", 0); /* * check to see if we set orientation already; if it wasn't set, * use Cs to set orientation here. */ S_OutNum(self, (float)orient); S_OutTok(self, "orientationFailed { ", 0); S_OutNum(self, (float)orient); S_OutTok(self, " } { 0 }ie Cs 100 sml gs", 1); } void PsOut_EndPage(PsOutPtr self) { S_OutTok(self, "gr gr sp", 1); /* did grestore: mark attributes 'dirty' so they will be re-sent */ PsOut_DirtyAttributes(self); /*** comment for pagenumbers *****/ S_Comment(self,"%%PageTrailer"); /*** end comment *****************/ } void PsOut_DirtyAttributes(PsOutPtr self) { int i; self->CurColor = 0xFFFFFFFF; self->LineWidth = -1; self->LineCap = (PsCapEnum)-1; self->LineJoin = (PsJoinEnum)-1; self->NDashes = -1; self->FontSize = -1; for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = -1.; if( self->Dashes ) { xfree(self->Dashes); self->Dashes = (int *)0; } if( self->FontName ) { xfree(self->FontName); self->FontName = (char *)0; } } void PsOut_Comment(PsOutPtr self, char *comment) { S_Comment(self, comment); } void PsOut_Offset(PsOutPtr self, int x, int y) { self->XOff = x; self->YOff = y; } void PsOut_Clip(PsOutPtr self, int clpTyp, PsClipPtr clpinf) { int i, k; int changed = 0; int xo = self->XOff; int yo = self->YOff; if( self->InTile ) return; if( self->InFrame ) xo = yo = 0; if( clpTyp!=self->ClipType ) changed = 1; else { if( clpinf->nRects!=self->Clip.nRects ) changed = 1; else { if( clpinf->nOutterClips!=self->Clip.nOutterClips ) changed = 1; else { for( i=0 ; inOutterClips ; i++ ) { if( memcmp(&clpinf->outterClips[i], &self->Clip.outterClips[i], sizeof(PsRectRec))!=0 ) break; } if( inOutterClips ) changed = 1; else { for( i=0 ; inRects ; i++ ) { if( memcmp(&clpinf->rects[i], &self->Clip.rects[i], sizeof(PsRectRec))!=0 ) { changed = 1; break; } } } } } if( clpinf->nElms!=self->Clip.nElms ) changed = 1; else { for( i=0 ; inElms ; i++ ) { if( clpinf->elms[i].type!=PSOUT_POINTS ) { if( memcmp(&clpinf->elms[i], &self->Clip.elms[i], sizeof(PsElmRec))!=0 ) { changed = 1; break; } } else { if( clpinf->elms[i].type!=self->Clip.elms[i].type || clpinf->elms[i].nPoints!=self->Clip.elms[i].nPoints ) { changed = 1; break; } else { for( k=0 ; kelms[i].nPoints ; k++ ) { if( memcmp(&clpinf->elms[i].c.points[k], &self->Clip.elms[i].c.points[k], sizeof(PsPointRec)) ) { changed = 1; break; } } if( changed ) break; } } } } } if( self->Clip.rects ) xfree(self->Clip.rects); if( self->Clip.outterClips ) xfree(self->Clip.outterClips); if( self->Clip.elms ) PsDestroyFillElementList(self->Clip.nElms, self->Clip.elms); self->ClipType = clpTyp; self->Clip.nRects = clpinf->nRects; self->Clip.nElms = clpinf->nElms; self->Clip.nOutterClips = clpinf->nOutterClips; if( clpinf->nRects ) { self->Clip.rects = (PsRectPtr)xalloc(clpinf->nRects*sizeof(PsRectRec)); memcpy(self->Clip.rects, clpinf->rects, clpinf->nRects*sizeof(PsRectRec)); } else self->Clip.rects = 0; if( clpinf->nOutterClips ) { self->Clip.outterClips = (PsRectPtr)xalloc(clpinf->nOutterClips* sizeof(PsRectRec)); memcpy(self->Clip.outterClips, clpinf->outterClips, clpinf->nOutterClips*sizeof(PsRectRec)); } else self->Clip.outterClips = 0; if( clpinf->nElms ) self->Clip.elms = PsCloneFillElementList(clpinf->nElms, clpinf->elms); else self->Clip.elms = 0; PsOut_DirtyAttributes(self); S_OutTok(self, "gr gs", 1); if( self->Clip.nOutterClips ) { for( i=0 ; iClip.nOutterClips ; i++ ) { S_OutNum(self, (float)(self->Clip.outterClips[i].x)); S_OutNum(self, (float)(self->Clip.outterClips[i].y)); S_OutNum(self, (float)self->Clip.outterClips[i].w); S_OutNum(self, (float)self->Clip.outterClips[i].h); S_OutTok(self, "R", 1); } S_OutTok(self, "cl n", 1); } if( self->Clip.nRects ) { for( i=0 ; iClip.nRects ; i++ ) { S_OutNum(self, (float)(self->Clip.rects[i].x+xo)); S_OutNum(self, (float)(self->Clip.rects[i].y+yo)); S_OutNum(self, (float)self->Clip.rects[i].w); S_OutNum(self, (float)self->Clip.rects[i].h); S_OutTok(self, "R", 1); } S_OutTok(self, "cl n", 1); } if( self->Clip.nElms ) { PsElmPtr elm = self->Clip.elms; for( i=0 ; iClip.nElms ; i++,elm++ ) { switch(elm->type) { case PSOUT_POINTS: for( k=0 ; knPoints ; k++ ) { S_OutNum(self, (float)elm->c.points[k].x+xo); S_OutNum(self, (float)elm->c.points[k].y+yo); if( k==0 ) S_OutTok(self, "m", 0); else S_OutTok(self, "l", 0); } S_OutTok(self, "cp", 1); break; case PSOUT_RECT: S_OutNum(self, (float)elm->c.rect.x+xo); S_OutNum(self, (float)elm->c.rect.y+yo); S_OutNum(self, (float)elm->c.rect.w); S_OutNum(self, (float)elm->c.rect.h); S_OutTok(self, "R", 1); break; case PSOUT_ARC: if( elm->c.arc.style==PsPieSlice ) { S_OutNum(self, (float)elm->c.arc.x+xo+(float)elm->c.arc.w/2.); S_OutNum(self, (float)elm->c.arc.y+yo+(float)elm->c.arc.h/2.); S_OutTok(self, "m", 0); } S_OutNum(self, (float)elm->c.arc.x+xo+(float)elm->c.arc.w/2.); S_OutNum(self, (float)elm->c.arc.y+yo+(float)elm->c.arc.h/2.); S_OutNum(self, (float)elm->c.arc.w); S_OutNum(self, (float)elm->c.arc.h); S_OutNum(self, (float)elm->c.arc.a1/64.); S_OutNum(self, (float)elm->c.arc.a1/64.+(float)elm->c.arc.a2/64.); if( elm->c.arc.a2<0 ) S_OutTok(self, "An cp", 1); else S_OutTok(self, "Ac cp", 1); break; } } S_OutTok(self, "cl n", 1); } } void PsOut_Color(PsOutPtr self, int clr) { if( clr==self->CurColor || self->InTile>=PsStip ) return; self->CurColor = clr; S_Color(self, clr); } void PsOut_FillRule(PsOutPtr self, PsRuleEnum rule) { self->FillRule = rule; } void PsOut_LineAttrs(PsOutPtr self, int wd, PsCapEnum cap, PsJoinEnum join, int nDsh, int *dsh, int dshOff, int bclr) { int i; int same = 1; if( wd!=self->LineWidth && wd>=0 ) { if( wd==0 ) wd = 1; self->LineWidth = wd; S_OutNum(self, (float)wd); S_OutTok(self, "w", 1); } if( cap!=self->LineCap ) { self->LineCap = cap; S_OutNum(self, (float)cap); S_OutTok(self, "lc", 1); } if( join!=self->LineJoin ) { self->LineJoin = join; S_OutNum(self, (float)join); S_OutTok(self, "lj", 1); } if( nDsh!=self->NDashes ) same = 0; else if( dshOff!=self->DashOffset ) same = 0; else if( nDsh ) { for( i=0 ; iDashes[i] ) break; } if( iNDashes && self->Dashes ) { xfree(self->Dashes); self->Dashes = (int *)0; } self->NDashes = nDsh; self->DashOffset = dshOff; if( nDsh ) self->Dashes = (int *)xalloc(sizeof(int)*nDsh); S_OutTok(self, "[", 0); for( i=0 ; iDashes[i] = dsh[i]; S_OutNum(self, (float)dsh[i]); } S_OutTok(self, "]", 0); S_OutNum(self, (float)dshOff); S_OutTok(self, "ds", 1); } if( nDsh ) self->LineBClr = bclr; else bclr = -1; } void PsOut_TextAttrs(PsOutPtr self, char *fnam, int siz, int iso) { int i; char buf[256]; if( self->FontName && strcmp(fnam, self->FontName)==0 && siz==self->FontSize ) return; if( self->FontName ) xfree(self->FontName); self->FontName = (char *)xalloc(strlen(fnam)+1); strcpy(self->FontName, fnam); self->FontSize = siz; for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = -1.; strcpy(buf, "/"); strcat(buf, fnam); S_OutTok(self, buf, 0); S_OutNum(self, (float)siz); if( iso ) S_OutTok(self, "t", 0); else S_OutTok(self, "f", 0); S_OutTok(self, "Tf", 1); } void PsOut_TextAttrsMtx(PsOutPtr self, char *fnam, float *mtx, int iso) { int i; char buf[256]; if( self->FontName && strcmp(fnam, self->FontName)==0 && mtx[0]==self->FontMtx[0] && mtx[1]==self->FontMtx[1] && mtx[2]==self->FontMtx[2] && mtx[3]==self->FontMtx[3] ) return; if( self->FontName ) xfree(self->FontName); self->FontName = (char *)xalloc(strlen(fnam)+1); strcpy(self->FontName, fnam); for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = mtx[i]; self->FontSize = -1; strcpy(buf, "/"); strcat(buf, fnam); strcat(buf, " ["); S_OutTok(self, buf, 0); for( i=0 ; i<4 ; i++ ) S_OutNum(self, mtx[i]); S_OutTok(self, "0 0]", 0); if( iso ) S_OutTok(self, "t", 0); else S_OutTok(self, "f", 0); S_OutTok(self, "Tfm", 1); } void PsOut_Polygon(PsOutPtr self, int nPts, PsPointPtr pts) { int i; int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; if( nPts<=2 ) return; for( i=0 ; iFillRule==PsEvenOdd ) S_OutTok(self, "cp ef", 1); else S_OutTok(self, "cp fl", 1); } void PsOut_FillRect(PsOutPtr self, int x, int y, int w, int h) { int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; S_OutNum(self, (float)x); S_OutNum(self, (float)y); S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutTok(self, "R fl", 1); } void PsOut_FillArc(PsOutPtr self, int x, int y, int w, int h, float ang1, float ang2, PsArcEnum style) { int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; if( style==PsPieSlice ) { S_OutNum(self, (float)x+(float)w/2.); S_OutNum(self, (float)y+(float)h/2.); S_OutTok(self, "m", 0); } S_OutNum(self, (float)x+(float)w/2.); S_OutNum(self, (float)y+(float)h/2.); S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutNum(self, ang1); S_OutNum(self, ang1+ang2); if( ang2<0 ) S_OutTok(self, "An cp fl", 1); else S_OutTok(self, "Ac cp fl", 1); } void PsOut_Lines(PsOutPtr self, int nPts, PsPointPtr pts) { int i; int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; if( nPts<1 ) return; for( i=0 ; iLineBClr>=0 ) { S_OutTok(self, "gs", 0); S_Color(self, self->LineBClr); S_OutTok(self, "[] 0 ds st gr", 0); } S_OutTok(self, "st", 1); } void PsOut_Points(PsOutPtr self, int nPts, PsPointPtr pts) { int i; int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; if( nPts<1 ) return; for( i=0 ; iXOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; S_OutNum(self, (float)x); S_OutNum(self, (float)y); S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutTok(self, "R", 0); if( self->LineBClr>=0 ) { S_OutTok(self, "gs", 0); S_Color(self, self->LineBClr); S_OutTok(self, "[] 0 ds st gr", 0); } S_OutTok(self, "st", 1); } void PsOut_DrawArc(PsOutPtr self, int x, int y, int w, int h, float ang1, float ang2) { int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; S_OutNum(self, (float)x+(float)w/2.); S_OutNum(self, (float)y+(float)h/2.); S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutNum(self, ang1); S_OutNum(self, ang1+ang2); if( ang2<0 ) S_OutTok(self, "An", 0); else S_OutTok(self, "Ac", 0); if( self->LineBClr>=0 ) { S_OutTok(self, "gs", 0); S_Color(self, self->LineBClr); S_OutTok(self, "[] 0 ds st gr", 0); } S_OutTok(self, "st", 1); } void PsOut_Text(PsOutPtr self, int x, int y, char *text, int textl, int bclr) { int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; S_OutStr(self, text, textl); S_OutNum(self, (float)x); S_OutNum(self, (float)y); if( bclr<0 ) S_OutTok(self, "T", 1); else { int ir = bclr>>16; int ig = (bclr>>8)&0xFF; int ib = bclr&0xFF; S_OutNum(self, (float)ir/255.); S_OutNum(self, (float)ig/255.); S_OutNum(self, (float)ib/255.); S_OutTok(self, "Tb", 1); } } void PsOut_Text16(PsOutPtr self, int x, int y, unsigned short *text, int textl, int bclr) { int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; S_OutStr16(self, text, textl); S_OutNum(self, (float)x); S_OutNum(self, (float)y); if( bclr<0 ) S_OutTok(self, "T", 1); else { int ir = bclr>>16; int ig = (bclr>>8)&0xFF; int ib = bclr&0xFF; S_OutNum(self, (float)ir/255.); S_OutNum(self, (float)ig/255.); S_OutNum(self, (float)ib/255.); S_OutTok(self, "Tb", 1); } } #ifdef BM_CACHE void /* new */ PsOut_ImageCache(PsOutPtr self, int x, int y, long cache_id, int bclr, int fclr) { char cacheID[10]; int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; sprintf(cacheID, "c%di", cache_id); S_OutNum(self, (float)x); S_OutNum(self, (float)y); if( fclr==0xFFFFFF ) { int ir, ig, ib; ir = bclr>>16; ig = (bclr>>8)&0xFF; ib = bclr&0xFF; if( ir==ig && ig==ib ) S_OutNum(self, (float)ir/255.); else S_OutNum(self, (float)0); self->RevImage = 1; } else { int ir, ig, ib; ir = fclr>>16; ig = (fclr>>8)&0xFF; ib = fclr&0xFF; if( ir==ig && ig==ib ) S_OutNum(self, (float)ir/255.); else S_OutNum(self, (float)0); } S_OutTok(self, cacheID, 1); } /* new */ void /* new */ PsOut_BeginImageCache(PsOutPtr self, long cache_id) { char cacheID[10]; sprintf(cacheID, "/c%di {", cache_id); S_OutTok(self, cacheID, 0); } /* new */ void /* new */ PsOut_EndImageCache(PsOutPtr self) { S_OutTok(self, "}bd", 1); } /* new */ #endif void PsOut_BeginImage(PsOutPtr self, int bclr, int fclr, int x, int y, int w, int h, int sw, int sh, int format) { int savClr = self->CurColor; int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; if( self->InTile ) { if( self->InTile>=PsStip && format!=1 ) { self->ImgSkip = 1; return; } self->ImgBClr = bclr; self->ImgFClr = fclr; self->ImgX = x; self->ImgY = y; self->ImgW = w; self->ImgH = h; self->SclW = sw; self->SclH = sh; S_OutTok(self, "<", 0); self->ImageFormat = format; self->RevImage = 0; if( self->InTile==PsTile && format==1 && fclr==0xFFFFFF ) self->RevImage = 1; return; } self->RevImage = 0; if( format==1 ) { S_OutTok(self, "gs", 0); if( fclr==0xFFFFFF ) { PsOut_Color(self, fclr); PsOut_FillRect(self, x, y, sw, sh); PsOut_Color(self, bclr); self->RevImage = 1; } else { PsOut_Color(self, bclr); PsOut_FillRect(self, x, y, sw, sh); PsOut_Color(self, fclr); } } S_OutNum(self, (float)x); S_OutNum(self, (float)y); S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutNum(self, (float)sw); S_OutNum(self, (float)sh); if( format==1 ) { if(self->RevImage) S_OutTok(self, "Im1rev", 1); else S_OutTok(self, "Im1", 1); } else S_OutTok(self, "Im24", 1); self->ImageFormat = format; self->CurColor = savClr; } void PsOut_BeginImageIM(PsOutPtr self, int bclr, int fclr, int x, int y, int w, int h, int sw, int sh, int format) { int savClr = self->CurColor; int xo = self->XOff; int yo = self->YOff; if( self->InFrame || self->InTile ) xo = yo = 0; x += xo; y += yo; if( self->InTile ) { if( self->InTile>=PsStip && format!=1 ) { self->ImgSkip = 1; return; } self->ImgBClr = bclr; self->ImgFClr = fclr; self->ImgX = x; self->ImgY = y; self->ImgW = w; self->ImgH = h; self->SclW = sw; self->SclH = sh; S_OutTok(self, "<", 0); self->ImageFormat = format; self->RevImage = 0; if( self->InTile==PsTile && format==1 && fclr==0xFFFFFF ) self->RevImage = 1; return; } self->RevImage = 0; if( format==1 ) { S_OutTok(self, "gs", 0); #ifdef BM_CACHE S_OutTok(self, "g", 1); #else if( fclr==0xFFFFFF ) { PsOut_Color(self, bclr); self->RevImage = 1; } else { PsOut_Color(self, fclr); } #endif } #ifdef BM_CACHE S_OutTok(self, "tr", 0); /* new */ #else S_OutNum(self, (float)x); S_OutNum(self, (float)y); #endif S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutNum(self, (float)sw); S_OutNum(self, (float)sh); #ifdef BM_CACHE S_OutTok(self, "mtx", 1); /* new */ S_OutTok(self, "<", 0); /* new */ self->start_image = 1; #else if( format==1 ){ if(self->RevImage) S_OutTok(self, "Im1rev", 1); else S_OutTok(self, "Im1", 1); } else S_OutTok(self, "Im24", 1); #endif self->ImageFormat = format; self->CurColor = savClr; } void PsOut_EndImage(PsOutPtr self) { if( self->ImgSkip ) { self->ImgSkip = 0; return; } if( self->InTile ) { S_OutTok(self, ">", 1); if( self->ImageFormat==1 && self->InTile==PsTile ) { if( self->ImgFClr==0xFFFFFF ) { PsOut_Color(self, self->ImgFClr); PsOut_FillRect(self, self->ImgX, self->ImgY, self->SclW, self->SclH); PsOut_Color(self, self->ImgBClr); } else { PsOut_Color(self, self->ImgBClr); PsOut_FillRect(self, self->ImgX, self->ImgY, self->SclW, self->SclH); PsOut_Color(self, self->ImgFClr); } } S_OutNum(self, (float)self->ImgX); S_OutNum(self, (float)self->ImgY); S_OutNum(self, (float)self->ImgW); S_OutNum(self, (float)self->ImgH); S_OutNum(self, (float)self->SclW); S_OutNum(self, (float)self->SclH); if( self->ImageFormat==1 ) S_OutTok(self, "Im1t", 1); else S_OutTok(self, "Im24t", 1); self->ImageFormat = 0; self->RevImage = 0; return; } #ifdef BM_CACHE if(self->start_image) S_OutTok(self, "> im", 1); /* new */ #endif self->ImageFormat = 0; self->RevImage = 0; S_Flush(self); #ifdef BM_CACHE if(self->start_image) { self->start_image = 0; S_OutTok(self, "gr", 0); } else S_OutTok(self, "gr", 1); #else S_OutTok(self, "gr", 1); #endif } void PsOut_OutImageBytes(PsOutPtr self, int nBytes, char *bytes) { int i; char buf[5]; if( (!self->ImageFormat) || self->ImgSkip ) return; for( i=0 ; iRevImage ) sprintf(buf, "%02x", (int)(bytes[i]^0xFF)&0xFF); else sprintf(buf, "%02x", (int)bytes[i]&0xFF); strcat(self->Buf, buf); if( strlen(self->Buf)>70 ) S_Flush(self); } } void PsOut_BeginFrame(PsOutPtr self, int xoff, int yoff, int x, int y, int w, int h) { int xo = self->XOff; int yo = self->YOff; if( self->InFrame ) xo = yo = 0; S_OutTok(self, "gs", 0); S_OutNum(self, (float)(x+xo)); S_OutNum(self, (float)(y+yo)); S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutTok(self, "R cl n", 0); xoff += xo; yoff += yo; if( xoff || yoff ) { S_OutNum(self, (float)xoff); S_OutNum(self, (float)yoff); S_OutTok(self, "tr", 0); } S_OutTok(self, "gs", 1); self->InFrame += 1; } void PsOut_EndFrame(PsOutPtr self) { self->InFrame -= 1; if( self->InFrame<0 ) self->InFrame = 0; S_OutTok(self, "gr gr", 1); PsOut_DirtyAttributes(self); } int PsOut_BeginPattern(PsOutPtr self, void *tag, int w, int h, PsFillEnum type, int bclr, int fclr) { int i; char key[64]; for( i=0 ; iNPatterns ; i++ ) { if( self->Patterns[i].tag==tag && self->Patterns[i].type==type ) break; } if( iNPatterns ) return(1); if( (self->NPatterns+1)>self->MxPatterns ) { if( self->Patterns ) { self->MxPatterns *= 2; self->Patterns = (PsPatPtr)xrealloc(self->Patterns, sizeof(PsPatRec)*self->MxPatterns); } else { self->MxPatterns = 64; self->Patterns = (PsPatPtr)xalloc(sizeof(PsPatRec)*self->MxPatterns); } } self->Patterns[self->NPatterns].tag = tag; self->Patterns[self->NPatterns].type = type; sprintf(key, "/ %d", (int)tag); switch(type) { case PsTile: key[1] = 't'; break; case PsStip: key[1] = 's'; break; case PsOpStip: key[1] = 'o'; break; } S_OutTok(self, key, 0); S_OutTok(self, "db/PatternType 1 d/PaintType 1 d", 0); S_OutTok(self, "/TilingType 1 d/BBox[0 0", 0); S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutTok(self, "]d/XStep", 0); S_OutNum(self, (float)w); S_OutTok(self, "d/YStep", 0); S_OutNum(self, (float)h); S_OutTok(self, "d/PaintProc{bg sv", 1); if( type==PsOpStip ) { S_Color(self, bclr); S_OutTok(self, "0 0", 0); S_OutNum(self, (float)w); S_OutNum(self, (float)h); S_OutTok(self, "R fl", 1); } if( type!=PsTile ) S_Color(self, fclr); self->NPatterns += 1; self->InTile = type; return(0); } void PsOut_EndPattern(PsOutPtr self) { self->InTile = PsSolid; S_OutTok(self, "rs ed}d de im_ mp d", 1); } void PsOut_SetPattern(PsOutPtr self, void *tag, PsFillEnum type) { int i; char key[64]; for( i=0 ; iNPatterns ; i++ ) { if( tag==self->Patterns[i].tag && type==self->Patterns[i].type ) break; } if( i>=self->NPatterns ) return; sprintf(key, " %d", (int)tag); switch(type) { case PsTile: key[0] = 't'; break; case PsStip: key[0] = 's'; break; case PsOpStip: key[0] = 'o'; break; } S_OutTok(self, key, 0); S_OutTok(self, "spt", 1); self->CurColor = 0xFFFFFFFF; } void PsOut_RawData(PsOutPtr self, char *data, int len) { S_Flush(self); if (!ferror(self->Fp)) { (void) fwrite(data, 1, len, self->Fp); } } typedef enum PsDownfontFontType_ { PsDFT_Type1PFA=0, PsDFT_Type1PFB, PsDFT_TrueType /* not implemented yet */ } PsDownfontFontType; /* Download a PS Type1 font */ int PsOut_DownloadType1(PsOutPtr self, const char *auditmsg, const char *name, const char *fname) { int i; int stt; char buf[256]; FILE *fp; PsDownfontFontType type; fp = fopen(fname, "r"); if( !fp ) return 0; #ifdef DEBUG_gisburn /* This should be log-able! */ fprintf(stderr, "PsOut_DownloadType1: %s: Downloading '%s' from '%s'\n", auditmsg, name, fname); #endif /* DEBUG_gisburn */ fread(buf, 32, 1, fp); fseek(fp, (long)0, 0); /* Is this a Adobe PostScript Type 1 binary font (PFB) ? */ if( (buf[0]&0xFF)==0x80 && (buf[1]&0xFF)==0x01 ) { type = PsDFT_Type1PFB; } /* Is this a Adobe PostScript ASCII font (PFA) ? */ else if (!strncmp(buf, "%!PS-AdobeFont", 14)) { type = PsDFT_Type1PFA; } else { /* This should be log-able! */ fprintf(stderr, "PsOut_DownloadType1: Unknown font type for '%s'\n", fname); return 0; } S_Flush(self); sprintf(buf, "%%%%BeginFont: %s", name); S_Comment(self, buf); if( type == PsDFT_Type1PFB ) { char *buf, *pt; int len, ch, stype; ch = fgetc(fp); /* Strip out the binary headers and de-binary it */ while( (ch&0xFF) == 0x80 ) { stype = fgetc(fp); if( stype==3 ) /* eof mark */ break; len = fgetc(fp); len |= fgetc(fp)<<8; len |= fgetc(fp)<<16; len |= fgetc(fp)<<24; buf = (char *)xalloc(len+1); if( stype==1 ) { /* Process ASCII section */ len = fread(buf, 1, len, fp); /* convert any lone CRs (ie Mac eol) to LFs */ for( pt = buf ; (pt = memchr(pt, '\r', len-(pt-buf))) != NULL ; pt++ ) { if ( pt[1]!='\n' ) *pt = '\n'; } fwrite(buf, 1, len, self->Fp); } else if( stype==2 ) { int i; /* Process binary section */ len = fread(buf, 1, len, fp); for( i=0 ; i>4)&0xf) <= 9 ) fputc('0'+((ch>>4)&0xf), self->Fp); else fputc('A'-10+((ch>>4)&0xf), self->Fp); if( (ch&0xf) <= 9 ) fputc('0'+(ch&0xf), self->Fp); else fputc('A'-10+(ch&0xf), self->Fp); if( (i&0x1f)==0x1f ) fputc('\n', self->Fp); } } xfree(buf); /* Next block... */ ch = fgetc(fp); } } /* Is this a Adobe PostScript ASCII font (PFA) ? */ else if (type == PsDFT_Type1PFA) { for(;;) { stt = fread(buf, 1, 256, fp); if( stt<=0 ) break; if (!ferror(self->Fp)) { (void) fwrite(buf, 1, stt, self->Fp); } if( stt<256 ) break; } } fclose(fp); S_Flush(self); S_Comment(self, "%%EndFont"); /* Success... */ return 1; }