3 % Copyright (C) 2002 artofcode LLC. All rights reserved.
5 % This software is provided AS-IS with no warranty, either express or
8 % This software is distributed under license and may not be copied,
9 % modified or distributed except as expressly authorized under the terms
10 % of the license contained in the file LICENSE in this distribution.
12 % For more information about licensing, please refer to
13 % http://www.ghostscript.com/licensing/. For information on
14 % commercial licensing, go to http://www.artifex.com/licensing/ or
15 % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
16 % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
18 % $Id: opdfread.ps,v 1.84 2005/09/07 20:43:36 leonardo Exp $
19 % pdfread.ps - A procset for interpreting an ordered PDF 1.3 file.
21 % This module defines routines for interpreting a PDF file with
22 % a Postscript interpreter. To convert a PDF file into Postscript
23 % just pre-contcatenate this file. The PDF file must satisfy
26 % 1. It must contain only Postscript level 2 objects encoded with
27 % the PDF 1.3 language. Higher PDF levels must be re-distilled
28 % with CompatibilityLevel=1.3 .
30 % 2. Objects must be ordered so that any resource be defined before
33 % 3. The PDF file must not include other PDF files.
34 % Consequently we have a single instance of the PDF reader.
35 % We use this fact to simplify binding of the routines.
37 % 4. The PDF root object must always have the object id 1.
39 % 5. Generations besides 0 are not allowed.
41 % 6. xref must appear after all objects.
43 % Assuming the currentfile isn't positionable.
44 % As a consequence, the reader fully ignores xref.
49 % ====================== Error handler =======================
50 % A general error handler prints an error to page.
52 10 dict begin % A dictionary for local binding
59 36 //this /y get moveto //ebuf cvs show
60 //this /y 2 copy get 12 sub put
64 36 //this /y get moveto
65 //this /y 2 copy get 12 sub put
68 errordict /handleerror
72 { (%%[ Error handled by opdfread.ps : ) print errorname //ebuf cvs print (; OffendingCommand: )
73 print /command load //ebuf cvs print ( ]%%) = flush
74 /newerror false store vmstatus pop pop 0 ne
77 errorname (VMerror) ne
82 errorname (VMerror) eq
83 { //this /ehsave known
84 { clear //this /ehsave get restore 2 vmreclaim
86 vmstatus exch pop exch pop
88 /Courier 12 selectfont
90 (ERROR: ) //prnt exec errorname //prnt exec
91 (OFFENDING COMMAND: ) //prnt exec
92 /command load //prnt exec
93 $error /ostack known {
96 $error /ostack get aload length {
101 dup type /nametype eq {
107 dup = //ebuf cvs show
113 //systemdict /showpage get exec
120 end % A dictionary for local binding
125 % ===================== Debugging =========================================
127 /DefaultSwitch % <name> DefaultSwitch -
136 /=string 256 string def
142 /HexDigits (0123456789ABCDEF) readonly def
144 /PrintHex % <int> PrintHex -
146 dup -28 bitshift //HexDigits exch 1 getinterval //=only exec
152 /PDFR_DEBUG DefaultSwitch
153 /PDFR_DUMP DefaultSwitch
154 /PDFR_STREAM DefaultSwitch
155 /TTFDEBUG DefaultSwitch
156 /RotatePages DefaultSwitch
157 /FitPages DefaultSwitch
158 /SetPageSize DefaultSwitch
160 /error % mark <object> .... error -
161 { % A stub for a while.
162 counttomark 1 sub -1 0 {
163 index dup type /arraytype eq { == } { =only } ifelse
167 % Assuming ....Undefined is never defined.
168 % Use it to emit an error.
173 //RotatePages //FitPages or {
174 mark (/RotatePages, /FitPages are not allowed with /SetPageSize) //error exec
178 % ===================== Utilities =========================================
180 /knownget % <dict> <key> knownget <value> true
181 % <dict> <key> knownget false
190 /IsUpper % <int> IsUpper <bool>
191 { dup (A) 0 get ge exch (Z) 0 get le and
194 % ===================== Work Data =========================================
196 /BlockBuffer 65535 string def % Make it big to load entire TrueType font
197 /PDFReader currentdict def
198 /ObjectRegistry 50 array def % may grow later
199 /CurrentObject null def
200 /DoneDocumentStructure false def
201 /GraphicState 20 dict begin
202 /InitialTextMatrix matrix def
203 /InitialMatrix matrix currentmatrix def
205 /TempMatrix matrix def
206 /GraphicStateStack 20 array def
207 /GraphicStateStackPointer 0 def
208 /PDFColorSpaces 50 dict def
209 /InstalledFonts 50 dict def
210 /MacRomanEncodingInverse null def
212 % We need some structures in local VM, put then into the userdict :
213 currentglobal false setglobal
214 userdict /PDFR_InitialGS gstate put
215 userdict /PDFR_Patterns 50 dict put
216 userdict /FuncDataReader 10 dict put
219 % ===================== Constants =========================================
221 /InitialExtGState 20 dict begin
222 /BG2 currentblackgeneration def
223 /UCR2 currentundercolorremoval def
224 /TR2 [ currentcolortransfer ] def
225 /HT currenthalftone def
226 currentdict end readonly def
228 /InitialGraphicState 20 dict begin
230 /CharacterSpacing 0 def
232 /TextRenderingMode 0 def
234 currentdict end readonly def
236 /SimpleColorSpaceNames 15 dict begin
240 currentdict end readonly def
242 /1_24_bitshift_1_sub 1 24 bitshift 1 sub def
244 /ReadFontProcs 10 dict def % Will be filled below.
246 % ===================== Reading PDF objects ===============================
248 /Register % <DefaultDaemon> <id> <obj> Register -
250 exch dup % d obj id id
251 //PDFReader /ObjectRegistry get length ge {
252 dup dup 2 idiv add array dup % d obj id [n] [n]
253 //PDFReader /ObjectRegistry get dup length % d obj id [n] [n] [o] l
254 3 2 roll exch % d obj id [n] [o] [n] l
255 0 exch getinterval copy pop % d obj id [n]
256 //PDFReader exch /ObjectRegistry exch put % d obj id
258 exch //PDFReader /ObjectRegistry get % d id obj r
259 3 1 roll % d r id obj
260 3 copy pop get % d r id obj e
261 dup xcheck { % d r id obj e
262 5 4 roll pop % r id obj e
264 (Have a daemon for ) print 2 index =
266 % We've got a definition daemon, execute it :
269 dup null ne { % d r id obj e
270 mark (The object ) 4 index ( already defined : ) 4 index //error exec
274 4 3 roll % r id obj d
275 % Execute the default daemon :
281 /IsRegistered % <id> GetRegistered <bool>
283 //PDFReader /ObjectRegistry get % id r
293 /GetRegistered % <id> GetRegistered <obj>
295 //PDFReader /ObjectRegistry get % id r
298 exch mark exch (Object ) exch ( isn't defined before needed (1).) //error exec
302 exch mark exch (Object ) exch ( isn't defined before needed (2).) //error exec
305 exch mark exch (Object ) exch ( isn't defined before needed (3).) //error exec
311 /StandardFontNames <<
321 /Helvetica-Oblique true
322 /Courier-Oblique true
323 /Times-BoldItalic true
324 /Helvetica-BoldOblique true
325 /Courier-BoldOblique true
328 /CleanAllResources % - CleanAllResources -
330 (CleanAllResources beg) =
332 //PDFReader /ObjectRegistry get
333 dup length 0 exch 1 exch 1 sub { % R i
334 2 copy get dup xcheck {
335 % Don't clean a daemon.
341 dup type /dicttype eq { /.Global known } { pop false } ifelse {
345 (Dropping ) print dup =
347 1 index exch /DroppedObject put
353 FontDirectory length dict begin
356 dup //StandardFontNames exch known not {
365 (Undefining font ) print dup =
370 (CleanAllResources end) =
374 /PrintReference % <array> PrintReference <array>
385 /R % <id> <gen> R <daemon>
386 { % Make a reference daemon.
388 exch mark exch (A referred object generation ) exch ( isn't 0.) //error exec
391 exch //GetRegistered /exec load
393 //PrintReference exec
396 /IsObjRef % <any> IsObjRef <bool>
398 dup type /arraytype eq {
401 dup 0 get type /integertype eq 3 2 roll and exch
402 dup 1 get //GetRegistered eq 3 2 roll and exch
403 2 get /exec load eq and
416 /RunTypeDaemon % <id> <obj> RunTypeDaemon <id> <obj>
418 dup type /dicttype eq {
419 dup /Type //knownget exec {
420 //PDFReader /TypeDaemons get exch
428 /obj % <id> <generation> obj <id>
431 (Defining ) print 1 index =only ( ) print dup =only ( obj) =
434 exch mark exch (An object generation ) exch ( isn't 0.) //error exec
438 /endobj % <id> <obj> endobj -
443 dup type /dicttype eq {
444 dup /.endobj_daemon //knownget exec {
445 //PDFR_DEBUG { (.endobj_daemon for ) print 2 index = } if
449 dup type /dicttype eq { dup /ImmediateExec known } { false } ifelse {
453 (Storing ) print 1 index =
456 //DoNothing 3 1 roll //Register exec
460 /StoreBlock % <buf> StoreBlock -
461 { % Stores a (encoded) stream data block to the current object.
463 (StoreBlock ) print //PDFReader /BlockCount get =only (, Length = ) print dup length =
465 dup length string copy
466 //PDFReader /BlockCount get exch % i s
467 //PDFReader /CurrentObject get 3 1 roll % o i s
469 //PDFReader /BlockCount get 1 add
470 //PDFReader exch /BlockCount exch put
473 /CheckLength % <val> CheckNumber <val>
474 { dup type /integertype ne {
475 mark (Object length isn't an integer.) //error exec
479 /ResolveD % <dict> <key> <check> ResolveD <value>
481 3 copy pop get % <> key {} e
482 dup //IsObjRef exec {
483 % We've got a reference daemon, execute it :
485 (Resolving ) print //PrintReference exec
488 exch exec % <> key val
492 dup 4 1 roll % val <> key val
496 /ResolveA % <array> <index> <check> ResolveA <value>
497 { 2 index 2 index get
498 dup //IsObjRef exec {
508 /StoreStream % <id> <obj> StoreStream <id> <obj>
509 { % Stores a (encoded) data stream copy to the current object.
510 dup //PDFReader exch /CurrentObject exch put % id obj
511 //PDFReader /BlockCount 0 put
512 dup /Length //CheckLength //ResolveD exec % id obj l
514 (StoreStream Length = ) print dup =
516 currentfile exch () /SubFileDecode filter % id obj file
517 { dup //BlockBuffer readstring { % id obj file buf
522 } ifelse % id obj file
525 //PDFReader /CurrentObject null put
531 /MakeStreamDumper % <file> MakeStreamDumper <file>
532 { % Debug purpose only.
534 (MakeStreamDumper beg.) =
536 currentglobal exch dup gcheck setglobal
538 1 dict dup /c 0 put exch % d f
540 { readstring pop % d s
541 (StreamDumper ) print 1 index /c get =string cvs print ( ) print
542 dup length =string cvs print ( <) print dup print (>\n) print
550 cvx 0 () /SubFileDecode filter
553 (MakeStreamDumper end.) =
557 /ShortFilterNames 15 dict begin
558 /AHx /ASCIIHexDecode def
559 /A85 /ASCII85Decode def
562 /RL /RunLengthDecode def
563 /CCF /CCITTFaxDecode def
565 currentdict end readonly def
567 /AppendFilters % <file> <dict> AppendFilters <file>
570 (AppendFilters beg.) =
573 /Filter //knownget exec { % d f F
574 dup type /nametype eq { % d f /F
575 dup //ShortFilterNames exch //knownget exec {
578 2 index /DecodeParms //knownget exec { % d f p /F
583 dup 0 exch 1 exch length 1 sub { % d f [] i
584 2 copy get % d f [] i /F
585 dup //ShortFilterNames exch //knownget exec {
588 3 1 roll % d f /F [] i
589 4 index /DecodeParms //knownget exec { % d f /F [] i DP
590 exch get % d f /F [] dp
592 pop null % d f /F [] dp
594 dup null eq { % d f /F [] dp
595 pop 3 1 roll filter exch % d f' []
597 3 1 roll % d f dp /F []
598 4 1 roll filter exch % d f' []
603 //PDFR_DEBUG //PDFR_DUMP and {
604 //MakeStreamDumper exec
609 (AppendFilters end.) =
613 /ExecuteStream % <id> <obj> ExecuteStream <id> <obj>
614 { % Executes a (encoded) data stream.
615 dup //PDFReader exch /CurrentObject exch put % id obj
616 dup /Length //CheckLength //ResolveD exec % id obj l
618 (ExecuteStream id = ) print 2 index =only ( Length = ) print dup =
620 //PDFReader /InitialGraphicState get
621 //PDFReader /GraphicState get copy pop
622 //PDFReader /Operators get begin
623 % currentfile exch () /SubFileDecode filter % id obj file
624 % We would like to use the code above,
625 % but HP LaserJet 1320 continues parsing after the byte count exceeds.
626 pop currentfile 0 (endstream) /SubFileDecode filter % id obj file
627 1 index //AppendFilters exec
628 cvx mark exch % id obj mark file
631 mark (Data left on ostack after an immediate stream execution.) //error exec
636 (ExecuteStream end.) =
638 //PDFReader /CurrentObject null put
640 dup /Context get /NumCopies //knownget exec {
649 /stream % <id> <obj> stream <id> <obj>
652 1 index =only ( stream) =
654 % Run the object definition daemon, if exists :
655 //PDFReader /ObjectRegistry get dup length 3 index % id obj r l id
660 % Disable the daemon :
661 //PDFReader /ObjectRegistry get 2 index null put
668 dup /ImmediateExec known {
669 dup /GlobalExec //knownget exec {
670 currentglobal 4 1 roll
680 dup /.CleanResources //knownget exec {
682 //CleanAllResources exec
687 /HookFont % <id> <obj> <font_descriptor> HookFont <id> <obj>
690 (Loaded the font ) print dup /FontName get =
693 dup /FontFileType get dup /Type1 eq exch /MMType1 eq or { % id obj fd
694 % We assume that the Type 1 font has same name with no prefix
695 % due to pdfwrite specifics.
696 % We use it to find the font after it is defined.
697 % We could redefine 'definefont' for hooking the font,
698 % but we don't think that it could be guaranteedly portable :
699 % a 3d party PS interpreter may set a special context
700 % when running the font file.
701 % Note that this mechanizm does not depend on the
702 % font name uniquity, because the last 'definefont'
704 dup /FontName get % id obj fd fn
705 //PDFReader /RemoveFontNamePrefix get exec
706 currentglobal true setglobal exch % id obj fd g fn
707 findfont % id obj fd g f
708 exch setglobal % id obj fd f
711 dup /FontFileType get /TrueType eq { % id obj fd
712 //PDFReader /MakeType42 get exec
720 (-string\() print length //=only exec (\)- ) =
724 exch //=only exec ( ) print ==
729 dup /FontName get exch definefont
732 mark (FontHook has no proc for ) 2 index /FontFileType get //error exec
734 /Font exch put % id obj
737 /endstream % <id> <obj> endstream <id> <obj>
746 //PDFReader /ObjectRegistry get ==
751 mark (Excessive data on estack at the end of the interpretation.) //error exec
753 currentfile flushfile
756 % ===================== Restoring the PDF Document Structure ===============
758 /ResolveDict % <dict> /ResolveDict -
760 pop 1 index exch % d cp key
761 //DoNothing //ResolveD exec % d obj
767 /SetupPageView % <obj> SetupPageView -
770 (SetupPageView beg) =
772 //GraphicState /InitialMatrix get setmatrix
773 /MediaBox get aload pop % bx0 by0 bx1 by1
774 3 index neg 3 index neg translate % Temporary move to origin
775 3 -1 roll sub 3 1 roll exch sub exch % bw bh
776 userdict /.HWMargins //knownget exec {
779 currentpagedevice /.HWMargins //knownget exec {
785 currentpagedevice /PageSize get aload pop
786 3 -1 roll sub 3 1 roll exch sub exch % bw bh px0 py0 px1 py1
787 exch 3 index sub exch 3 index sub % bw bh px0 py0 pw ph
790 (Setting page size to ) print 1 index //=only exec ( ) print dup =
792 pop pop 3 index 3 index 2 copy % bw bh px0 py0 bw bh bw bh
793 currentglobal false setglobal 3 1 roll % bw bh px0 py0 bw bh bool bw bh
794 2 array astore % bw bh px0 py0 bw bh bool []
795 << exch /PageSize exch >> setpagedevice % bw bh px0 py0 bw bh bool
796 userdict /PDFR_InitialGS gstate put
797 setglobal % bw bh px0 py0 bw bh
800 2 copy gt 6 index 6 index gt ne {
801 % a rotation is useful except it fits with no rotation.
802 1 index 5 index le 1 index 5 index le and not
810 1 index 5 index div 1 index 7 index div % bw bh px0 py0 pw ph sx sy
814 pop dup scale % bw bh px0 py0 pw ph
817 0 5 index neg translate
820 1 index 6 index div 1 index 6 index div % bw bh px0 py0 pw ph sx sy
824 pop dup scale % bw bh px0 py0 pw ph
827 pop pop % bw bh px0 py0
831 (SetupPageView end) =
835 /PageContentsDaemon % <id> <obj> <node> PageContentsDaemon <id> <obj>
836 { % Note: an excessive operand from a prebond procedure.
838 (Executing PageContentsDaemon for ) print 2 index =
840 1 index exch /Context exch put % id obj
841 dup /ImmediateExec true put
843 dup /Context get //SetupPageView exec
846 /FontFileDaemon % <id> <obj> <font_descriptor> FontFileDaemon <id> <obj>
847 { % Note: an excessive operand from a prebond procedure.
849 (Executing FontFileDaemon for ) print 2 index =
851 % We need any font resource that refers this descriptor
852 % to know the font type. Assuming that FontDescriptorDaemon
853 % provided FontFileType.
854 dup /FontFileType get % id obj fd ft
855 2 index exch % id obj fd obj ft
856 dup //ReadFontProcs exch //knownget exec { % id obj fd obj ft proc
857 exch pop exec % id obj fd
859 mark (FontFile reader for ) 2 index ( isn't implemented yet.) //error exec
862 (FontFileDaemon end) =
867 /FontDescriptorDaemon % <id> <obj> <font_resource> FontDescriptorDaemon <id> <obj>
868 { % Note: an excessive operand from a prebond procedure.
870 (Executing FontDescriptorDaemon for ) print 2 index =
872 %HACK BEG assuming an own font for each font descriptor
873 % to provide an access to PDFEncoding
874 % from MakeType42, ComposeCharStrings.
875 2 copy /FontResource exch put
877 /Subtype get 1 index exch /FontFileType exch put
880 /TypeDaemons << % <id> <obj> proc <id> <obj>
883 (Recognized a page.) =
885 dup /Contents //knownget exec { % id obj c
886 0 get //DoNothing exch % id obj dn id1
887 [ % <id> <obj> proc <id> <obj>
888 3 index //PageContentsDaemon /exec load
890 //Register exec % id obj
892 (fixme: page with no Contents won't be printed.) =
897 (Recognized a font descriptor.) =
900 dup dup /FontFile known {/FontFile} {/FontFile2} ifelse
901 //knownget exec { % id obj ff
902 0 get //DoNothing exch % id obj dn id1
903 [ % <id> <obj> proc <id> <obj>
904 3 index //FontFileDaemon /exec load
906 //Register exec % id obj
909 % FontFile3 are not implemented yet.
910 (Font descriptor ) print 1 index =only ( has no FontFile.) =
915 (Recognized a font resource.) =
917 dup /BaseFont //knownget exec {
918 % cache the installed font (if any) before replacing it.
919 //PDFReader /RemoveFontNamePrefix get exec
920 currentglobal exch % A hack against HP LaserJet 1320 bug :
921 % It sets the local allocation mode
922 % when 'resourcestatus' fails.
923 dup /Font resourcestatus {
925 //PDFReader /GetInstalledFont get exec pop
931 dup /FontDescriptor //knownget exec { % id obj fd
933 dup //IsRegistered exec { % id obj id1
935 (already registered ) print dup =
939 //DoNothing exch % id obj dn id1
940 [ % <id> <obj> proc <id> <obj>
941 3 index //FontDescriptorDaemon /exec load
943 //Register exec % id obj
949 /MakeStreamReader % <obj> MakeStreamReader <file>
986 ( end of stream proc.\n)
991 (Stream reader ) print dup ==
993 0 () /SubFileDecode filter
994 exch //AppendFilters exec
997 /RunDelayedStream % <stream_obj> RunDelayedStream -
999 //MakeStreamReader exec % file
1003 mark (Data left on ostack after a delayed stream execution.) //error exec
1008 % ===================== Font Management ======================
1010 //ReadFontProcs begin
1011 /Type1 % <font_descriptor> <FontFile_object> Type1 <font_descriptor>
1013 (ReadFontProcs.Type1) =
1015 dup /.endobj_daemon [ 4 index //HookFont /exec load ] cvx put
1016 dup /ImmediateExec true put
1017 /GlobalExec true put
1019 /MMType1 //Type1 def
1020 /TrueType % <font_descriptor> <FontFile_object> TrueType <font_descriptor>
1022 (ReadFontProcs.TrueType) =
1024 dup /.endobj_daemon [ 4 index //HookFont /exec load ] cvx put
1029 /MakeType42 % <FontFile_object> <font_descriptor> MakeType42 <FontFile_object> <font_descriptor> <font>
1035 /FontName 1 index /FontName get def
1037 /FontMatrix [1 0 0 1 0 0] def
1038 /FontBBox 1 index /FontBBox get def % fo fd
1039 dup /FontResource get % fo fd fr
1040 dup /Encoding known { % fo fd fr
1041 //PDFReader /ObtainEncoding get exec % fo fd fr
1042 /Encoding get % fo fd e
1046 /PDFEncoding exch def % fo fd
1047 /CharStrings 2 index //PDFReader /MakeTTCharStrings get exec def
1048 /sfnts [ 3 index //MakeStreamReader exec 65535 string readstring pop ] def
1049 /Encoding StandardEncoding def % A stub - will be replaced by font resource.
1057 /GetInstalledFont % <name> GetInstalledFont <font>
1058 { currentglobal exch true setglobal % g n
1059 dup //InstalledFonts exch knownget { % g n f
1062 dup findfont dup 3 1 roll % g f n f
1063 //InstalledFonts 3 1 roll put % g f
1068 /RemoveFontNamePrefix % <name> RemoveFontNamePrefix <name>
1069 { //=string cvs true
1071 2 index exch get //IsUpper exec not {
1082 /CheckFont % <key> <val> CheckFont <key> <val>
1083 { dup /Type get /Font ne {
1084 mark (Resource ) 3 index ( must have /Type/Font .) //error exec
1088 /CheckEncoding % <key> <val> CheckEncoding <key> <val>
1089 { dup type /nametype ne {
1090 dup /Type get /Encoding ne {
1091 mark (Resource ) 3 index ( must have /Type/Encoding .) //error exec
1096 /ObtainEncoding % <font_resource> ObtainEncoding <font_resource>
1097 { dup /Encoding known {
1098 dup dup /Encoding //CheckEncoding //ResolveD exec % fr fr er|e|n
1099 dup type dup /arraytype eq exch /packedarraytype eq or {
1103 dup type /nametype eq {
1104 /Encoding findresource % fr fr e
1106 dup /BaseEncoding //knownget exec not {
1109 /Encoding findresource % fr fr er e
1111 /Differences //knownget exec { % fr fr e d
1112 exch dup length array copy exch
1113 0 exch % fr fr e 0 d
1115 dup type /integertype eq {
1118 3 copy put pop % fr fr e i
1125 /Encoding exch put % fr
1128 dup /Encoding /StandardEncoding /Encoding findresource put
1132 /ObtainMetrics % <font_resource> ObtainMetrics <font_resource>
1133 { dup /Widths //knownget exec { % fr W
1134 1 index /Encoding get % fr W E
1136 3 index /Subtype get /TrueType eq {
1140 } ifelse % fr W E M s
1141 4 index /MissingWidth //knownget exec not {
1143 } if % fr W E M s mw
1144 5 index /FirstChar //knownget exec not {
1146 } if % fr W E M s mw c0
1147 6 5 roll % fr E M s mw c0 W
1148 dup 0 exch 1 exch length 1 sub { % fr E M s mw c0 W i
1149 2 copy get % fr E M s mw c0 W i w
1150 exch 3 index add % fr E M s mw c0 W w c
1151 7 index exch get % fr E M s mw c0 W w n
1153 6 index 3 1 roll exch % fr E M s mw c0 W M n w
1155 3 copy pop //knownget exec {
1160 { put % fr E M s mw c0 W
1168 pop pop pop pop exch pop % fr M
1169 1 index exch /Metrics exch put % fr
1171 dup /MissingWidth //knownget exec { % fr mw
1173 2 index /Encoding get { % fr mw M e
1175 3 copy 3 2 roll put % fr mw M e
1180 1 index exch /Metrics exch put % fr
1185 /NotDef % - NotDef -
1186 { % A Type 3 font is on dstack.
1187 FontMatrix aload pop pop pop exch pop exch pop % sx sy
1189 1 exch div exch % wx wy
1190 1 index 0 setcharwidth
1195 neg exch neg exch rlineto %
1199 /BuildChar % <font> <char_code> BuildChar -
1201 (BuildChar ) print dup //=only exec ( ) print
1204 Encoding exch get % n
1211 CharProcs exch //knownget exec { % cp_stream
1212 //RunDelayedStream exec
1220 /printdict % <dict> printdict -
1222 { exch = == } forall
1226 /printfont % <dict> printfont -
1233 dup /FontInfo eq exch /Private eq or {
1242 /ScaleMetrics % <Metrics> <scale> ScaleMetrics <Metrics>
1243 { 1 index { % M s n v
1244 2 index div % M s n v'
1245 3 index % M s n v' M
1251 /ResolveAndSetFontAux % <resource_name> <size> ResolveAndSetFont -
1252 { exch dup % s rn rn
1253 //PDFReader /CurrentObject get /Context get /Resources get
1254 /Font //DoNothing //ResolveD exec
1255 exch //CheckFont //ResolveD exec % s rn fr
1256 dup /Font //knownget exec { % s rn fr f
1260 dup /Subtype get dup dup /Type1 eq exch /TrueType eq or exch /MMType1 eq or {
1263 dup /BaseFont get % s fr n
1264 //RemoveFontNamePrefix exec % s fr n
1268 1 index /FontDescriptor known { % s fr n
1270 (Font from a font descriptor.) =
1273 /FontDescriptor //DoNothing //ResolveD exec % s fr n fd
1274 /Font //knownget exec {
1278 (Font descriptor has no Font resolved.) =
1280 //GetInstalledFont exec % s fr f
1283 //GetInstalledFont exec % s fr f
1286 dup /Encoding known not {
1287 1 index /Encoding get 1 index exch /Encoding exch put
1289 //ObtainEncoding exec
1290 //ObtainMetrics exec
1292 dup length dict copy % s fr f
1293 dup 2 index /Encoding get % s fr f f e
1294 /Encoding exch put % s fr f
1295 1 index /Metrics //knownget exec { % s fr f M
1296 2 index /Subtype get /TrueType ne {
1297 % Adjust Metrics for fonts converted from TrueTypes by 3d party.
1298 1 index /FontMatrix get 0 get 0.001 div
1301 1 index exch /Metrics exch put % s fr f
1303 1 index /BaseFont get % s fr f n
1308 dup 3 1 roll % s f fr f
1309 /Font exch put % s f
1312 dup /Subtype get /Type3 eq { % s rn fr
1313 //ObtainEncoding exec
1314 2 copy exch /FontName exch put
1315 dup /CharProcs get //ResolveDict exec
1317 dup /BuildChar //BuildChar put
1318 dup dup /Font exch put
1319 % Ignore Metrics because pdfwrite duplicates it
1320 % from setcharwidth/setcachedevice.
1321 dup 3 1 roll % s fr rn fr
1324 % The interpreter copied the font dictionary while 'definefont'
1325 % Need to update the font pointer in the resource.
1326 2 copy /Font exch put % s fr f
1331 dup /Subtype get /Type0 eq { % s rn fr
1333 dup /Subtype get /CIDFontType0 eq { % s rn fr
1335 dup /Subtype get /CIDFontType2 eq { % s rn fr
1337 mark (Unknown font type ) 2 index /Subtype get //error exec
1340 exch scalefont setfont %
1343 /ResolveAndSetFont % <resource_name> <size> ResolveAndSetFont -
1344 { currentglobal true setglobal 3 1 roll
1345 //ResolveAndSetFontAux exec
1350 % ================= Auxiliary procedures for True Type cmap Decoder =============
1371 % ===================== True Type cmap Decoder =============
1372 % The following procedures are copied from gs/lib/gs_ttf.ps with no change.
1374 % <string> <index> getu16 <integer>
1376 2 copy get 8 bitshift 3 1 roll 1 add get add
1379 % <string> <index> gets16 <integer>
1381 getu16 16#8000 xor 16#8000 sub
1384 % <string> <index> getu32 <integer>
1386 2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add
1389 % <string> <index> gets32 <integer>
1391 2 copy gets16 16 bitshift 3 1 roll 2 add getu16 add
1394 % Each procedure in this dictionary is called as follows:
1395 % <encodingtable> proc <glypharray>
1397 0 { % Apple standard 1-to-1 mapping.
1398 6 256 getinterval { } forall 256 packedarray
1400 2 { % Apple 16bit CJK (ShiftJIS etc)
1402 % /sHK_sz subHeaderKey_size % 1 * uint16
1403 % /sH_sz subHeader_size % 4 * uint16
1404 % /sH_len subHeader_length
1405 % /cmapf2_tblen total table length
1406 % /cmapf2_lang language code (not used)
1407 % /sHKs subHeaderKeys
1411 dup 2 getu16 /cmapf2_tblen exch def
1413 dup 4 getu16 /cmapf2_lang exch def
1415 dup 6 256 sHK_sz mul getinterval /sHKs exch def
1417 0 % initialization value for /sH_len
1421 1 index % get current max
1422 1 index % get current subHeaderKey
1427 dup 6 256 sHK_sz mul add
1428 cmapf2_tblen 1 index sub getinterval
1431 /cmapf2_glyph_array 65535 array def
1434 /cmapf2_ch cmapf2_ch_hi 8 bitshift cmapf2_ch_lo add def
1435 firstCode cmapf2_ch_lo le
1436 cmapf2_ch_lo firstCode entryCount add lt
1437 and { % true: j is inside
1438 sH_offset idRangeOffset add % offset to gI
1439 cmapf2_ch_lo firstCode sub 2 mul % rel. pos. in range
1440 add 6 add % offset in sH_gIA
1444 cmapf2_glyph_array exch cmapf2_ch exch put
1447 % cmapf2_glyph_array cmapf2_ch 0 put
1449 } { % false: j is outside
1450 % cmapf2_glyph_array cmapf2_ch 0 put
1454 16#00 1 16#ff { % hi_byte scan
1455 /cmapf2_ch_hi exch def
1456 sHKs cmapf2_ch_hi sHK_sz mul getu16
1458 sH_gIA sH_offset sH_sz getinterval
1459 dup 0 getu16 /firstCode exch def
1460 dup 2 getu16 /entryCount exch def
1461 dup 4 gets16 /idDelta exch def
1462 dup 6 getu16 /idRangeOffset exch def
1465 /cmapf2_ch_lo cmapf2_ch_hi def
1469 16#00 1 16#ff { % lo_byte scan
1470 /cmapf2_ch_lo exch def
1476 0 1 cmapf2_glyph_array length 1 sub { % rewrite null -> 0.
1477 dup cmapf2_glyph_array exch get
1478 null eq { cmapf2_glyph_array exch 0 put } {pop} ifelse
1482 4 { % Microsoft/Adobe segmented mapping.
1484 /nseg2 etab 6 getu16 def
1485 14 /endc etab 2 index nseg2 getinterval def
1486 % The Apple TrueType documentation omits the 2-byte
1487 % 'reserved pad' that follows the endCount vector!
1489 nseg2 add /startc etab 2 index nseg2 getinterval def
1490 nseg2 add /iddelta etab 2 index nseg2 getinterval def
1491 nseg2 add /idroff etab 2 index nseg2 getinterval def
1492 % The following hack allows us to properly handle
1493 % idiosyncratic fonts that start at 0xf000:
1495 /firstcode startc 0 getu16 16#ff00 and dup 16#f000 ne { pop 0 } if def
1497 glyphs code 3 -1 roll put /code code 1 add def
1499 % Do a first pass to compute the size of the glyphs array.
1500 /numcodes 0 def /glyphs 0 0 2 nseg2 3 sub {
1501 % Stack: /glyphs numglyphs i2
1503 /scode startc i2 getu16 def
1504 /ecode endc i2 getu16 def
1505 numcodes scode firstcode sub
1506 % Hack for fonts that have only 0x0000 and 0xf000 ranges
1507 %dup 16#e000 ge { 255 and } if
1508 % the previous line is obstructive to CJK fonts, so it was removed
1509 exch sub 0 .max ecode scode sub 1 add add
1510 exch 1 index add exch
1511 numcodes add /numcodes exch def
1513 % prefill the array with 0's faster than a { 0 putglyph } repeat
1514 glyphs length 1024 ge {
1515 .array1024z 0 1024 glyphs length 1023 sub { glyphs exch 2 index putinterval } for
1516 glyphs dup length 1024 sub 3 -1 roll
1519 0 1 glyphs length 1 sub { glyphs exch 0 put } for
1521 % Now fill in the array.
1522 /numcodes 0 def /code 0 def
1525 /scode startc i2 getu16 def
1526 /ecode endc i2 getu16 def
1527 numcodes scode firstcode sub
1528 % Hack for fonts that have only 0x0000 and 0xf000 ranges
1529 %dup 16#e000 ge { 255 and } if
1530 % the previous line is obstructive to CJK fonts, so it was removed
1531 exch sub 0 .max dup /code exch code exch add def
1532 ecode scode sub 1 add add numcodes add /numcodes exch def
1533 /delta iddelta i2 gets16 def
1535 (scode=) print scode =only
1536 ( ecode=) print ecode =only
1537 ( delta=) print delta =only
1538 ( droff=) print idroff i2 getu16 =
1540 idroff i2 getu16 dup 0 eq {
1541 pop scode delta add 65535 and 1 ecode delta add 65535 and
1543 } { % The +2 is for the 'reserved pad'.
1544 /gloff exch 14 nseg2 3 mul add 2 add i2 add add def
1545 0 1 ecode scode sub {
1546 2 mul gloff add etab exch getu16
1547 dup 0 ne { delta add 65535 and } if putglyph
1550 } for glyphs /glyphs null def % for GC
1552 6 { % Single interval lookup.
1553 dup 6 getu16 /firstcode exch def dup 8 getu16 /ng exch def
1554 firstcode ng add array
1556 % Fill elements 0 .. firstcode-1 with 0
1557 0 1 firstcode 1 sub { 2 copy 0 put pop } for
1558 dup firstcode ng getinterval
1559 % Stack: tab array subarray
1560 % Fill elements firstcode .. firstcode+nvalue-1 with glyph values
1562 dup 2 mul 10 add 4 index exch getu16 3 copy put pop pop
1565 .dicttomark readonly def % cmapformats
1567 % <cmaptab> cmaparray <glypharray>
1569 dup 0 getu16 cmapformats exch .knownget {
1571 (cmap: format ) print 1 index 0 getu16 = flush
1574 (Can't handle format ) print 0 getu16 = flush
1575 0 1 255 { } for 256 packedarray
1578 (cmap: length=) print dup length = dup ==
1582 % Define remapping for misnamed glyphs in TrueType 'post' tables.
1583 % There are probably a lot more than this!
1587 /Eoverdot /Edotaccent
1593 /eoverdot /edotaccent
1597 .dicttomark readonly def
1599 % Each procedure in this dictionary is called as follows:
1600 % posttable <<proc>> glyphencoding
1602 16#00010000 { % 258 standard Macintosh glyphs.
1603 pop MacGlyphEncoding
1605 16#00020000 { % Detailed map, required by Microsoft fonts.
1607 TTFDEBUG { (post format 2.0 invalid.) = flush } if
1610 /postglyphs exch def
1611 postglyphs 32 getu16 /numglyphs exch def
1612 /glyphnames numglyphs 2 mul 34 add def
1613 % Build names array in the order they occur in the 'post' table
1614 /postpos glyphnames def
1616 postpos postglyphs length ge { exit } if
1617 % No name available, /postnames will be defined as an empty
1618 % array and the glyph won't get a name attached.
1619 postglyphs postpos get
1620 postglyphs postpos 1 add 2 index getinterval cvn
1621 exch postpos add 1 add /postpos exch def
1623 ] /postnames exch def
1624 [ 0 1 numglyphs 1 sub {
1625 2 mul 34 add postglyphs exch getu16
1627 MacGlyphEncoding exch get
1630 % According to the published TrueType spec, such values are
1631 % "reserved for future use", but at least some PDF files
1632 % produced by the Adobe PDF library contain entries with a
1636 % Get the name for this glyph
1637 258 sub dup postnames length ge {
1638 TTFDEBUG { ( *** warning: glyph index past end of 'post' table) = flush } if
1642 % At least some of Microsoft's TrueType fonts use incorrect
1643 % (Adobe-incompatible) names for some glyphs.
1644 % Correct for this here.
1645 postremap 1 index .knownget { exch pop } if
1652 16#00030000 { % No map.
1655 .dicttomark readonly def % postformats
1658 % Uses post, defines glyphencoding
1660 /glyphencoding post null eq {
1661 TTFDEBUG { (post missing) = flush } if [ ]
1663 postformats post 0 getu32 .knownget {
1665 (post: format ) print
1666 post 0 getu16 =only (,) print post 2 getu16 = flush
1670 TTFDEBUG { (post: unknown format ) print post 0 getu32 = flush } if [ ]
1675 % ===================== True Type Interpretation =============
1682 /readu8 % <file> readu8 <int>
1684 mark (Insufficient data in the stream.) //error exec
1688 /readu16 % <file> readu16 <int>
1689 { dup //readu8 exec 8 bitshift exch //readu8 exec or
1692 /reads16 % <file> reads16 <int>
1693 { //readu16 exec 16#8000 xor 16#8000 sub
1696 /readu32 % <file> readu32 <int>
1697 { dup //readu16 exec 16 bitshift exch //readu16 exec or
1700 /reads32 % <file> reads32 <int>
1701 { dup //reads16 exec 16 bitshift exch //readu16 exec or
1704 /SkipToPosition % <file> <int> SkipToPosition -
1705 { dup //TTParser /Pos get % f P P p
1706 exch //TTParser exch /Pos exch put % f P p
1709 (Skipping ) print dup //=only exec ( bytes.) =
1714 //BlockBuffer exch 0 exch getinterval readstring not {
1715 mark (Insufficient data in the stream for SkipToPosition.) //error exec
1721 /TagBuffer 4 string def
1723 /ParseTTTableDirectory % <file> ParseTTTableDirectory <dict>
1725 (ParseTTTableDirectory beg) =
1728 dup //readu32 exec 16#00010000 ne {
1729 mark (Unknown True Type version.) //error exec
1731 dup //readu16 exec /NumTables exch def
1732 dup //readu16 exec /SearchRange exch def
1733 dup //readu16 exec /EntrySelector exch def
1734 dup //readu16 exec /RangeShift exch def
1736 (NumTables = ) print NumTables =
1739 dup //TagBuffer readstring not {
1740 mark (Could not read TT tag.) //error exec
1743 [ 2 index //readu32 exec pop % CheckSum
1744 2 index //readu32 exec % Offset
1745 3 index //readu32 exec % Length
1748 2 copy exch //=only exec ( ) print ==
1753 //TTParser /Pos 12 NumTables 16 mul add put
1756 (ParseTTTableDirectory end) =
1760 /ParseTTcmap % <file> <TableDirectory> ParseTTcmap <dict>
1764 /cmap get aload pop % f o L
1768 (Current position = ) print //TTParser /Pos get =
1769 (cmap position = ) print dup =
1771 1 index exch //SkipToPosition exec % L f
1772 //TTParser /Pos get /TablePos exch def
1773 dup //readu16 exec pop % version
1774 dup //readu16 exec /NumEncodings exch def
1776 (NumEncodings = ) print NumEncodings =
1780 1 index //readu32 exec % platformID, specificID % L f null id
1781 2 index //readu32 exec % offset % L f null id o
1782 3 array dup 3 2 roll 0 exch put % L f []|null id []
1784 dup 0 get 3 index 0 get sub % L f []|null id [] l
1785 3 index exch 1 exch put % L f []|null id []
1787 dup 4 3 roll pop 3 1 roll % L f [] id []
1790 dup 0 get % L f [] o
1791 4 3 roll exch sub % f [] L-o
1795 exch dup type /integertype eq {
1796 //PrintHex exec ( ) print ==
1802 4 NumEncodings 8 mul add /HeaderLength exch def
1803 //TTParser /Pos //TTParser /Pos get HeaderLength add put
1806 16#7FFFFFF null % f o om null|[]
1807 % Choosing a table with minimal offset greater than 'o' :
1809 1 index type /integertype eq { % f o om null|[] id []
1810 exch pop dup 0 get % f o om null|[] [] oi
1813 4 1 roll % f o oi om null|[] []
1814 exch pop exch pop % f o oi []
1820 } ifelse % f o oi []
1824 } forall % f o om' []
1826 (Obtaining subtable for ) print dup ==
1828 3 2 roll pop % f o' []
1829 3 copy pop % f o' [] f o'
1830 TablePos add //SkipToPosition exec % f o' []
1831 3 copy exch pop 1 get % f o' [] l
1832 //TTParser /Pos //TTParser /Pos get 3 index add put
1833 string % f o' [] f ()
1835 mark (Can't read a cmap subtable.) //error exec
1846 /GetTTEncoding % <file> <TTcmapHeader> <platformIDspecificID> GetTTEncoding <array>
1848 (GetTTEncoding beg) =
1853 10 dict begin % For local variables.
1854 /TTFDEBUG //PDFR_DEBUG def
1858 (GetTTEncoding end) =
1863 /InverseEncoding % <encoding> InverseEncoding <dict>
1866 dup length 1 sub -1 0 { % E i
1869 1 index currentdict exch //knownget exec { % E n i e
1870 dup type /arraytype eq {
1871 aload length 1 add array astore % E n e'
1873 2 array astore % E n e'
1882 /GetMacRomanEncodingInverse
1883 { //PDFReader /MacRomanEncodingInverse get
1886 MacRomanEncoding //InverseEncoding exec
1887 dup //PDFReader exch /MacRomanEncodingInverse exch put
1891 /PutCharStringSingle % <cmap_array> <glyph_name> <char_code> PutCharStringSingle <cmap_array>
1893 dup 3 index length lt { % cmap name code
1894 2 index exch get % cmap name glyphindex
1905 /PutCharString % <cmap_array> <glyph_name> <char_code> PutCharString <cmap_array>
1906 { 1 index type /nametype ne {
1907 mark (Bad charstring name) //error exec
1909 dup type /arraytype eq {
1911 3 copy //PutCharStringSingle exec % cmap name code cmap
1916 //PutCharStringSingle exec
1920 /ComposeCharStrings % <cmaparray> <dict> ComposeCharStrings <dict>
1923 (ComposeCharStrings beg) =
1925 1 index length 1 add dict begin % cmap d
1926 % fixme : the dict length estimation doesn't account 'post'.
1929 //TTParser /post get % d cmap [post]|null
1932 1 index length 1 sub -1 0 { % d [] cmap code
1933 dup 3 index exch get exch % d [] cmap name code
1941 exch pop exch % cmap d
1943 //PutCharString exec
1948 (ComposeCharStrings end) =
1952 /ParseTTpost % <file> <TableDirectory> ParseTTpost -
1953 { % Defines TTparser.post - an array,
1954 % which maps glyph indices to glyph names.
1958 /post get aload pop % f o L
1961 (Current position = ) print //TTParser /Pos get =
1962 (post position = ) print dup =
1964 1 index exch //SkipToPosition exec % L f
1965 //TTParser /Pos //TTParser /Pos get 4 index add put
1968 mark (Insufficient data in the stream for ParseTTpost.) //error exec
1970 1 dict begin % A bridge to the code from /gs/lib/gs_ttf.ps .
1973 //TTParser /post glyphencoding put
1981 /MakeTTCharStrings % <FontFile_object> MakeTTCharStrings <CharStrings>
1982 { //MakeStreamReader exec % f
1983 dup dup //ParseTTTableDirectory exec % f f d
1984 % Since the file isn't positionable,
1985 % we must pick up either 'post' or 'cmap' first.
1986 % Deside which one we do first :
1987 //TTParser /post null put
1988 dup /post //knownget exec {
1990 1 index /cmap get 0 get
1992 2 copy //ParseTTpost exec % f f d
1993 //ParseTTcmap exec % f ch
1995 2 copy //ParseTTcmap exec % f f d ch
1997 //ParseTTpost exec % f ch
2000 //ParseTTcmap exec % f ch
2003 dup 16#00030001 known {
2005 (Using the TT cmap encoding for Windows Unicode.) =
2007 16#00030001 //GetTTEncoding exec
2008 AdobeGlyphList //ComposeCharStrings exec
2011 dup 16#00010000 known {
2013 (Using the TT cmap encoding for Macintosh Roman.) =
2015 16#00010000 //GetTTEncoding exec
2016 PDFEncoding dup null eq {
2017 pop //GetMacRomanEncodingInverse exec
2019 //InverseEncoding exec
2021 //ComposeCharStrings exec
2024 dup 16#00030000 known {
2026 (Using the TT cmap encoding 3.0 - not sure why Ghostscript writes it since old versions.) =
2028 % Same algorithm as for 16#00010000.
2029 16#00030000 //GetTTEncoding exec
2030 PDFEncoding dup null eq {
2031 pop //GetMacRomanEncodingInverse exec
2033 //InverseEncoding exec
2035 //ComposeCharStrings exec
2038 mark (True Type cmap has no useful encodings.) //error exec
2044 dup type /nametype eq {
2057 % ===================== Functions ============================
2059 /ScaleVal % <value> <Range> ScaleVal <scaled_value>
2062 1 index sub % v r0 r1-r0
2066 /ScaleArg % <arg> <Domain> ScaleArg <scaled_arg>
2069 1 index sub % a d0 d1-d0
2070 3 1 roll % d1-d0 a d0
2071 sub exch div % (a-d0)/(d1-d0)
2074 /ScaleArgN % <arg1> ... <argN> <Domain> ScaleArg <scaled_arg1> ... <scaled_argN>
2076 dup length 2 sub -2 0 { % a1 ... an [] 2i
2077 2 % a1 ... an [] 2i 2
2078 2 index 3 1 roll getinterval % a1 ... an [] []
2079 3 2 roll % a1 ... [] [] an
2080 exch //ScaleArg exec % a1 ... [] an'
2081 1 index length 2 idiv 1 add 1 roll % an' a1 ... []
2082 } for % a1' ... an' []
2087 /ComputeFunction_10 % <scaled_arg> <sample_array> ComputeFunction_10 <result>
2088 { % Assuming a 1-argument 1-result function type 0.
2090 (ComputeFunction_10 beg ) print 1 index //=only exec ( stack=) print count =
2094 pop dup length 1 sub get % y
2096 1 index length 1 sub mul % [] x*(l-1)
2097 dup dup floor sub % [] x*(l-1) f
2101 3 1 roll floor cvi % f [] i
2102 2 getinterval % f []
2104 2 index mul 3 2 roll 1 exch sub 3 2 roll mul add % y1*f+(1-f)*y0
2108 (ComputeFunction_10 end ) print dup //=only exec ( stack=) print count =
2112 /ComputeFunction_n0 % <arg1> .... <argn> <sample_array> <n> ComputeFunction_n0 <result>
2113 { % Assuming a n-argument 1-result function type 0.
2115 (ComputeFunction_n0 beg N=) print dup //=only exec ( stack=) print count =
2120 dup 2 add -1 roll % a2 .... an [] n a1
2121 dup 3 index length 1 sub ge {
2122 pop 1 sub % a2 .... an [] n-1
2123 exch dup length 1 sub get exch
2124 //PDFReader /ComputeFunction_n0 get exec
2126 dup floor cvi dup % a2 .... an [] n a1 i i
2127 4 index exch get % a2 .... an [] n a1 i [i]
2128 3 index dup % a2 .... an [] n a1 i [i] n n
2129 5 add copy % a2 .... an [] n a1 i [i] n a2 .... an [] n a1 i [i] n
2130 6 2 roll % a2 .... an [] n a1 i [i] n a2 .... an [i] n [] n a1 i
2131 pop pop pop pop % a2 .... an [] n a1 i [i] n a2 .... an [i] n
2132 1 sub % a2 .... an [] n a1 i [i] n a2 .... an [i] n-1
2133 //PDFReader /ComputeFunction_n0 get exec % a2 .... an [] n a1 i [i] n v0
2134 3 2 roll pop % a2 .... an [] n a1 i n v0
2135 exch % a2 .... an [] n a1 i v0 n
2136 4 3 roll exch % a2 .... an [] n i v0 a1 n
2137 4 add 2 roll 1 add % v0 a1 a2 .... an [] n i+1
2138 3 2 roll exch get % v0 a1 a2 .... an n [i+1]
2139 exch 1 sub % v0 a1 a2 .... an [i+1] n-1
2140 //PDFReader /ComputeFunction_n0 get exec % v0 a1 v1
2141 1 index mul % v0 a1 v1*a1
2142 3 1 roll % v1*a1 v0 a1
2143 1 exch sub mul add % v1*a1+v0*(1-a1)
2147 (ComputeFunction_n0 end ) print dup //=only exec ( stack=) print count =
2151 /FunctionToProc_x01 % <function_dict> FunctionToProc_x01 <proc>
2152 { % Assuming a n-argument 1-result function type 0.
2153 % The stream is already converted to the array /Data.
2154 dup /Domain get exch
2155 dup /Data get 0 get exch
2159 { (function beg, stack =) print count //=only exec (\n) print } /exec load
2162 dup 1 gt { % a1 ... an Domain Data n
2163 { mark exch % a1 ... an Domain Data [ n
2164 3 add 2 roll % Data [ a1 ... an Domain
2165 //ScaleArgN exec % Data [ a1 ... an
2166 counttomark dup % Data [ a1 ... an n n
2167 3 add -2 roll % a1 ... an n Data [
2168 pop exch % a1 ... an Data n
2169 //ComputeFunction_n0 exec
2172 pop % a1 Domain Data
2173 3 1 /roll load //ScaleArg /exec load % Data a1s
2175 //ComputeFunction_10 /exec load
2178 (function end, stack =) /print load /count load //=only /exec load (\n) /print load
2182 (Made a procedure for the 1-result function :) =
2187 /FunctionProcDebugBeg % - FunctionProcDebugBeg -
2188 { (FunctionProcDebugBeg ) print count =
2191 /FunctionProcDebugEnd % - FunctionProcDebugEnd -
2192 { (FunctionProcDebugEnd ) print count =
2195 /FunctionToProc_x0n % <function_dict> <m> FunctionToProc_x0n <proc>
2196 { % Assuming a n-argument m-result function type 0.
2197 % The stream is already converted to the array /Data.
2199 % Making the procedure : { Domain //ScaleArg exec ... n copy {} exec n+1 1 roll ... }
2200 % except "n copy" for the last chunk.
2203 (FunctionToProc_x0n beg m=) print dup =
2205 1 index /Size get length exch % f n m
2206 dup 7 mul 2 add array % f n m []
2208 dup 0 //FunctionProcDebugBeg put
2210 dup 0 //DoNothing put
2212 dup 1 /exec load put
2213 dup 2 5 index /Domain get put
2215 dup 3 //ScaleArg put
2217 dup 3 //ScaleArgN put
2219 dup 4 /exec load put
2220 1 index 1 sub 0 exch 1 exch { % f n m [] i
2221 dup 7 mul 5 add % f n m [] i i1
2222 1 index 4 index 1 sub ne {
2223 dup 3 index exch 6 index put 1 add
2224 dup 3 index exch /copy load put 1 add
2227 6 index /Data get 3 index get % f n m [] i i1 [ di
2229 //ComputeFunction_10 /exec load
2232 //ComputeFunction_n0 /exec load
2234 ] cvx % f n m [] i i1 {}
2235 3 index exch 2 index exch put 1 add % f n m [] i i1
2236 2 index 1 index /exec load put 1 add
2237 1 index 4 index 1 sub ne {
2238 2 index 1 index 6 index 1 add put 1 add
2239 2 index 1 index 1 put 1 add
2240 2 index 1 index /roll load put % f n m [] i i1
2245 dup dup length 2 sub //FunctionProcDebugEnd put
2247 dup dup length 2 sub //DoNothing put
2249 dup dup length 1 sub /exec load put
2250 cvx exch pop exch pop exch pop
2252 (Made a procedure for the n-argument function :) =
2256 (FunctionToProc_x0n end) =
2260 /MakeTableRec % <func_obj> <n> MakeTableRec <array>
2262 0 % to be bound below
2266 /MakeTable % <func_obj> <n> MakeTable <array>
2268 (MakeTable beg ) print count =
2270 1 index /Size get exch % f S N
2276 exch pop exch pop % []
2278 dup length 1 sub -1 0 { % f n [] i
2279 3 index 3 index //MakeTableRec exec % f n [] i []
2280 2 index 3 1 roll put % f n []
2285 (MakeTable end ) print count =
2289 //MakeTableRec 0 //MakeTable put
2291 /StoreSample % <value> <table> <dimensions> StoreSample -
2292 { % The reader is on the dictionary stack.
2298 I exch get get % v T[I[i]]
2301 I 0 get 3 2 roll put
2304 /ReadSample32 % - ReadSample32 <value>
2308 mark (Insufficient data for function.) //error exec
2311 pop % Ignore the last byte because it can't fit into 'real'.
2313 256 mul add 256 mul add
2314 //1_24_bitshift_1_sub div
2317 /ReadSample % - ReadSample <value>
2318 { % The reader in on the dictionary stack.
2319 Buffer BitsLeft BitsPerSample
2325 256 mul File read not {
2326 mark (Insufficient data for function.) //error exec
2331 sub dup % b bl-bps bl-bps
2332 2 index exch % b bl-bps b bl-bps
2333 neg bitshift % b bl-bps v
2334 2 copy exch bitshift % b bl-bps v v<<(bl-bps)
2335 4 3 roll exch sub % bl-bps v b-(v<<(bl-bps))
2336 /Buffer exch def % bl-bps v
2337 exch /BitsLeft exch def % v
2338 Div div % v/(1<<pbs-1)
2341 /ReadSamplesRec % <dimensions> ReadSamplesRec -
2342 { 0 % Will be bound below
2346 /ReadSamples % <dimensions> ReadSamples -
2347 { % The reader in on the dictionary stack.
2349 (ReadSamples beg ) print count =
2353 0 1 Size 0 get 1 sub {
2356 dup Range exch 2 mul 2 getinterval % m r
2358 (Will read a sample ... ) print
2360 BitsPerSample 32 eq { //ReadSample32 } { //ReadSample } ifelse
2361 exec exch //ScaleVal exec % m v
2363 (value=) print dup =
2365 exch Table exch get % v []
2366 Size length //StoreSample exec %
2371 dup Size exch get 0 exch 1 exch 1 sub { % d-1 i
2372 I exch 2 index exch put % d-1
2373 dup //ReadSamplesRec exec % d-1
2378 (ReadSamples end ) print count =
2382 //ReadSamplesRec 0 //ReadSamples put
2384 /StreamToArray % <obj> StreamToArray -
2386 (StreamToArray beg ) print count =
2388 currentglobal true setglobal exch
2389 userdict /FuncDataReader get begin % g f
2390 dup /BitsPerSample get /BitsPerSample exch def
2391 dup /Size get length /N exch def
2392 dup /Range get length 2 idiv /M exch def
2393 1 BitsPerSample bitshift 1 sub /Div exch def
2396 dup /Size get /Size exch def % g f
2397 dup /Range get /Range exch def % g f
2398 /File 1 index //MakeStreamReader exec def % g f
2399 /I [ N { 0 } repeat ] def % g f
2401 dup length 1 sub -1 0 { % g f [] m
2402 2 index N //MakeTable exec % g f [] m T
2403 2 index 3 1 roll put % g f []
2405 /Table exch def % g f
2406 N //ReadSamples exec % g f
2408 (Table = ) print Table ==
2414 (StreamToArray end ) print count =
2418 /FunctionToProc10 % <function_dict> FunctionToProc10 <proc>
2419 { % Assuming a 1-argument function type 0.
2421 (FunctionToProc10 beg, Range = ) print dup /Range get ==
2423 dup /Order //knownget exec {
2425 (Underimplemented function Type 0 Order 3.) =
2428 dup //StreamToArray exec % f
2429 dup /Range get length dup 2 eq {
2430 pop //FunctionToProc_x01 exec % proc
2432 2 idiv //FunctionToProc_x0n exec % proc
2435 (FunctionToProc10 end) =
2439 /FunctionToProc12 % <function_dict> FunctionToProc12 <proc>
2441 currentdict /C0 //knownget exec { length 1 eq } { true } ifelse {
2443 currentdict /C0 //knownget exec {
2448 currentdict /C1 //knownget exec {
2456 4 2 roll % c0 c1-c0 x n
2462 0 1 C0 length 1 sub {
2464 C0 2 index get % [ ... i n c0
2465 C1 3 index get % [ ... i n c0 c1
2466 4 3 roll pop % [ ... n c0 c1
2467 1 index sub % [ ... n c0 c1-c0
2468 [ /dup load % [ ... n c0 c1-c0 [ dup
2469 5 2 roll % [ ... [ dup n c0 c1-c0
2471 4 2 roll % x c0 c1-c0 x n
2483 (FunctionType2Proc : ) print dup ==
2488 /FunctionToProc14 % <function_dict> FunctionToProc14 <proc>
2489 { //MakeStreamReader exec cvx exec
2491 (FunctionType4Proc : ) print dup ==
2495 /FunctionToProc1 % <function_dict> FunctionToProc <proc>
2496 { % Assuming a 1-argument function.
2497 dup /FunctionType get
2499 pop //FunctionToProc10 exec exit
2502 pop //FunctionToProc12 exec exit
2505 pop //FunctionToProc14 exec exit
2507 mark exch (Function type ) exch ( isn't implemented yet.) //error exec
2511 /FunctionToProc20 % <function_dict> FunctionToProc20 <proc>
2512 { % Assuming a 2-argument function type 0.
2514 (FunctionToProc20, Range = ) print dup /Range get ==
2516 dup /Order //knownget exec {
2518 (Underimplemented function Type 0 Order 3.) =
2521 dup //StreamToArray exec % f
2522 dup /Range get length dup 2 eq {
2523 pop //FunctionToProc_x01 exec % proc
2525 2 idiv //FunctionToProc_x0n exec % proc
2529 /FunctionToProc % <function_dict> FunctionToProc <proc>
2531 (FunctionToProc beg ) print count =
2533 dup /Domain get length 2 idiv
2536 pop //FunctionToProc1 exec exit
2539 pop //FunctionToProc20 exec exit
2541 mark (Functions with many arguments aren't implemented yet.) //error exec
2544 (FunctionToProc end ) print count =
2548 /spotfunctions mark % Copied from pdf_draw.ps
2550 abs exch abs 2 copy add 1 le {
2551 dup mul exch dup mul add 1 exch sub
2553 1 sub dup mul exch 1 sub dup mul add 1 sub
2557 abs exch abs 2 copy add .75 le {
2558 dup mul exch dup mul add 1 exch sub
2560 2 copy add 1.23 le {
2561 .85 mul add 1 exch sub
2563 1 sub dup mul exch 1 sub dup mul add 1 sub
2568 abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
2569 pop dup mul exch .75 div dup mul add 4 div 1 exch sub
2572 pop 1 exch sub dup mul exch 1 exch sub
2573 .75 div dup mul add 4 div 1 sub
2575 .5 exch sub exch pop exch pop
2579 /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
2580 /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
2581 /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
2582 /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
2583 /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
2584 /Line { exch pop abs neg }
2587 /Square { abs exch abs 2 copy lt { exch } if pop neg }
2588 /Cross { abs exch abs 2 copy gt { exch } if pop neg }
2589 /Rhomboid { abs exch abs 0.9 mul add 2 div }
2590 /DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
2591 /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
2592 /SimpleDot { dup mul exch dup mul add 1 exch sub }
2593 /InvertedSimpleDot { dup mul exch dup mul add 1 sub }
2594 /CosineDot { 180 mul cos exch 180 mul cos add 2 div }
2595 /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
2597 exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
2599 .dicttomark readonly def
2601 % ===================== Color Spaces and Colors ==============
2603 /CheckColorSpace % <key> <val> CheckColorSpace <key> <val>
2605 dup type /arraytype ne {
2606 mark (Resource ) 3 index ( must be an array.) //error exec
2610 /SubstitutePDFColorSpaceRec % <array> SubstitutePDFColorSpace <array>
2611 { 0 % Will be bound below
2615 /SubstitutePDFColorSpace % <array> SubstitutePDFColorSpace <array>
2616 { currentglobal true setglobal exch
2618 dup 0 get /Pattern eq {
2620 dup dup 1 //CheckColorSpace //ResolveA exec
2621 dup type /nametype ne {
2622 //SubstitutePDFColorSpaceRec exec
2628 dup 0 get /Indexed eq {
2631 dup 0 get /Separation eq {
2632 dup dup 2 //CheckColorSpace //ResolveA exec
2633 dup type /nametype ne {
2634 //SubstitutePDFColorSpaceRec exec
2639 dup 0 get /CalGray eq {
2641 dup /Gamma //knownget exec {
2642 [ exch /exp load ] cvx
2643 1 index exch /DecodeLMN exch put
2645 [ exch /CIEBasedA exch ] % []
2648 dup 0 get /CalRGB eq {
2650 dup /Matrix //knownget exec {
2651 1 index exch /MatrixLMN exch put
2653 dup /Gamma //knownget exec {
2655 [ exch /exp load ] cvx
2657 [ exch /exp load ] cvx
2659 [ exch /exp load ] cvx
2662 1 index exch /DecodeLMN exch put
2664 [ exch /CIEBasedABC exch ] % []
2670 currentdict /Range //knownget exec { aload pop } { -100 100 -100 100 } ifelse
2671 0 100 6 2 roll 6 array astore
2673 /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind] def
2674 /MatrixABC [1 1 1 1 0 0 0 0 -1] def
2675 { dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse }
2677 % Store white point implicitly inside procedures.
2678 [ 3 index aload pop WhitePoint 0 get /mul load ] cvx
2679 [ 4 index aload pop WhitePoint 1 get /mul load ] cvx
2680 [ 5 index aload pop WhitePoint 2 get /mul load ] cvx
2683 (Constructed from Lab <<) =
2684 currentdict { exch = == } forall
2687 [ /CIEBasedABC currentdict ] % []
2692 mark exch (Unimplemented color space ) exch //error exec
2697 //SubstitutePDFColorSpaceRec 0 //SubstitutePDFColorSpace put
2699 /ResolveArrayElement % <array> <index> ResolveArrayElement <array>
2700 { 2 copy get xcheck {
2702 2 index 4 1 roll put
2708 /ResolveColorSpaceArrayRec % <color_space> ResolveColorSpaceArrayRec <color_space>
2709 { 0 % Will be bond below.
2713 /SetColorSpaceSafe % <color_space> SetColorSpaceSafe -
2715 % This works against applying a pattern over a pattern space,
2716 % which may happen due to duplication of stroking and non-stroking colors.
2717 % gs3.70 fails when setting a pattern space and
2718 % the (old) current color space is a pattern space.
2720 % If the new color space is an array and it appears equal to the old one,
2721 % do nothing. Otherwise set the new color space.
2723 (SetColorSpaceSafe beg) =
2725 currentcolorspace dup type /arraytype eq { % cs cs'
2726 1 index type /arraytype eq {
2727 dup length 2 index length eq {
2728 false exch % cs b cs'
2729 dup length 0 exch 1 exch 1 sub { % cs b cs' i
2731 4 index exch get exch % cs b cs' csi i
2732 2 index exch get % cs b cs' csi cs'i
2734 exch pop true exch exit
2753 (SetColorSpaceSafe end) =
2757 /ResolveColorSpaceArray % <color_space> ResolveColorSpaceArray <color_space>
2760 (ResolveColorSpaceArray beg ) print dup ==
2762 currentglobal true setglobal exch
2763 dup 0 get /Indexed eq {
2764 1 //ResolveArrayElement exec
2766 dup type /arraytype eq {
2767 //SubstitutePDFColorSpace exec
2768 //ResolveColorSpaceArrayRec exec
2774 dup 0 get /Separation eq {
2775 3 //ResolveArrayElement exec
2776 dup 3 get //FunctionToProc exec
2781 (Construcrted color space :) =
2786 (ResolveColorSpaceArray end ) print dup ==
2790 //ResolveColorSpaceArrayRec 0 //ResolveColorSpaceArray put
2792 /ResolveColorSpace % <name> ResolveColorSpace <color_space>
2795 (ResolveColorSpace beg ) print dup =
2797 dup //SimpleColorSpaceNames exch known not {
2798 dup //PDFColorSpaces exch //knownget exec {
2801 (ResolveColorSpace known ) =
2805 //PDFReader /CurrentObject get /Context get /Resources get
2806 /ColorSpace //DoNothing //ResolveD exec
2807 exch //CheckColorSpace //ResolveD exec % n cs
2808 dup type /arraytype eq {
2809 //SubstitutePDFColorSpace exec
2810 //ResolveColorSpaceArray exec
2811 dup //PDFColorSpaces 4 2 roll put % []
2816 (ResolveColorSpace end ) print dup ==
2820 /CheckPattern % <key> <val> CheckPattern <key> <val>
2822 dup /PatternType //knownget exec {
2824 mark (Resource ) 4 index ( is a shading, which can't be handled at level 2. ) //error exec
2828 dup /Type get /Pattern ne {
2829 mark (Resource ) 4 index ( must have /Type/Pattern .) //error exec
2834 { /Context get % pattern_object
2835 //RunDelayedStream exec
2838 /ResolvePattern % <name> ResolvePattern <pattern>
2841 % Since makepattern makes a local dictionary,
2842 % we cahche them in userdict, which is in local VM.
2843 % Assuming unique resource name through the document
2844 userdict /PDFR_Patterns get % n n d
2845 exch //knownget exec { % n p
2849 //PDFReader /CurrentObject get /Context get /Resources get
2850 /Pattern //DoNothing //ResolveD exec
2851 exch //CheckPattern //ResolveD exec % n o
2852 dup dup /Context exch put
2853 dup /Resources //DoNothing //ResolveD exec pop
2854 dup /PaintProc //PaintProc put
2855 gsave userdict /PDFR_InitialGS get setgstate
2856 currentglobal exch false setglobal % gs3_70 compatibility
2859 exch setglobal % gs3_70 compatibility
2861 dup userdict /PDFR_Patterns get % n p p d
2867 /SetColor % Same arguments and result as for scn
2871 currentcolorspace dup type /nametype eq {
2875 //ResolvePattern exec setpattern
2885 % ===================== Images ===============================
2887 /ImageKeys 15 dict begin
2888 /BPC /BitsPerComponent def
2891 /DP /DecodeParms def
2895 % /Intent is undefined - pdfwrite must take care of.
2898 currentdict end readonly def
2900 /ImageValues 15 dict begin
2903 /CMYK /DeviceCMYK def
2905 /AHx /ASCIIHexDecode def
2906 /A85 /ASCII85Decode def
2908 /Fl /FlateDecode def
2909 /RL /RunLengthDecode def
2910 /CCF /CCITTFaxDecode def
2912 currentdict end readonly def
2915 { 2 index /ColorSpace get
2916 dup type /arraytype eq {
2919 exch //knownget exec {
2924 /DecodeArrays 15 dict begin
2925 /DeviceGray { [0 1] } def
2926 /DeviceRGB { [0 1 0 1 0 1] } def
2927 /DeviceCMYK { [0 1 0 1 0 1 0 1] } def
2928 /Indexed { dup /ColorSpace get 2 get [ exch 0 exch ] } def
2929 /Separation { [0 1] } def
2930 /CIEBasedA { [0 1] /RangeA //GetColorSpaceRange exec } def
2931 /CIEBasedABC { [0 1 0 1 0 1] /RangeABC //GetColorSpaceRange exec } def
2932 currentdict end readonly def
2934 /Substitute % <key> <dict> Substitute <key>
2935 { 1 index //knownget exec {
2940 /DebugImagePrinting % <image_dict> DebugImagePrinting <image_dict>
2944 dup { exch //=only exec ( ) print ==
2949 /CompleteImage % <dict> CompleteImage <image_dict>
2951 dup /ColorSpace known {
2952 dup /ColorSpace //CheckColorSpace //ResolveD exec pop
2954 dup /Decode known not {
2955 dup /ColorSpace //knownget exec {
2956 dup type /arraytype eq {
2959 //DecodeArrays exch get exec
2963 1 index exch /Decode exch put
2965 dup /ImageMatrix [2 index /Width get 0 0 5 index /Height get neg
2966 0 7 index /Height get] put % Not sure why upside down ?
2967 //DebugImagePrinting exec
2970 /CompleteInlineImage % <dict> CompleteInlineImage <image_dict>
2973 (CompleteInlineImage beg) =
2975 dup /ImageType known not {
2976 dup /ImageType 1 put
2978 dup length dict exch { % d key val
2979 exch //ImageKeys //Substitute exec
2981 exch //ImageValues //Substitute exec exch
2983 dup /ColorSpace eq {
2985 dup //ImageValues exch //knownget exec {
2988 //ResolveColorSpace exec
2993 2 index 3 1 roll put
2995 //CompleteImage exec
2996 dup /DataSource 2 copy get % d d /n f
2997 2 index //AppendFilters exec put
2999 (CompleteInlineImage end) =
3003 /CompleteOutlineImage % <dict> CompleteOutlineImage <image_dict>
3005 currentglobal exch dup gcheck setglobal
3007 (CompleteOutlineImage beg) =
3009 % todo: ResetStreamReader if DataSource already exists.
3010 dup dup //MakeStreamReader exec /DataSource exch put
3011 dup /ImageType known not {
3012 //CompleteImage exec
3013 dup /ImageType 1 put
3014 dup /ColorSpace known {
3015 dup /ColorSpace //CheckColorSpace //ResolveD exec
3016 dup type /arraytype eq {
3017 //ResolveColorSpaceArray exec
3018 //SubstitutePDFColorSpace exec
3019 1 index exch /ColorSpace exch put
3026 (CompleteOutlineImage end) =
3031 /DoImage % <image_dict> DoImage -
3037 dup /ColorSpace //knownget exec { setcolorspace } if
3038 dup /ImageMask //knownget exec not { false } if
3039 { imagemask } { image } ifelse
3046 % ===================== Viewer State ===============
3051 //PDFReader /GraphicStateStackPointer get
3052 dup //GraphicStateStack exch get null eq {
3053 currentglobal true setglobal exch
3054 dup //GraphicStateStack exch //InitialGraphicState length dict put
3057 dup //GraphicStateStack exch get
3058 //GraphicState exch copy pop
3059 1 add //PDFReader exch /GraphicStateStackPointer exch put
3062 /GRestore % - GRestore -
3065 //PDFReader /GraphicStateStackPointer get
3067 //PDFReader exch /GraphicStateStackPointer exch put
3068 //GraphicStateStack exch get
3069 //GraphicState copy pop
3073 % ===================== Interpret Data Streams ===============
3075 /SetFont % <resource_name> <size> SetFont -
3076 { dup //GraphicState exch /FontSize exch put
3077 //ResolveAndSetFont exec
3080 /ShowText % <string> ShowText -
3081 { //GraphicState /TextRenderingMode get 0 eq {
3082 //GraphicState /WordSpacing get 0
3084 //GraphicState /CharacterSpacing get 0
3087 //GraphicState /CharacterSpacing get 0 eq
3088 //GraphicState /WordSpacing get 0 eq and {
3091 % Emulate with "{ charpath } cshow".
3092 % Not sure how it works with CID fonts.
3094 currentpoint 5 4 roll % wx wy x y c
3095 ( ) dup 0 3 index put true charpath % wx wy x y c
3096 5 1 roll % c wx wy x y
3098 //GraphicState /CharacterSpacing get 0 rmoveto % c
3100 //GraphicState /WordSpacing get 0 rmoveto
3108 /ShowTextBeg % - ShowTextBeg -
3109 { //GraphicState /TextRenderingMode get 0 ne {
3110 currentpoint newpath moveto
3114 /ShowTextEnd % - ShowTextEnd -
3115 { //GraphicState /TextRenderingMode get
3120 gsave fill grestore stroke exit
3123 currentpoint newpath moveto
3126 gsave fill grestore clip exit
3129 gsave stroke grestore clip exit
3132 gsave fill grestore gsave stroke grestore fill exit
3142 /ShowTextWithGlyphPositioning % <array> ShowTextWithGlyphPositioning -
3143 { //ShowTextBeg exec
3144 { dup type /stringtype eq {
3147 neg 1000 div //GraphicState /FontSize get mul 0 rmoveto
3153 /CheckFont % key val CheckFont key val
3154 { dup /Type get /ExtGState ne {
3155 mark (Resource ) 3 index ( must have /Type/ExtGState.) //error exec
3159 /SetTransfer % <operand> SetTransfer -
3161 //PDFR_DEBUG { (SetTransfer beg ) print count = } if
3162 dup type /arraytype eq 1 index xcheck not and {
3163 0 4 getinterval aload pop
3168 //PDFR_DEBUG { (SetTransfer end ) print count = } if
3171 /CheckExtGState % <id> <obj> CheckExtGState <id> <obj>
3172 { dup /Type get /ExtGState ne {
3173 mark (Resource ) 3 index ( must have /Type/ExtGState.) //error exec
3177 /CheckHalftone % <id> <obj> CheckHalftone <id> <obj>
3178 { dup /HalftoneType known not {
3179 mark (Resource ) 3 index ( must have /HalftoneType.) //error exec
3183 /ResolveFunction % <dict> <name> ResolveFunction <dict> <proc>
3185 //PDFR_DEBUG { (ResolveFunction beg ) print dup = count = } if
3186 2 copy get //IsObjRef exec {
3187 2 copy //DoNothing //ResolveD exec
3190 2 copy get dup type /arraytype eq exch xcheck and not {
3192 dup type /arraytype eq 1 index xcheck not and {
3193 dup length 1 sub -1 0 {
3194 2 copy //DoNothing ResolveA
3198 //FunctionToProc exec
3205 % Leave it. ExtGState methods will resolve.
3209 } { dup type /nametype eq {
3210 //spotfunctions exch get
3212 //FunctionToProc exec
3222 //PDFR_DEBUG { (ResolveFunction end ) print dup == count = } if
3225 /ResolveFunctionSafe % <dict> <name> ResolveFunctionSafe <dict>
3227 //ResolveFunction exec
3232 /CreateHalftoneThresholds % <halftone_dict> CreateHalftoneThresholds <halftone_dict>
3234 dup /Thresholds known not {
3235 dup /HalftoneType get 10 eq {
3236 dup dup //MakeStreamReader exec
3237 /Thresholds exch put
3239 dup /HalftoneType get dup 3 eq exch 6 eq or {
3240 dup dup //MakeStreamReader exec
3241 //BlockBuffer readstring pop
3244 mark (Could not read Thresholds) //error exec
3246 string copy /Thresholds exch put
3247 dup /HalftoneType 3 put % replace Type 6 with Type 3.
3253 /SetExtGState % <name> SetExtGState -
3255 //PDFReader /CurrentObject get /Context get /Resources get
3256 /ExtGState //DoNothing //ResolveD exec
3257 exch //CheckExtGState //ResolveD exec % s gs
3258 dup /LW //knownget exec {
3261 dup /LC //knownget exec {
3264 dup /LJ //knownget exec {
3267 dup /ML //knownget exec {
3270 dup /D //knownget exec {
3273 dup /RI //knownget exec {
3274 % Ghostscript never writes it.
3275 mark (Unimplemented ExtGState.RI) //error exec
3277 dup /OP //knownget exec {
3278 % pdfwrite must take care of stroking/filling
3281 dup /op //knownget exec {
3284 dup /OPM //knownget exec {
3285 % pdfwrite must take care of.
3286 mark (Unimplemented ExtGState.OPM) //error exec
3288 dup /Font //knownget exec {
3289 % Ghostscript never writes it.
3290 mark (Unimplemented ExtGState.Font) //error exec
3293 /BG //ResolveFunction exec
3297 /BG2 //ResolveFunction exec
3299 //InitialExtGState /BG2 get
3304 /UCR //ResolveFunction exec
3305 setundercolorremoval
3308 /UCR2 //ResolveFunction exec
3310 //InitialExtGState /UCR2 get
3312 setundercolorremoval
3315 /TR //ResolveFunction exec
3319 /TR2 //ResolveFunction exec
3321 pop //InitialExtGState /TR2 get
3322 aload pop setcolortransfer
3327 dup /HT //knownget exec {
3329 pop //InitialExtGState /HT get
3332 //PDFR_DEBUG { (Ht beg) = } if
3333 pop dup /HT //CheckHalftone //ResolveD exec
3334 /SpotFunction //ResolveFunctionSafe exec
3335 /TransferFunction //ResolveFunctionSafe exec
3337 dup /HalftoneType get dup 5 eq exch dup 4 eq exch 2 eq or or {
3339 dup //IsObjRef exec {
3341 1 index exch //CheckHalftone ResolveD
3343 dup type /dicttype eq {
3344 dup /SpotFunction //ResolveFunctionSafe exec
3345 /TransferFunction //ResolveFunctionSafe exec
3346 //CreateHalftoneThresholds exec
3347 dup /HalftoneType get 5 gt { % null h n v
3355 //CreateHalftoneThresholds exec
3359 1 index /Default eq {
3362 { exch = == } forall
3371 (Warning: Ignoring a halftone with a Level 3 component halftone Type ) print dup /HalftoneType get =
3375 dup /HalftoneType get 5 gt {
3376 (Warning: Ignoring a Level 3 halftone Type ) print dup /HalftoneType get =
3382 //PDFR_DEBUG { (HT set)= flush } if
3385 dup /FL //knownget exec {
3388 dup /SM //knownget exec {
3391 dup /SA //knownget exec {
3394 dup /BM //knownget exec {
3395 % pdfwrite must take care of.
3396 mark (Unimplemented ExtGState.BM) //error exec
3398 dup /SMask //knownget exec {
3399 % pdfwrite must take care of.
3400 mark (Unimplemented ExtGState.SMask) //error exec
3402 dup /CA //knownget exec {
3403 % pdfwrite must take care of.
3404 mark (Unimplemented ExtGState.CA) //error exec
3406 dup /ca //knownget exec {
3407 % pdfwrite must take care of.
3408 mark (Unimplemented ExtGState.ca) //error exec
3410 dup /AIS //knownget exec {
3411 % pdfwrite must take care of.
3412 mark (Unimplemented ExtGState.AIS) //error exec
3414 dup /TK //knownget exec {
3415 % pdfwrite must take care of.
3416 mark (Unimplemented ExtGState.TK) //error exec
3421 /CheckXObject % <id> <obj> CheckHalftone <id> <obj>
3422 { dup /Subtype get dup /Image ne exch dup /Form ne exch /PS ne and and {
3423 mark (Resource ) 3 index ( must have /Subtype /Image or /Form or /PS.) //error exec
3427 /DoXObject % <name> DoXObject -
3429 //PDFReader /CurrentObject get /Context get /Resources get
3430 /XObject //DoNothing //ResolveD exec
3431 exch //CheckXObject //ResolveD exec
3435 //CompleteOutlineImage exec
3440 (Executing a PS Xobject) =
3443 //RunDelayedStream exec
3448 (Executing a Form XObject) =
3450 //PDFReader /CurrentObject get exch
3451 dup //PDFReader exch << exch /Context exch >> /CurrentObject exch put
3452 dup /Matrix get concat
3453 dup /BBox get aload pop exch 3 index sub exch 2 index sub rectclip
3454 //RunDelayedStream exec
3455 //PDFReader exch /CurrentObject exch put
3457 mark exch (unimplemented XObject type ) exch //error exec
3463 /Operators 50 dict begin
3464 /q { //GSave exec } bind def
3465 /Q { //GRestore exec } bind def
3466 /cm { //TempMatrix astore concat } bind def
3467 /i { 1 .min setflat } bind def
3468 /J /setlinecap load def
3469 /d /setdash load def
3470 /j /setlinejoin load def
3471 /w /setlinewidth load def
3472 /M /setmiterlimit load def
3473 /gs { SetExtGState } bind def
3475 /g /setgray load def
3476 /rg /setrgbcolor load def
3477 /k /setcmykcolor load def
3478 /cs { //ResolveColorSpace exec //SetColorSpaceSafe exec
3480 /sc /setcolor load def
3481 /scn { //SetColor exec } bind def
3482 /G /setgray load def
3483 /RG /setrgbcolor load def
3484 /K /setcmykcolor load def
3486 /ri { SetColorRenderingIntent } bind def
3487 /SC /setcolor load def
3488 /SCN { //SetColor exec } bind def
3492 /c /curveto load def
3493 /v { currentpoint 6 2 roll curveto } bind def
3494 /y { 2 copy curveto } bind def
3496 4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto
3499 /h /closepath load def
3500 /n /newpath load def
3502 /s { closepath stroke } bind def
3504 /f* /eofill load def
3505 /B { gsave fill grestore stroke } bind def
3506 /b { closepath gsave fill grestore stroke } bind def
3507 /B* { gsave eofill grestore stroke } bind def
3508 /b* { closepath gsave eofill grestore stroke } bind def
3510 /W* /eoclip load def
3511 /sh { % Reserved for ps3write.
3513 dup /Background known {
3515 dup /ColorSpace get setcolorspace
3516 dup /Background get aload pop setcolor
3517 pathbbox % x0 y0 x1 y1
3518 2 index sub exch 3 index sub exch
3525 /Do { //DoXObject exec } bind def
3527 /BI { currentglobal false setglobal << } bind def
3529 dup /DataSource currentfile
3531 % This hack provides a compatibility to HP LaserJet 1320,
3532 % which sometimes closes the underlying stream when EOD
3533 % is reached in the ASCII85Decode filter.
3534 % This portion is not required by the Postscript language definition.
3535 2 index /F //knownget exec {
3537 0 (~>) /SubFileDecode filter
3542 //CompleteInlineImage exec
3548 /BT { gsave //GraphicState /InitialTextMatrix get currentmatrix pop } bind def
3549 /ET { grestore } bind def
3550 /Tc { //GraphicState exch /CharacterSpacing exch put } bind def
3551 /TL { //GraphicState exch /TextLeading exch put } bind def
3552 /Tr { //GraphicState exch /TextRenderingMode exch put } bind def
3553 /Ts { % Ghostscript never generates it.
3554 mark (Unimplemented SetTextRise) //error exec
3556 /Tw { //GraphicState exch /WordSpacing exch put } bind def
3557 /Tz { % Ghostscript never generates it.
3558 mark (Unimplemented SetHorizontalTextScaling) //error exec
3560 /Td { translate 0 0 moveto } bind def
3561 /TD { dup neg //TL exec //Td exec } bind def
3562 /Tm { //GraphicState /InitialTextMatrix get setmatrix
3563 //TempMatrix astore concat
3564 0 0 moveto } bind def
3565 /T* { 0 //GraphicState /TextLeading get neg //Td exec } bind def
3566 /Tj { //ShowTextBeg exec //ShowText exec //ShowTextEnd exec } bind def
3567 /' { //T* exec //ShowText exec //ShowTextEnd exec } bind def
3568 /" { 3 2 roll //Tw exec exch //Tc exec //' exec} bind def
3569 /TJ //ShowTextWithGlyphPositioning def
3572 /d0 /setcharwidth load def
3573 /d1 /setcachedevice load def
3575 /BDC { BeginMarkedContentSequenceWithPropertyList } bind def
3576 /BMC { BeginMarkedContentSequence } bind def
3577 /EMC { EndMarkedContentSequence } bind def
3578 /BX { BeginCompatibilitySection } bind def
3579 /EX { EndCompatibilitySection } bind def
3580 /DP { DefineMarkedContentPointWithPropertyList } bind def
3581 /MP { DefineMarkedContentPoint } bind def
3582 /PS { cvx exec } bind def
3586 % Rebind operators with a debug tracing.
3587 //Operators length dict begin
3590 [ exch //=only /exec load % p n [ n =only exec
3591 ( ) /print load % p n [ n =only exec () print
3592 8 7 roll % n [ n =only exec () print p
3593 dup type /arraytype eq {
3594 /exec load % n [ n =only exec () print p exec
3600 currentdict end /Operators exch def
3603 % Functions for handling Ghostscript library files that define encodings.
3618 % Leaving the procset on the dictionary stack to provide
3619 % definitions of obj, endobj, stream, endstream, R, xref.