3 Copyright 1996, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
27 * (c) Copyright 1996 Hewlett-Packard Company
28 * (c) Copyright 1996 International Business Machines Corp.
29 * (c) Copyright 1996, 2000 Sun Microsystems, Inc. All Rights Reserved.
30 * (c) Copyright 1996 Novell, Inc.
31 * (c) Copyright 1996 Digital Equipment Corp.
32 * (c) Copyright 1996 Fujitsu Limited
33 * (c) Copyright 1996 Hitachi, Ltd.
35 * Permission is hereby granted, free of charge, to any person obtaining
36 * a copy of this software and associated documentation files (the
37 * "Software"), to deal in the Software without restriction, including
38 * without limitation the rights to use, copy, modify, merge, publish,
39 * distribute, sublicense, and/or sell copies of the Software, and to
40 * permit persons to whom the Software is furnished to do so, subject
41 * to the following conditions:
43 * The above copyright notice and this permission notice shall be included
44 * in all copies or substantial portions of the Software.
46 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
49 * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
50 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
51 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
54 * Except as contained in this notice, the names of the copyright holders
55 * shall not be used in advertising or otherwise to promote the sale, use
56 * or other dealings in this Software without prior written authorization
57 * from said copyright holders.
60 /*******************************************************************
62 ** *********************************************************
66 ** * Contents: Code to output PostScript to file
68 ** * Created By: Roger Helmendach (Liberty Systems)
70 ** * Copyright: Copyright 1996 The Open Group, Inc.
72 ** *********************************************************
74 ********************************************************************/
76 #ifdef HAVE_DIX_CONFIG_H
77 #include <dix-config.h>
83 #define USE_PSOUT_PRIVATE 1
86 #ifdef XP_USE_FREETYPE
88 #include FT_FREETYPE_H
89 #endif /* XP_USE_FREETYPE */
90 /* For VENDOR_STRING and VENDOR_RELEASE */
94 * Standard definitions
97 static char *S_StandardDefs
= "\
115 /sml{setmiterlimit}bd\
147 /cm{currentmatrix}bd\
149 /ccm{concatmatrix}bd\
155 /fd{FontDirectory}bd\
162 /rh{readhexstring}bd\
176 /db{20 dict dp bg}bd\
178 /languagelevel wh{p languagelevel}{1}ie\
179 1 eq{/makepattern{p}bd/setpattern{p}bd/setpagedevice{p}bd}if\
182 /spd{setpagedevice}bd\
184 #ifdef XP_USE_FREETYPE
185 "/trmoveto{currentfont /FontMatrix get transform rm}d"
186 #endif /* XP_USE_FREETYPE */
190 * Composite definitions
193 * XYr - Return X/Y dpi for device
197 * Cs - Coordinate setup (for origin upper left)
199 * <orient(0,1,2,3)> Cs
205 * R - Add rectangle to path
209 * Ac - Add arc to path
211 * <x> <y> <w> <h> <ang1> <ang2> Ac
213 * An - Add arc to path (counterclockwise)
215 * <x> <y> <w> <h> <ang1> <ang2> An
219 * <font_name> <size> <iso> Tf
221 * Tfm - Set font with matrix
223 * <font_name> <matrix> <iso> Tfm
229 * Tb - Draw text with background color
231 * <text> <x> <y> <bg_red> <bg_green> <bg_blue> Tb
233 * Im1 - Image 1 bit monochrome imagemask
235 * <x> <y> <w> <h> <sw> <sh> Im1
237 * Im24 - Image 24 bit RGB color
239 * <x> <y> <w> <h> <sw> <sh> Im24
241 * Im1t - Image 1 bit monochrome imagemask (in tile)
243 * <data> <x> <y> <w> <h> <sw> <sh> Im1t
245 * Im24t - Image 24 bit RGB color (in tile)
247 * <data> <x> <y> <w> <h> <sw> <sh> Im24t
250 static char *S_CompositeDefs
= "\
251 /XYr{/currentpagedevice wh\
252 {p currentpagedevice dp /HWResolution kn\
253 {/HWResolution get al p}{p 300 300}ie}{300 300}ie}bd\
254 /Cs{dp 0 eq{0 pHt tr XYr -1 x dv 72 ml x 1 x dv 72 ml x scl}if\
255 dp 1 eq{90 rt XYr -1 x dv 72 ml x 1 x dv 72 ml x scl}if\
256 dp 2 eq{pWd 0 tr XYr 1 x dv 72 ml x -1 x dv 72 ml x scl}if\
257 3 eq{pHt pWd tr 90 rt XYr 1 x dv 72 ml x -1 x dv 72 ml x scl}if}bd\
258 /P{gs 1 w [] 0 ds 2 c m .1 ad x .1 ad x l st gr}bd\
259 /R{4 2 r m 1 i 0 rl 0 x rl ng 0 rl cp}bd\
260 /Ac{mx_ cm p 6 -2 r tr 4 2 r ng scl 0 0 .5 5 3 r a mx_ sm}bd\
261 /An{mx_ cm p 6 -2 r tr 4 2 r ng scl 0 0 .5 5 3 r an mx_ sm}bd\
262 /ISO{dp len dict bg{1 i/FID ne{d}{p p}ie}fa\
263 /Encoding ISOLatin1Encoding d cd ed df}bd\
264 /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\
265 /Tp{{x dp iN dp fd x kn{x p dp/f_ x d ff}{dp/f_ x d x ff ISO}ie x}\
266 {x dp/f_ x d ff x}ie}bd\
267 /Tf{Tp[x 0 0 2 i ng 0 0] dp/fm_ x d mf sf}bd\
268 /Tfm{Tp 1 -1 tm1_ scl tm2_ ccm dp/fm_ x d mf sf}bd\
270 /Tb{gs sc f_ ff sf cft/FontMatrix get 3 get\
271 cft/FontBBox get dp 1 get x 3 get 2 i ml 3 1 r ml\
272 0 0 m 4 i stw p 4 i 4 i m fm_ cc\
273 0 2 i rl dp 0 rl 0 2 i ng rl 0 3 i rl ng 0 rl cp fl p p\
275 /Im1{6 4 r tr scl t [3 i 0 0 5 i 0 0]{cf str1 rh p} im}bd\
276 /Im1rev{6 4 r tr scl f [3 i 0 0 5 i 0 0]{cf str1 rh p} im}bd\
277 /Im24{gs 6 4 r tr scl 8 [3 i 0 0 5 i 0 0]{cf str3 rh p} f 3 ci}bd\
278 /Im1t{6 4 r tr scl t [3 i 0 0 5 i 0 0]{} im}bd\
279 /Im24t{gs 6 4 r tr scl 8 [3 i 0 0 5 i 0 0]{} f 3 ci}bd\
280 /ck2{/currentpagedevice wh \
281 {p dp currentpagedevice dp 3 -1 r kn \
282 {x get al p 3 -1 r eq 3 1 r eq and } \
285 /ck1{/currentpagedevice wh \
286 {p dp currentpagedevice dp 3 -1 r kn \
287 {x get eq} {p p p t}ie} \
289 /mtx{scl t [3 i 0 0 5 i 0 0]}bd \
292 char *pg_orient
[] = {"Portrait","Landscape","Reverse Portrait","Reverse Landscape"};
297 static char *S_SetupDefs
= "\
306 /*******************************************************************
307 * PRIVATE FUNCTIONS *
308 *******************************************************************/
311 S_Flush(PsOutPtr self
)
315 if( self
->Buf
[0] == '\0' )
318 len
= strlen(self
->Buf
);
320 /* Append a newline char ('\n') if there isn't one there already */
321 if( self
->Buf
[len
-1] != '\n' )
323 self
->Buf
[len
++] = '\n';
324 self
->Buf
[len
] = '\0';
327 (void)fwrite(self
->Buf
, len
, 1, self
->Fp
);
333 S_Comment(PsOutPtr self
, char *comment
)
336 strcpy(self
->Buf
, comment
);
341 S_OutDefs(PsOutPtr self
, char *defs
)
345 memset(self
->Buf
, 0, sizeof(self
->Buf
));
346 for( i
=0 ; defs
[i
]!='\0' ;)
348 if( k
>70 && (i
==0 || (i
&& defs
[i
-1]!='/')) &&
349 (defs
[i
]==' ' || defs
[i
]=='/' || defs
[i
]=='{') )
353 memset(self
->Buf
, 0, sizeof(self
->Buf
));
355 if( k
&& self
->Buf
[k
-1]==' ' && defs
[i
]==' ' ) { i
++; continue; }
356 self
->Buf
[k
] = defs
[i
];
363 S_OutNum(PsOutPtr self
, float num
)
369 sprintf(buf
, "%.3f", num
);
371 /* Remove any zeros at the end */
372 for( i
=strlen(buf
)-1 ; buf
[i
]=='0' ; i
-- ); buf
[i
+1] = '\0';
373 /* Remove '.' if it is the last character */
374 i
= strlen(buf
)-1; if( buf
[i
]=='.' ) buf
[i
] = '\0';
376 len
= strlen(self
->Buf
);
379 self
->Buf
[len
++] = ' ';
380 self
->Buf
[len
] = '\0';
382 strcpy(&self
->Buf
[len
], buf
);
383 if( (len
+i
)>70 ) S_Flush(self
);
387 S_OutStr(PsOutPtr self
, char *txt
, int txtl
)
391 for( i
=0,k
=0 ; i
<txtl
; i
++ )
393 if( (txt
[i
]>=' ' && txt
[i
]<='~') &&
394 txt
[i
]!='(' && txt
[i
]!=')' && txt
[i
]!='\\' )
395 { buf
[k
] = txt
[i
]; k
++; continue; }
397 sprintf(&buf
[k
], "%03o", txt
[i
]&0xFF);
398 /* Skip to the end of the buffer */
399 while( buf
[k
] != '\0' )
402 strcat(self
->Buf
, "(");
403 i
= strlen(self
->Buf
);
404 memcpy(&self
->Buf
[i
], buf
, k
);
405 self
->Buf
[i
+k
] = '\0';
406 strcat(self
->Buf
, ")");
407 if( strlen(self
->Buf
)>70 ) S_Flush(self
);
410 /* Same as S_OutStr() but takes |short *| instead of |char *| */
412 S_OutStr16(PsOutPtr self
, unsigned short *txt
, int txtl
)
416 for( i
=0,k
=0 ; i
<txtl
; i
++ )
418 if( (txt
[i
]>=' ' && txt
[i
]<='~') &&
419 txt
[i
]!='(' && txt
[i
]!=')' && txt
[i
]!='\\' )
420 { buf
[k
] = txt
[i
]; k
++; continue; }
422 sprintf(&buf
[k
], "%03o", txt
[i
]&0xFFFF);
423 /* Skip to the end of the buffer */
424 while( buf
[k
] != '\0' )
427 strcat(self
->Buf
, "(");
428 i
= strlen(self
->Buf
);
429 memcpy(&self
->Buf
[i
], buf
, k
);
430 self
->Buf
[i
+k
] = '\0';
431 strcat(self
->Buf
, ")");
432 if( strlen(self
->Buf
)>70 ) S_Flush(self
);
436 S_OutTok(PsOutPtr self
, char *tok
, int cr
)
438 int len
= strlen(self
->Buf
);
441 self
->Buf
[len
++] = ' ';
442 self
->Buf
[len
] = '\0';
444 strcpy(&self
->Buf
[len
], tok
);
445 if( cr
) S_Flush(self
);
449 S_Color(PsOutPtr self
, PsOutColor clr
)
452 ir
= PSOUTCOLOR_TO_REDBITS(clr
);
453 ig
= PSOUTCOLOR_TO_GREENBITS(clr
);
454 ib
= PSOUTCOLOR_TO_BLUEBITS(clr
);
455 if( ir
==ig
&& ig
==ib
)
456 { S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ir
)); S_OutTok(self
, "g", 1); }
459 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ir
));
460 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ig
));
461 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ib
));
462 S_OutTok(self
, "sc", 1);
467 S_SetPageDevice(PsOutPtr self
, int orient
, int count
, int plex
, int res
,
468 int wd
, int ht
, int isPage
)
470 float fwd
= ((float)wd
/(float)res
)*72.;
471 float fht
= ((float)ht
/(float)res
)*72.;
473 #define USE_WORKAROUND_COPY_COUNT_BUG 1
475 #ifdef USE_WORKAROUND_COPY_COUNT_BUG
476 /* Workaround (see http://xprint.mozdev.org/bugs/show_bug.cgi?id=1861 -
477 * 'Need workaround for bug 1378 ...') to avoid that we print n^2 copies
478 * instead of n copies.
479 * The problem is that we use both /NumCopies here but pass the
480 * %copy-count% to the spooler, too.
481 * But we only have to use _one_ way...
483 * The final fix for bug 1378 (http://xprint.mozdev.org/bugs/show_bug.cgi?id=1378 -
484 * "PS DDX creates n^2 copies of a job instead of n copies") will back this
485 * workaround out and replace it with a better solution.
486 * (see mozilla.org bug 140030
487 * (http://bugzilla.mozilla.org/show_bug.cgi?id=140030 - "Setting number
488 * of copies causes too many copies to print") for the initial report for
492 #endif /* USE_WORKAROUND_COPY_COUNT_BUG */
494 S_OutTok(self
, "/pWd", 0);
496 S_OutTok(self
, "d /pHt", 0);
498 S_OutTok(self
, "d", 1);
501 * if these are page attributes, have PostScript check to see if they
502 * have changed. If not, don't do setpagedevice, since it will cause
503 * a page flush and screw up duplex printing. Having PostScript check
504 * means we don't have to keep track ourselves.
507 S_OutNum(self
, (float) orient
);
508 S_OutTok(self
, "/Orientation ck1", 0);
509 S_OutTok(self
, "pWd pHt /PageSize ck2 and not {", 1);
511 S_OutTok(self
, "{db", 0);
513 S_OutTok(self
, "/Orientation", 0);
514 S_OutNum(self
, (float) orient
);
515 S_OutTok(self
, " d ", 0);
516 S_OutTok(self
, "/PageSize [pWd pHt] d", 0);
518 S_OutTok(self
, " de spd", 0);
520 * save a flag to show if we failed to set orientation... determined
521 * by both/either Orientation and/or PageSize, use this
522 * later to set/not set orientation using Cs command.
524 S_OutTok(self
,"}stp /orientationFailed x d", 1);
526 * if these are page attributes, have PostScript check to see if they
527 * have changed. If not, don't do setpagedevice, since it will cause
528 * a page flush and screw up duplex printing. Having PostScript check
529 * means we don't have to keep track ourselves.
533 S_OutTok(self
,"}if",1);
535 S_OutTok(self
, (plex
==0)?"f":"t", 0);
536 S_OutTok(self
, "/Duplex ck1 ", 0);
538 S_OutTok(self
, (plex
==2)?"t":"f", 0);
539 S_OutTok(self
, "/Tumble ck1 and ", 0);
542 S_OutNum(self
, (float)res
);
543 S_OutNum(self
, (float)res
);
544 S_OutTok(self
, " /HWResolution ck2 and", 0);
548 S_OutNum(self
, (float)count
);
549 S_OutTok(self
, " /NumCopies", 0);
550 S_OutTok(self
, " ck1 and ", 0);
552 S_OutTok(self
," not {",1);
554 S_OutTok(self
, "{db", 0);
556 S_OutTok(self
, "/Duplex ", 0);
557 S_OutTok(self
, (plex
==0)?"f":"t", 0);
558 S_OutTok(self
, " d ", 0);
560 S_OutTok(self
, "/Tumble ", 0);
561 S_OutTok(self
, (plex
==2)?"t":"f", 0);
562 S_OutTok(self
, " d ", 0);
564 S_OutTok(self
, " /HWResolution [", 0);
565 S_OutNum(self
, (float)res
);
566 S_OutNum(self
, (float)res
);
567 S_OutTok(self
, "] d ", 0);
571 S_OutTok(self
, " /NumCopies", 0);
572 S_OutNum(self
, (float)count
);
573 S_OutTok(self
, " d ", 0);
575 S_OutTok(self
, " de spd}stp p", 1);
579 S_OutTok(self
, "}if", 1);
583 /*******************************************************************
585 *******************************************************************/
588 PsOut_ChangeFile(PsOutPtr self
, FILE *fp
)
600 PsOut_BeginFile(FILE *fp
, char *title
, int orient
, int count
, int plex
, int res
,
601 int wd
, int ht
, Bool raw
)
604 char buffer
[256+32]; /* enougth space for a title with 256 chars... */
606 * Get ready to output PostScript header
609 psout
= (PsOutPtr
)xalloc(sizeof(PsOutRec
));
610 memset(psout
, 0, sizeof(PsOutRec
));
617 * Output PostScript header
619 /* GhostScript will rant about the missing BoundingBox if we use
620 * "%!PS-Adobe-3.0 EPSF-3.0" here... */
621 S_Comment(psout
, "%!PS-Adobe-3.0");
622 #ifdef XP_USE_FREETYPE
627 extern FT_Library ftypeLibrary
; /* defined in xc/lib/font/FreeType/ftfuncs.c */
629 FT_Library_Version(ftypeLibrary
, &ftmajor
, &ftminor
, &ftpatch
);
631 "%%%%Creator: The X Print Server's PostScript DDX "
632 "(%s, release %d, FreeType version %d.%d.%d)",
633 VENDOR_STRING
, VENDOR_RELEASE
,
634 (int)ftmajor
, (int)ftminor
, (int)ftpatch
);
638 "%%%%Creator: The X Print Server's PostScript DDX (%s, release %d)",
639 VENDOR_STRING
, VENDOR_RELEASE
);
640 #endif /* XP_USE_FREETYPE */
641 S_Comment(psout
, buffer
);
645 sprintf(buffer
, "%%%%Title: %.256s", title
);
646 S_Comment(psout
, buffer
);
648 S_Comment(psout
, "%%EndComments");
649 S_Comment(psout
, "%%BeginProlog");
650 S_Comment(psout
, "%%BeginProcSet: XServer_PS_Functions");
651 S_OutDefs(psout
, S_StandardDefs
);
652 S_OutDefs(psout
, S_CompositeDefs
);
653 S_Comment(psout
, "%%EndProcSet");
654 S_Comment(psout
, "%%EndProlog");
655 S_Comment(psout
, "%%BeginSetup");
656 /* set document level page attributes */
657 S_SetPageDevice(psout
, orient
, count
, plex
, res
, wd
, ht
, 0);
658 S_Comment(psout
, "%%Pages: atend");
659 S_OutDefs(psout
, S_SetupDefs
);
660 S_Comment(psout
, "%%EndSetup");
663 * Initialize the structure
665 psout
->CurColor
= PSOUTCOLOR_NOCOLOR
;
666 psout
->LineWidth
= 1;
667 psout
->LineCap
= PsCButt
;
668 psout
->LineJoin
= PsJMiter
;
670 psout
->Dashes
= (int *)0;
671 psout
->FontName
= (char *)0;
673 psout
->start_image
= 0;
674 for( i
=0 ; i
<4 ; i
++ ) psout
->FontMtx
[i
] = 0.;
675 psout
->ImageFormat
= 0;
680 PsOut_EndFile(PsOutPtr self
, int closeFile
)
688 S_Comment(self
,"%%Trailer");
689 sprintf(coms
,"%%%%Pages: %d", self
->pagenum
);
690 S_Comment(self
, coms
);
691 S_Comment(self
, "%%EOF");
693 if( self
->NDashes
&& self
->Dashes
) xfree(self
->Dashes
);
694 if( self
->FontName
) xfree(self
->FontName
);
695 if( self
->Patterns
) xfree(self
->Patterns
);
696 if( self
->Clip
.rects
) xfree(self
->Clip
.rects
);
697 if( closeFile
) fclose(self
->Fp
);
702 PsOut_BeginPage(PsOutPtr self
, int orient
, int count
, int plex
, int res
,
707 /*** comment for pagenumbers *****/
709 S_Comment(self
,"%%PageHeader");
711 sprintf(coms
,"%%%%Page: %d %d", self
->pagenum
, self
->pagenum
);
712 S_Comment(self
, coms
);
713 sprintf(coms
,"%%%%PageOrientation: %s",pg_orient
[orient
]);
714 S_Comment(self
, coms
);
716 /*** end comment *****************/
718 /* set page level page attributes */
719 S_SetPageDevice(self
, orient
, count
, plex
, res
, wd
, ht
, 1);
721 S_OutTok(self
, "gs ", 0);
723 * check to see if we set orientation already; if it wasn't set,
724 * use Cs to set orientation here.
726 S_OutNum(self
, (float)orient
);
727 S_OutTok(self
, "orientationFailed { ", 0);
728 S_OutNum(self
, (float)orient
);
729 S_OutTok(self
, " } { 0 }ie Cs 100 sml gs", 1);
733 PsOut_EndPage(PsOutPtr self
)
735 S_OutTok(self
, "gr gr sp", 1);
737 /* did grestore: mark attributes 'dirty' so they will be re-sent */
738 PsOut_DirtyAttributes(self
);
740 /*** comment for pagenumbers *****/
742 S_Comment(self
,"%%PageTrailer");
744 /*** end comment *****************/
748 PsOut_DirtyAttributes(PsOutPtr self
)
751 self
->CurColor
= PSOUTCOLOR_NOCOLOR
;
752 self
->LineWidth
= -1;
753 self
->LineCap
= (PsCapEnum
)-1;
754 self
->LineJoin
= (PsJoinEnum
)-1;
757 for( i
=0 ; i
<4 ; i
++ ) self
->FontMtx
[i
] = -1.;
758 if( self
->Dashes
) { xfree(self
->Dashes
); self
->Dashes
= (int *)0; }
759 if( self
->FontName
) { xfree(self
->FontName
); self
->FontName
= (char *)0; }
763 PsOut_Comment(PsOutPtr self
, char *comment
)
765 S_Comment(self
, comment
);
769 PsOut_Offset(PsOutPtr self
, int x
, int y
)
776 PsOut_Clip(PsOutPtr self
, int clpTyp
, PsClipPtr clpinf
)
783 if( self
->InTile
) return;
784 if( self
->InFrame
) xo
= yo
= 0;
785 if( clpTyp
!=self
->ClipType
) changed
= 1;
788 if( clpinf
->nRects
!=self
->Clip
.nRects
) changed
= 1;
791 if( clpinf
->nOutterClips
!=self
->Clip
.nOutterClips
) changed
= 1;
794 for( i
=0 ; i
<clpinf
->nOutterClips
; i
++ )
796 if( memcmp(&clpinf
->outterClips
[i
], &self
->Clip
.outterClips
[i
],
797 sizeof(PsRectRec
))!=0 ) break;
799 if( i
<clpinf
->nOutterClips
) changed
= 1;
802 for( i
=0 ; i
<clpinf
->nRects
; i
++ )
804 if( memcmp(&clpinf
->rects
[i
], &self
->Clip
.rects
[i
],
805 sizeof(PsRectRec
))!=0 ) { changed
= 1; break; }
810 if( clpinf
->nElms
!=self
->Clip
.nElms
) changed
= 1;
813 for( i
=0 ; i
<clpinf
->nElms
; i
++ )
815 if( clpinf
->elms
[i
].type
!=PSOUT_POINTS
)
817 if( memcmp(&clpinf
->elms
[i
], &self
->Clip
.elms
[i
],
818 sizeof(PsElmRec
))!=0 ) { changed
= 1; break; }
822 if( clpinf
->elms
[i
].type
!=self
->Clip
.elms
[i
].type
||
823 clpinf
->elms
[i
].nPoints
!=self
->Clip
.elms
[i
].nPoints
)
824 { changed
= 1; break; }
827 for( k
=0 ; k
<clpinf
->elms
[i
].nPoints
; k
++ )
829 if( memcmp(&clpinf
->elms
[i
].c
.points
[k
],
830 &self
->Clip
.elms
[i
].c
.points
[k
], sizeof(PsPointRec
)) )
831 { changed
= 1; break; }
840 if( self
->Clip
.rects
) xfree(self
->Clip
.rects
);
841 if( self
->Clip
.outterClips
) xfree(self
->Clip
.outterClips
);
842 if( self
->Clip
.elms
)
843 PsDestroyFillElementList(self
->Clip
.nElms
, self
->Clip
.elms
);
844 self
->ClipType
= clpTyp
;
845 self
->Clip
.nRects
= clpinf
->nRects
;
846 self
->Clip
.nElms
= clpinf
->nElms
;
847 self
->Clip
.nOutterClips
= clpinf
->nOutterClips
;
850 self
->Clip
.rects
= (PsRectPtr
)xalloc(clpinf
->nRects
*sizeof(PsRectRec
));
851 memcpy(self
->Clip
.rects
, clpinf
->rects
, clpinf
->nRects
*sizeof(PsRectRec
));
853 else self
->Clip
.rects
= 0;
854 if( clpinf
->nOutterClips
)
856 self
->Clip
.outterClips
= (PsRectPtr
)xalloc(clpinf
->nOutterClips
*
858 memcpy(self
->Clip
.outterClips
, clpinf
->outterClips
,
859 clpinf
->nOutterClips
*sizeof(PsRectRec
));
861 else self
->Clip
.outterClips
= 0;
863 self
->Clip
.elms
= PsCloneFillElementList(clpinf
->nElms
, clpinf
->elms
);
864 else self
->Clip
.elms
= 0;
866 PsOut_DirtyAttributes(self
);
867 S_OutTok(self
, "gr gs", 1);
868 if( self
->Clip
.nOutterClips
)
870 for( i
=0 ; i
<self
->Clip
.nOutterClips
; i
++ )
872 S_OutNum(self
, (float)(self
->Clip
.outterClips
[i
].x
));
873 S_OutNum(self
, (float)(self
->Clip
.outterClips
[i
].y
));
874 S_OutNum(self
, (float)self
->Clip
.outterClips
[i
].w
);
875 S_OutNum(self
, (float)self
->Clip
.outterClips
[i
].h
);
876 S_OutTok(self
, "R", 1);
878 S_OutTok(self
, "cl n", 1);
880 if( self
->Clip
.nRects
)
882 for( i
=0 ; i
<self
->Clip
.nRects
; i
++ )
884 S_OutNum(self
, (float)(self
->Clip
.rects
[i
].x
+xo
));
885 S_OutNum(self
, (float)(self
->Clip
.rects
[i
].y
+yo
));
886 S_OutNum(self
, (float)self
->Clip
.rects
[i
].w
);
887 S_OutNum(self
, (float)self
->Clip
.rects
[i
].h
);
888 S_OutTok(self
, "R", 1);
890 S_OutTok(self
, "cl n", 1);
892 if( self
->Clip
.nElms
)
894 PsElmPtr elm
= self
->Clip
.elms
;
895 for( i
=0 ; i
<self
->Clip
.nElms
; i
++,elm
++ )
900 for( k
=0 ; k
<elm
->nPoints
; k
++ )
902 S_OutNum(self
, (float)elm
->c
.points
[k
].x
+xo
);
903 S_OutNum(self
, (float)elm
->c
.points
[k
].y
+yo
);
904 if( k
==0 ) S_OutTok(self
, "m", 0);
905 else S_OutTok(self
, "l", 0);
907 S_OutTok(self
, "cp", 1);
910 S_OutNum(self
, (float)elm
->c
.rect
.x
+xo
);
911 S_OutNum(self
, (float)elm
->c
.rect
.y
+yo
);
912 S_OutNum(self
, (float)elm
->c
.rect
.w
);
913 S_OutNum(self
, (float)elm
->c
.rect
.h
);
914 S_OutTok(self
, "R", 1);
917 if( elm
->c
.arc
.style
==PsPieSlice
)
919 S_OutNum(self
, (float)elm
->c
.arc
.x
+xo
+(float)elm
->c
.arc
.w
/2.);
920 S_OutNum(self
, (float)elm
->c
.arc
.y
+yo
+(float)elm
->c
.arc
.h
/2.);
921 S_OutTok(self
, "m", 0);
923 S_OutNum(self
, (float)elm
->c
.arc
.x
+xo
+(float)elm
->c
.arc
.w
/2.);
924 S_OutNum(self
, (float)elm
->c
.arc
.y
+yo
+(float)elm
->c
.arc
.h
/2.);
925 S_OutNum(self
, (float)elm
->c
.arc
.w
);
926 S_OutNum(self
, (float)elm
->c
.arc
.h
);
927 S_OutNum(self
, (float)elm
->c
.arc
.a1
/64.);
928 S_OutNum(self
, (float)elm
->c
.arc
.a1
/64.+(float)elm
->c
.arc
.a2
/64.);
929 if( elm
->c
.arc
.a2
<0 ) S_OutTok(self
, "An cp", 1);
930 else S_OutTok(self
, "Ac cp", 1);
934 S_OutTok(self
, "cl n", 1);
939 PsOut_Color(PsOutPtr self
, PsOutColor clr
)
941 if( clr
==self
->CurColor
|| self
->InTile
>=PsStip
) return;
942 self
->CurColor
= clr
;
947 PsOut_FillRule(PsOutPtr self
, PsRuleEnum rule
)
949 self
->FillRule
= rule
;
953 PsOut_LineAttrs(PsOutPtr self
, int wd
, PsCapEnum cap
, PsJoinEnum join
,
954 int nDsh
, int *dsh
, int dshOff
, PsOutColor bclr
)
959 if( wd
!=self
->LineWidth
&& wd
>=0 )
962 self
->LineWidth
= wd
;
963 S_OutNum(self
, (float)wd
); S_OutTok(self
, "w", 1);
965 if( cap
!=self
->LineCap
)
968 S_OutNum(self
, (float)cap
); S_OutTok(self
, "lc", 1);
970 if( join
!=self
->LineJoin
)
972 self
->LineJoin
= join
;
973 S_OutNum(self
, (float)join
); S_OutTok(self
, "lj", 1);
975 if( nDsh
!=self
->NDashes
) same
= 0;
976 else if( dshOff
!=self
->DashOffset
) same
= 0;
979 for( i
=0 ; i
<nDsh
; i
++ )
980 { if( dsh
[i
]!=self
->Dashes
[i
] ) break; }
981 if( i
<nDsh
) same
= 0;
985 if( self
->NDashes
&& self
->Dashes
)
986 { xfree(self
->Dashes
); self
->Dashes
= (int *)0; }
987 self
->NDashes
= nDsh
;
988 self
->DashOffset
= dshOff
;
989 if( nDsh
) self
->Dashes
= (int *)xalloc(sizeof(int)*nDsh
);
990 S_OutTok(self
, "[", 0);
991 for( i
=0 ; i
<nDsh
; i
++ )
993 self
->Dashes
[i
] = dsh
[i
];
994 S_OutNum(self
, (float)dsh
[i
]);
996 S_OutTok(self
, "]", 0);
997 S_OutNum(self
, (float)dshOff
);
998 S_OutTok(self
, "ds", 1);
1002 self
->LineBClr
= bclr
;
1004 bclr
= PSOUTCOLOR_NOCOLOR
;
1008 PsOut_TextAttrs(PsOutPtr self
, char *fnam
, int siz
, int iso
)
1012 if( self
->FontName
&& strcmp(fnam
, self
->FontName
)==0 &&
1013 siz
==self
->FontSize
) return;
1014 if( self
->FontName
) xfree(self
->FontName
);
1015 self
->FontName
= (char *)xalloc(strlen(fnam
)+1);
1016 strcpy(self
->FontName
, fnam
);
1017 self
->FontSize
= siz
;
1018 for( i
=0 ; i
<4 ; i
++ ) self
->FontMtx
[i
] = -1.;
1019 strcpy(buf
, "/"); strcat(buf
, fnam
);
1020 S_OutTok(self
, buf
, 0);
1021 S_OutNum(self
, (float)siz
);
1022 if( iso
) S_OutTok(self
, "t", 0);
1023 else S_OutTok(self
, "f", 0);
1024 S_OutTok(self
, "Tf", 1);
1028 PsOut_TextAttrsMtx(PsOutPtr self
, char *fnam
, float *mtx
, int iso
)
1032 if( self
->FontName
&& strcmp(fnam
, self
->FontName
)==0 &&
1033 mtx
[0]==self
->FontMtx
[0] && mtx
[1]==self
->FontMtx
[1] &&
1034 mtx
[2]==self
->FontMtx
[2] && mtx
[3]==self
->FontMtx
[3] ) return;
1035 if( self
->FontName
) xfree(self
->FontName
);
1036 self
->FontName
= (char *)xalloc(strlen(fnam
)+1);
1037 strcpy(self
->FontName
, fnam
);
1038 for( i
=0 ; i
<4 ; i
++ ) self
->FontMtx
[i
] = mtx
[i
];
1039 self
->FontSize
= -1;
1040 strcpy(buf
, "/"); strcat(buf
, fnam
); strcat(buf
, " [");
1041 S_OutTok(self
, buf
, 0);
1042 for( i
=0 ; i
<4 ; i
++ ) S_OutNum(self
, mtx
[i
]);
1043 S_OutTok(self
, "0 0]", 0);
1044 if( iso
) S_OutTok(self
, "t", 0);
1045 else S_OutTok(self
, "f", 0);
1046 S_OutTok(self
, "Tfm", 1);
1050 PsOut_Polygon(PsOutPtr self
, int nPts
, PsPointPtr pts
)
1053 int xo
= self
->XOff
;
1054 int yo
= self
->YOff
;
1056 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1057 if( nPts
<=2 ) return;
1058 for( i
=0 ; i
<nPts
; i
++ )
1060 S_OutNum(self
, (float)(pts
[i
].x
+xo
));
1061 S_OutNum(self
, (float)(pts
[i
].y
+yo
));
1062 if( i
==0 ) S_OutTok(self
, "m", 0);
1063 else S_OutTok(self
, "l", 0);
1065 if( self
->FillRule
==PsEvenOdd
) S_OutTok(self
, "cp ef", 1);
1066 else S_OutTok(self
, "cp fl", 1);
1070 PsOut_FillRect(PsOutPtr self
, int x
, int y
, int w
, int h
)
1072 int xo
= self
->XOff
;
1073 int yo
= self
->YOff
;
1075 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1077 S_OutNum(self
, (float)x
);
1078 S_OutNum(self
, (float)y
);
1079 S_OutNum(self
, (float)w
);
1080 S_OutNum(self
, (float)h
);
1081 S_OutTok(self
, "R fl", 1);
1085 PsOut_FillArc(PsOutPtr self
, int x
, int y
, int w
, int h
,
1086 float ang1
, float ang2
, PsArcEnum style
)
1088 int xo
= self
->XOff
;
1089 int yo
= self
->YOff
;
1091 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1093 if( style
==PsPieSlice
)
1095 S_OutNum(self
, (float)x
+(float)w
/2.);
1096 S_OutNum(self
, (float)y
+(float)h
/2.);
1097 S_OutTok(self
, "m", 0);
1099 S_OutNum(self
, (float)x
+(float)w
/2.);
1100 S_OutNum(self
, (float)y
+(float)h
/2.);
1101 S_OutNum(self
, (float)w
);
1102 S_OutNum(self
, (float)h
);
1103 S_OutNum(self
, ang1
);
1104 S_OutNum(self
, ang1
+ang2
);
1105 if( ang2
<0 ) S_OutTok(self
, "An cp fl", 1);
1106 else S_OutTok(self
, "Ac cp fl", 1);
1110 PsOut_Lines(PsOutPtr self
, int nPts
, PsPointPtr pts
)
1113 int xo
= self
->XOff
;
1114 int yo
= self
->YOff
;
1116 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1117 if( nPts
<1 ) return;
1118 for( i
=0 ; i
<nPts
; i
++ )
1120 S_OutNum(self
, (float)(pts
[i
].x
+xo
));
1121 S_OutNum(self
, (float)(pts
[i
].y
+yo
));
1122 if( i
==0 ) S_OutTok(self
, "m", 0);
1123 else S_OutTok(self
, "l", 0);
1125 if( self
->LineBClr
!= PSOUTCOLOR_NOCOLOR
)
1127 S_OutTok(self
, "gs", 0);
1128 S_Color(self
, self
->LineBClr
);
1129 S_OutTok(self
, "[] 0 ds st gr", 0);
1131 S_OutTok(self
, "st", 1);
1135 PsOut_Points(PsOutPtr self
, int nPts
, PsPointPtr pts
)
1138 int xo
= self
->XOff
;
1139 int yo
= self
->YOff
;
1141 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1142 if( nPts
<1 ) return;
1143 for( i
=0 ; i
<nPts
; i
++ )
1145 S_OutNum(self
, (float)(pts
[i
].x
+xo
));
1146 S_OutNum(self
, (float)(pts
[i
].y
+yo
));
1147 S_OutTok(self
, "P", 1);
1152 PsOut_DrawRect(PsOutPtr self
, int x
, int y
, int w
, int h
)
1154 int xo
= self
->XOff
;
1155 int yo
= self
->YOff
;
1157 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1159 S_OutNum(self
, (float)x
);
1160 S_OutNum(self
, (float)y
);
1161 S_OutNum(self
, (float)w
);
1162 S_OutNum(self
, (float)h
);
1163 S_OutTok(self
, "R", 0);
1164 if( self
->LineBClr
!= PSOUTCOLOR_NOCOLOR
)
1166 S_OutTok(self
, "gs", 0);
1167 S_Color(self
, self
->LineBClr
);
1168 S_OutTok(self
, "[] 0 ds st gr", 0);
1170 S_OutTok(self
, "st", 1);
1174 PsOut_DrawArc(PsOutPtr self
, int x
, int y
, int w
, int h
,
1175 float ang1
, float ang2
)
1177 int xo
= self
->XOff
;
1178 int yo
= self
->YOff
;
1180 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1182 S_OutNum(self
, (float)x
+(float)w
/2.);
1183 S_OutNum(self
, (float)y
+(float)h
/2.);
1184 S_OutNum(self
, (float)w
);
1185 S_OutNum(self
, (float)h
);
1186 S_OutNum(self
, ang1
);
1187 S_OutNum(self
, ang1
+ang2
);
1188 if( ang2
<0 ) S_OutTok(self
, "An", 0);
1189 else S_OutTok(self
, "Ac", 0);
1190 if( self
->LineBClr
!= PSOUTCOLOR_NOCOLOR
)
1192 S_OutTok(self
, "gs", 0);
1193 S_Color(self
, self
->LineBClr
);
1194 S_OutTok(self
, "[] 0 ds st gr", 0);
1196 S_OutTok(self
, "st", 1);
1200 PsOut_Text(PsOutPtr self
, int x
, int y
, char *text
, int textl
, PsOutColor bclr
)
1202 int xo
= self
->XOff
;
1203 int yo
= self
->YOff
;
1205 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1207 S_OutStr(self
, text
, textl
);
1208 S_OutNum(self
, (float)x
);
1209 S_OutNum(self
, (float)y
);
1210 if( bclr
== PSOUTCOLOR_NOCOLOR
)
1211 S_OutTok(self
, "T", 1);
1214 int ir
= PSOUTCOLOR_TO_REDBITS(bclr
);
1215 int ig
= PSOUTCOLOR_TO_GREENBITS(bclr
);
1216 int ib
= PSOUTCOLOR_TO_BLUEBITS(bclr
);
1218 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ir
));
1219 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ig
));
1220 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ib
));
1221 S_OutTok(self
, "Tb", 1);
1226 PsOut_Text16(PsOutPtr self
, int x
, int y
, unsigned short *text
, int textl
, PsOutColor bclr
)
1228 int xo
= self
->XOff
;
1229 int yo
= self
->YOff
;
1231 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1233 S_OutStr16(self
, text
, textl
);
1234 S_OutNum(self
, (float)x
);
1235 S_OutNum(self
, (float)y
);
1236 if( bclr
== PSOUTCOLOR_NOCOLOR
)
1237 S_OutTok(self
, "T", 1);
1240 int ir
= PSOUTCOLOR_TO_REDBITS(bclr
);
1241 int ig
= PSOUTCOLOR_TO_GREENBITS(bclr
);
1242 int ib
= PSOUTCOLOR_TO_BLUEBITS(bclr
);
1243 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ir
));
1244 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ig
));
1245 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ib
));
1246 S_OutTok(self
, "Tb", 1);
1252 PsOut_ImageCache(PsOutPtr self
, int x
, int y
, long cache_id
, PsOutColor bclr
, PsOutColor fclr
)
1255 int xo
= self
->XOff
;
1256 int yo
= self
->YOff
;
1258 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1260 sprintf(cacheID
, "c%di", cache_id
);
1262 S_OutNum(self
, (float)x
);
1263 S_OutNum(self
, (float)y
);
1265 if( fclr
==PSOUTCOLOR_WHITE
)
1267 int ir
= PSOUTCOLOR_TO_REDBITS(bclr
);
1268 int ig
= PSOUTCOLOR_TO_GREENBITS(bclr
);
1269 int ib
= PSOUTCOLOR_TO_BLUEBITS(bclr
);
1271 if( ir
==ig
&& ig
==ib
)
1272 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ir
));
1274 S_OutNum(self
, (float)0);
1279 int ir
= PSOUTCOLOR_TO_REDBITS(fclr
);
1280 int ig
= PSOUTCOLOR_TO_GREENBITS(fclr
);
1281 int ib
= PSOUTCOLOR_TO_BLUEBITS(fclr
);
1283 if( ir
==ig
&& ig
==ib
)
1284 S_OutNum(self
, PSOUTCOLOR_BITS_TO_PSFLOAT(ir
));
1286 S_OutNum(self
, (float)0);
1289 S_OutTok(self
, cacheID
, 1);
1293 PsOut_BeginImageCache(PsOutPtr self
, long cache_id
)
1297 sprintf(cacheID
, "/c%di {", cache_id
);
1299 S_OutTok(self
, cacheID
, 0);
1303 PsOut_EndImageCache(PsOutPtr self
)
1305 S_OutTok(self
, "}bd", 1);
1310 PsOut_BeginImage(PsOutPtr self
, PsOutColor bclr
, PsOutColor fclr
, int x
, int y
,
1311 int w
, int h
, int sw
, int sh
, int format
)
1313 PsOutColor savClr
= self
->CurColor
;
1314 int xo
= self
->XOff
;
1315 int yo
= self
->YOff
;
1317 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1321 if( self
->InTile
>=PsStip
&& format
!=1 ) { self
->ImgSkip
= 1; return; }
1322 self
->ImgBClr
= bclr
; self
->ImgFClr
= fclr
;
1323 self
->ImgX
= x
; self
->ImgY
= y
;
1324 self
->ImgW
= w
; self
->ImgH
= h
;
1325 self
->SclW
= sw
; self
->SclH
= sh
;
1326 S_OutTok(self
, "<", 0);
1327 self
->ImageFormat
= format
;
1329 if( self
->InTile
==PsTile
&& format
==1 && fclr
==PSOUTCOLOR_WHITE
)
1337 S_OutTok(self
, "gs", 0);
1338 if( fclr
==PSOUTCOLOR_WHITE
)
1340 PsOut_Color(self
, fclr
);
1341 PsOut_FillRect(self
, x
, y
, sw
, sh
);
1342 PsOut_Color(self
, bclr
);
1347 PsOut_Color(self
, bclr
);
1348 PsOut_FillRect(self
, x
, y
, sw
, sh
);
1349 PsOut_Color(self
, fclr
);
1352 S_OutNum(self
, (float)x
);
1353 S_OutNum(self
, (float)y
);
1354 S_OutNum(self
, (float)w
);
1355 S_OutNum(self
, (float)h
);
1356 S_OutNum(self
, (float)sw
);
1357 S_OutNum(self
, (float)sh
);
1360 S_OutTok(self
, "Im1rev", 1);
1362 S_OutTok(self
, "Im1", 1);
1364 else S_OutTok(self
, "Im24", 1);
1365 self
->ImageFormat
= format
;
1366 self
->CurColor
= savClr
;
1370 PsOut_BeginImageIM(PsOutPtr self
, PsOutColor bclr
, PsOutColor fclr
, int x
, int y
,
1371 int w
, int h
, int sw
, int sh
, int format
)
1373 PsOutColor savClr
= self
->CurColor
;
1374 int xo
= self
->XOff
;
1375 int yo
= self
->YOff
;
1377 if( self
->InFrame
|| self
->InTile
) xo
= yo
= 0;
1381 if( self
->InTile
>=PsStip
&& format
!=1 ) { self
->ImgSkip
= 1; return; }
1382 self
->ImgBClr
= bclr
; self
->ImgFClr
= fclr
;
1383 self
->ImgX
= x
; self
->ImgY
= y
;
1384 self
->ImgW
= w
; self
->ImgH
= h
;
1385 self
->SclW
= sw
; self
->SclH
= sh
;
1386 S_OutTok(self
, "<", 0);
1387 self
->ImageFormat
= format
;
1389 if( self
->InTile
==PsTile
&& format
==1 && fclr
==PSOUTCOLOR_WHITE
)
1397 S_OutTok(self
, "gs", 0);
1399 S_OutTok(self
, "g", 1);
1401 if( fclr
==PSOUTCOLOR_WHITE
)
1403 PsOut_Color(self
, bclr
);
1408 PsOut_Color(self
, fclr
);
1414 S_OutTok(self
, "tr", 0); /* new */
1416 S_OutNum(self
, (float)x
);
1417 S_OutNum(self
, (float)y
);
1419 S_OutNum(self
, (float)w
);
1420 S_OutNum(self
, (float)h
);
1421 S_OutNum(self
, (float)sw
);
1422 S_OutNum(self
, (float)sh
);
1424 S_OutTok(self
, "mtx", 1); /* new */
1425 S_OutTok(self
, "<", 0); /* new */
1426 self
->start_image
= 1;
1430 S_OutTok(self
, "Im1rev", 1);
1432 S_OutTok(self
, "Im1", 1);
1434 else S_OutTok(self
, "Im24", 1);
1436 self
->ImageFormat
= format
;
1437 self
->CurColor
= savClr
;
1441 PsOut_EndImage(PsOutPtr self
)
1443 if( self
->ImgSkip
) { self
->ImgSkip
= 0; return; }
1446 S_OutTok(self
, ">", 1);
1447 if( self
->ImageFormat
==1 && self
->InTile
==PsTile
)
1449 if( self
->ImgFClr
==PSOUTCOLOR_WHITE
)
1451 PsOut_Color(self
, self
->ImgFClr
);
1452 PsOut_FillRect(self
, self
->ImgX
, self
->ImgY
, self
->SclW
, self
->SclH
);
1453 PsOut_Color(self
, self
->ImgBClr
);
1457 PsOut_Color(self
, self
->ImgBClr
);
1458 PsOut_FillRect(self
, self
->ImgX
, self
->ImgY
, self
->SclW
, self
->SclH
);
1459 PsOut_Color(self
, self
->ImgFClr
);
1462 S_OutNum(self
, (float)self
->ImgX
);
1463 S_OutNum(self
, (float)self
->ImgY
);
1464 S_OutNum(self
, (float)self
->ImgW
);
1465 S_OutNum(self
, (float)self
->ImgH
);
1466 S_OutNum(self
, (float)self
->SclW
);
1467 S_OutNum(self
, (float)self
->SclH
);
1468 if( self
->ImageFormat
==1 ) S_OutTok(self
, "Im1t", 1);
1469 else S_OutTok(self
, "Im24t", 1);
1470 self
->ImageFormat
= 0;
1475 * Bug 4639307: Move flush before "> im" to get all of bitmap into ps file.
1479 if(self
->start_image
)
1480 S_OutTok(self
, "> im", 1); /* new */
1482 self
->ImageFormat
= 0;
1485 if(self
->start_image
)
1487 self
->start_image
= 0;
1488 S_OutTok(self
, "gr", 0);
1491 S_OutTok(self
, "gr", 1);
1493 S_OutTok(self
, "gr", 1);
1498 PsOut_OutImageBytes(PsOutPtr self
, int nBytes
, char *bytes
)
1503 const char hex
[] = { '0', '1', '2', '3', '4', '5', '6', '7',
1504 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
1506 if( (!self
->ImageFormat
) || self
->ImgSkip
) return;
1508 len
= strlen(self
->Buf
);
1510 for( i
=0 ; i
<nBytes
; i
++ )
1512 if( self
->RevImage
) b
= (int)((bytes
[i
]^0xFF)&0xFF);
1513 else b
= (int)(bytes
[i
]&0xFF);
1515 self
->Buf
[len
++] = hex
[(b
&0xF0) >> 4];
1516 self
->Buf
[len
++] = hex
[(b
&0x0F)];
1517 self
->Buf
[len
] = '\0';
1528 PsOut_BeginFrame(PsOutPtr self
, int xoff
, int yoff
, int x
, int y
,
1531 int xo
= self
->XOff
;
1532 int yo
= self
->YOff
;
1534 if( self
->InFrame
) xo
= yo
= 0;
1535 S_OutTok(self
, "gs", 0);
1536 S_OutNum(self
, (float)(x
+xo
));
1537 S_OutNum(self
, (float)(y
+yo
));
1538 S_OutNum(self
, (float)w
);
1539 S_OutNum(self
, (float)h
);
1540 S_OutTok(self
, "R cl n", 0);
1541 xoff
+= xo
; yoff
+= yo
;
1544 S_OutNum(self
, (float)xoff
);
1545 S_OutNum(self
, (float)yoff
);
1546 S_OutTok(self
, "tr", 0);
1548 S_OutTok(self
, "gs", 1);
1553 PsOut_EndFrame(PsOutPtr self
)
1556 if( self
->InFrame
<0 ) self
->InFrame
= 0;
1557 S_OutTok(self
, "gr gr", 1);
1558 PsOut_DirtyAttributes(self
);
1562 PsOut_BeginPattern(PsOutPtr self
, void *tag
, int w
, int h
, PsFillEnum type
,
1563 PsOutColor bclr
, PsOutColor fclr
)
1568 for( i
=0 ; i
<self
->NPatterns
; i
++ )
1569 { if( self
->Patterns
[i
].tag
==tag
&& self
->Patterns
[i
].type
==type
) break; }
1570 if( i
<self
->NPatterns
) return(1);
1571 if( (self
->NPatterns
+1)>self
->MxPatterns
)
1573 if( self
->Patterns
)
1575 self
->MxPatterns
*= 2;
1577 (PsPatPtr
)xrealloc(self
->Patterns
, sizeof(PsPatRec
)*self
->MxPatterns
);
1581 self
->MxPatterns
= 64;
1582 self
->Patterns
= (PsPatPtr
)xalloc(sizeof(PsPatRec
)*self
->MxPatterns
);
1585 self
->Patterns
[self
->NPatterns
].tag
= tag
;
1586 self
->Patterns
[self
->NPatterns
].type
= type
;
1587 sprintf(key
, "/ %d", (int)tag
);
1589 case PsTile
: key
[1] = 't'; break;
1590 case PsStip
: key
[1] = 's'; break;
1591 case PsOpStip
: key
[1] = 'o'; break;
1593 S_OutTok(self
, key
, 0);
1594 S_OutTok(self
, "db/PatternType 1 d/PaintType 1 d", 0);
1595 S_OutTok(self
, "/TilingType 1 d/BBox[0 0", 0);
1596 S_OutNum(self
, (float)w
);
1597 S_OutNum(self
, (float)h
);
1598 S_OutTok(self
, "]d/XStep", 0);
1599 S_OutNum(self
, (float)w
);
1600 S_OutTok(self
, "d/YStep", 0);
1601 S_OutNum(self
, (float)h
);
1602 S_OutTok(self
, "d/PaintProc{bg sv", 1);
1603 if( type
==PsOpStip
)
1605 S_Color(self
, bclr
);
1606 S_OutTok(self
, "0 0", 0);
1607 S_OutNum(self
, (float)w
);
1608 S_OutNum(self
, (float)h
);
1609 S_OutTok(self
, "R fl", 1);
1611 if( type
!=PsTile
) S_Color(self
, fclr
);
1612 self
->NPatterns
+= 1;
1613 self
->InTile
= type
;
1618 PsOut_EndPattern(PsOutPtr self
)
1620 self
->InTile
= PsSolid
;
1621 S_OutTok(self
, "rs ed}d de im_ mp d", 1);
1625 PsOut_SetPattern(PsOutPtr self
, void *tag
, PsFillEnum type
)
1630 for( i
=0 ; i
<self
->NPatterns
; i
++ )
1631 { if( tag
==self
->Patterns
[i
].tag
&& type
==self
->Patterns
[i
].type
) break; }
1632 if( i
>=self
->NPatterns
) return;
1633 sprintf(key
, " %d", (int)tag
);
1635 case PsTile
: key
[0] = 't'; break;
1636 case PsStip
: key
[0] = 's'; break;
1637 case PsOpStip
: key
[0] = 'o'; break;
1639 S_OutTok(self
, key
, 0);
1640 S_OutTok(self
, "spt", 1);
1641 self
->CurColor
= PSOUTCOLOR_NOCOLOR
;
1645 PsOut_RawData(PsOutPtr self
, char *data
, int len
)
1648 if (!ferror(self
->Fp
)) {
1649 (void) fwrite(data
, 1, len
, self
->Fp
);
1653 typedef enum PsDownfontFontType_
1657 PsDFT_TrueType
/* not implemented yet */
1658 } PsDownfontFontType
;
1660 /* Download a PS Type1 font */
1662 PsOut_DownloadType1(PsOutPtr self
, const char *auditmsg
, const char *name
, const char *fname
)
1667 PsDownfontFontType type
;
1669 fp
= fopen(fname
, "r");
1673 #ifdef DEBUG_gisburn
1674 /* This should be log-able! */
1675 fprintf(stderr
, "PsOut_DownloadType1: %s: Downloading '%s' from '%s'\n", auditmsg
, name
, fname
);
1676 #endif /* DEBUG_gisburn */
1678 fread(buf
, 32, 1, fp
);
1679 fseek(fp
, (long)0, 0);
1681 /* Is this a Adobe PostScript Type 1 binary font (PFB) ? */
1682 if( (buf
[0]&0xFF)==0x80 && (buf
[1]&0xFF)==0x01 )
1684 type
= PsDFT_Type1PFB
;
1686 /* Is this a Adobe PostScript ASCII font (PFA) ? */
1687 else if (!strncmp(buf
, "%!PS-AdobeFont", 14))
1689 type
= PsDFT_Type1PFA
;
1693 /* This should be log-able! */
1694 fprintf(stderr
, "PsOut_DownloadType1: Unknown font type for '%s'\n", fname
);
1699 sprintf(buf
, "%%%%BeginFont: %s", name
);
1700 S_Comment(self
, buf
);
1702 if( type
== PsDFT_Type1PFB
)
1711 /* Strip out the binary headers and de-binary it */
1712 while( (ch
&0xFF) == 0x80 )
1715 if( stype
==3 ) /* eof mark */
1718 len
|= fgetc(fp
)<<8;
1719 len
|= fgetc(fp
)<<16;
1720 len
|= fgetc(fp
)<<24;
1721 buf
= (char *)xalloc(len
+1);
1724 /* Process ASCII section */
1725 len
= fread(buf
, 1, len
, fp
);
1726 /* convert any lone CRs (ie Mac eol) to LFs */
1727 for( pt
= buf
; (pt
= memchr(pt
, '\r', len
-(pt
-buf
))) != NULL
; pt
++ )
1732 fwrite(buf
, 1, len
, self
->Fp
);
1738 /* Process binary section */
1739 len
= fread(buf
, 1, len
, fp
);
1740 for( i
=0 ; i
<len
; i
++ )
1743 if( ((ch
>>4)&0xf) <= 9 )
1744 fputc('0'+((ch
>>4)&0xf), self
->Fp
);
1746 fputc('A'-10+((ch
>>4)&0xf), self
->Fp
);
1749 fputc('0'+(ch
&0xf), self
->Fp
);
1751 fputc('A'-10+(ch
&0xf), self
->Fp
);
1753 if( (i
&0x1f)==0x1f )
1754 fputc('\n', self
->Fp
);
1763 /* Is this a Adobe PostScript ASCII font (PFA) ? */
1764 else if (type
== PsDFT_Type1PFA
)
1768 stt
= fread(buf
, 1, 256, fp
);
1770 if (!ferror(self
->Fp
)) {
1771 (void) fwrite(buf
, 1, stt
, self
->Fp
);
1779 S_Comment(self
, "%%EndFont");