diff options
author | Reinhard Kotucha <reinhard.kotucha@web.de> | 2015-04-02 23:03:05 +0000 |
---|---|---|
committer | Reinhard Kotucha <reinhard.kotucha@web.de> | 2015-04-02 23:03:05 +0000 |
commit | 8abbce681f8658c931f1403643d08ad2e7fb6d7e (patch) | |
tree | 7b4a42a19e5cc2c57575c4111c9ecb3fbe40ece7 /Master/tlpkg/tlgs/lib/opdfread.ps | |
parent | b2dcb6358d02b5256659808c99916fe8c5975e35 (diff) |
tlpkg/tlgs: upgrade: gs-9.15 -> gs-9.16
git-svn-id: svn://tug.org/texlive/trunk@36707 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlgs/lib/opdfread.ps')
-rw-r--r-- | Master/tlpkg/tlgs/lib/opdfread.ps | 4694 |
1 files changed, 0 insertions, 4694 deletions
diff --git a/Master/tlpkg/tlgs/lib/opdfread.ps b/Master/tlpkg/tlgs/lib/opdfread.ps deleted file mode 100644 index 62da258f098..00000000000 --- a/Master/tlpkg/tlgs/lib/opdfread.ps +++ /dev/null @@ -1,4694 +0,0 @@ -%!PS-Adobe-2.0 -% -% Copyright (C) 2001-2012 Artifex Software, Inc. -% All Rights Reserved. -% -% This software is provided AS-IS with no warranty, either express or -% implied. -% -% This software is distributed under license and may not be copied, -% modified or distributed except as expressly authorized under the terms -% of the license contained in the file LICENSE in this distribution. -% -% Refer to licensing information at http://www.artifex.com or contact -% Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -% CA 94903, U.S.A., +1(415)492-9861, for further information. -% - -% $Id: opdfread.ps 11951 2010-12-15 08:22:58Z ken $ -% pdfread.ps - A procset for interpreting an ordered PDF 1.3 file. - -% This module defines routines for interpreting a PDF file with -% a Postscript interpreter. To convert a PDF file into Postscript -% just pre-contcatenate this file. The PDF file must satisfy -% few constraints : -% -% 1. It must contain only Postscript level 2 objects encoded with -% the PDF 1.3 language. Higher PDF levels must be re-distilled -% with CompatibilityLevel=1.3 . -% -% 2. Objects must be ordered so that any resource be defined before -% its usage. -% -% 3. The PDF file must not include other PDF files. -% Consequently we have a single instance of the PDF reader. -% We use this fact to simplify binding of the routines. -% -% 4. The PDF root object must always have the object id 1. -% -% 5. Generations besides 0 are not allowed. -% -% 6. xref must appear after all objects. -% -% Assuming the currentfile isn't positionable. -% As a consequence, the reader fully ignores xref. - -% ====================== Error handler ======================= -% A general error handler prints an error to page. - -% -% See if our notification from ps2write is present. If it is -% then pick it up. Otherwise define it as false. Used to prevent -% use of setmatrix at start of each page. The DSC-compliant -% output from ps2write wraps pages in a save/restore, so we don't -% need the setmatrix, and it breaks use of psnup with the output. -% -currentdict /DSC_OPDFREAD known { - currentdict /DSC_OPDFREAD get -}{ - false -} ifelse - -10 dict begin % A dictionary for local binding - -% This switch used to control paeg independent values, like -% whether to use InitialMatrix in SetupPageView -% -/DSC_OPDFREAD exch def - -/this currentdict def -/y 720 def -/ebuf 200 string def - -/prnt { - 36 //this /y get moveto //ebuf cvs show - //this /y 2 copy get 12 sub put -} bind def - -/newline { - 36 //this /y get moveto - //this /y 2 copy get 12 sub put -} bind def - -errordict /handleerror -{ systemdict begin - $error begin - newerror - { (%%[ Error handled by opdfread.ps : ) print errorname //ebuf cvs print (; OffendingCommand: ) - print /command load //ebuf cvs print ( ]%%) = flush - /newerror false store vmstatus pop pop 0 ne - { grestoreall - } if - errorname (VMerror) ne - { showpage - } if - initgraphics - 0 720 moveto - errorname (VMerror) eq - { //this /ehsave known - { clear //this /ehsave get restore 2 vmreclaim - } if - vmstatus exch pop exch pop - } - /Courier 12 selectfont - { - (ERROR: ) //prnt exec errorname //prnt exec - (OFFENDING COMMAND: ) //prnt exec - /command load //prnt exec - $error /ostack known { - (%%[STACK:) = - (STACK:) //prnt exec - $error /ostack get aload length { - //newline exec - dup mark eq { - (-mark-) dup = show - } { - dup type /nametype eq { - dup xcheck not { - (/) show - (/) print - } if - } if - dup = //ebuf cvs show - } ifelse - } repeat - } if - } ifelse - (%%]%) = - //systemdict /showpage get exec - quit - } if - end - end -} bind readonly put - -end % A dictionary for local binding - - -50 dict begin - -% ===================== Debugging ========================================= - -/DefaultSwitch % <name> DefaultSwitch - -{ - dup where { - pop pop - } { - false def - } ifelse -} bind def - -/=string 256 string def - -/=only { - //=string cvs print -} bind def - -/HexDigits (0123456789ABCDEF) readonly def - -%% This routine assumes that a PostScript int is only 32 bits -%% we partially address that by and'ing 15 with the 4 bits of -%% data in order to ensure that we don't index off the end of -%% the string above. However, if the integer is genuinely -%% more than 32 bits we still only print the first 32. -/PrintHex % <int> PrintHex - -{ 8 { - dup -28 bitshift 15 and //HexDigits exch 1 getinterval //=only exec - 4 bitshift - } repeat - pop -} bind def - -/PDFR_DEBUG DefaultSwitch -/PDFR_DUMP DefaultSwitch -/PDFR_STREAM DefaultSwitch -/TTFDEBUG DefaultSwitch -/RotatePages DefaultSwitch -/FitPages DefaultSwitch -/CenterPages DefaultSwitch -/SetPageSize DefaultSwitch - -/error % mark <object> .... error - -{ % A stub for a while. - counttomark 1 sub -1 0 { - index dup type /arraytype eq { == } { =only } ifelse - } for - () = - cleartomark - % Assuming ....Undefined is never defined. - % Use it to emit an error. - ....Undefined -} bind def - -//SetPageSize { - //RotatePages //FitPages or //CenterPages or{ - mark (/RotatePages, /FitPages and CenterPages are not allowed with /SetPageSize) //error exec - } if -} -{ - //FitPages //CenterPages and { - mark (CenterPages is not allowed with /FitPages) //error exec - } if -} -ifelse - -% ===================== Utilities ========================================= - -/knownget % <dict> <key> knownget <value> true - % <dict> <key> knownget false -{ - 2 copy known { - get true - } { - pop pop false - } ifelse -} bind def - -/IsUpper % <int> IsUpper <bool> -{ dup (A) 0 get ge exch (Z) 0 get le and -} bind def - -% Copy (recursive) packedarray|array to to global VM -% NOTE: a packedarray will be converted to non-packed (too bad) -/cpa2g { % <packedarray|array> cpa2g <packedarray|array> - dup length array % <src> <dest> - 0 1 2 index length 1 sub { - % <src> <dest> index - dup 3 index exch get cp2g - % <src> <dest> index <globalelement> - 3 copy put pop pop - } for - exch pop -} bind def - -% Copy (recursive) dict to to global VM -/cpd2g { - dup length dict exch { - cp2g 2 index 3 1 roll put - } forall -} bind def - -% Copy string to to global VM -/cps2g { % <string> cps2g <string> - dup length string copy -} bind def - -/cp2gprocs -<< /arraytype //cpa2g /dicttype //cpd2g /packedarraytype //cpa2g /stringtype //cps2g >> -def - -/cp2g { % <any> cp2g <any> - % where <any> is array | dict | string | packedarray - % NOTE: The object must be readable (not executeonly or noaccess) - dup gcheck not { - dup //cp2gprocs 1 index type - 2 copy known { - get currentglobal 3 1 roll true setglobal exec exch setglobal - % set the attributes appropriately (we must have 'read' access to get this far) - 1 index wcheck not { readonly } if - 1 index xcheck { cvx } if - exch pop % discard original (local) object - } { - pop pop % discard type - } ifelse - } if -} bind def - -% ===================== Work Data ========================================= - -/BlockBuffer 65535 string def % Make it big to load entire TrueType font -/PDFReader currentdict def -/ObjectRegistryMaxLength 50000 def -/ObjectRegistry 10 dict def -ObjectRegistry -begin - 0 ObjectRegistryMaxLength dict def -end -/CurrentObject null def -/DoneDocumentStructure false def -/GraphicState 20 dict begin - /InitialTextMatrix matrix def - /InitialMatrix matrix currentmatrix def -currentdict end def -/TempMatrix matrix def -/GraphicStateStack 20 array def -/GraphicStateStackPointer 0 def -/InitialTextMatrixStack 20 array def -/InitialTextMatrixStackPointer 0 def -/PDFColorSpaces 50 dict def -/InstalledFonts 50 dict def -/MacRomanEncodingInverse null def - -% We need some structures in local VM, put then into the userdict : -currentglobal false setglobal -userdict /PDFR_InitialGS gstate put -userdict /PDFR_Patterns 50 dict put -userdict /FuncDataReader 10 dict put -setglobal - -% ===================== Constants ========================================= - -% The ExtGState elements are composite, thus need to be copied to -% global VM (in case they aren't already global). -/InitialExtGState 20 dict begin - /BG2 currentblackgeneration cp2g def - /UCR2 currentundercolorremoval cp2g def - /TR2 currentglobal false setglobal [ currentcolortransfer ] exch setglobal cp2g def - /HT currenthalftone cp2g def -currentdict end readonly def - -/InitialGraphicState 20 dict begin - /FontSize 0 def - /CharacterSpacing 0 def - /TextLeading 0 def - /TextRenderingMode 0 def - /WordSpacing 0 def -currentdict end readonly def - -/SimpleColorSpaceNames 15 dict begin - /DeviceGray true def - /DeviceRGB true def - /DeviceCMYK true def -currentdict end readonly def - -/1_24_bitshift_1_sub 1 24 bitshift 1 sub def - -/ReadFontProcs 10 dict def % Will be filled below. - -/GetObject % <id> GetObject obj true - % <id> GetObject false -{ - dup ObjectRegistryMaxLength idiv - //PDFReader /ObjectRegistry get exch knownget { - exch knownget - } { - pop false - }ifelse -} bind def - -/PutObject % <id> <obj> PutObject -{ - 1 index ObjectRegistryMaxLength idiv % id obj oregnr - //PDFReader /ObjectRegistry get 1 index knownget { - % object already defined in Objectregistry - % id obj oregnr dict - exch pop % id obj dict - 3 1 roll put - }{ - % object not already defined in ObjectRegistry - % id obj oregnr - //PDFReader /ObjectRegistry get dup - begin % new Objectregistry entry: - 1 index ObjectRegistryMaxLength dict def - end - exch get % id obj dict - 3 1 roll put - }ifelse -} bind def - -% ===================== Reading PDF objects =============================== - -/Register % <DefaultDaemon> <id> <obj> Register - -{ - 1 index GetObject { - % d id obj e - dup xcheck { - 4 3 roll pop % id obj e - //PDFR_DEBUG { - (Have a daemon for ) print 2 index == - } if - %% We've got a definition daamon, execute it: - exec - } { - dup null ne { - mark (The object ) 4 index (is already defined : ) 4 index //error exec - } { - pop % d id obj - } ifelse - 3 2 roll % id obj d - %% Execute the default Daemon - exec - }ifelse - } { - % d id obj - 3 2 roll % id obj d - exec % execute the default deamon - }ifelse - PutObject -} bind def - -/IsRegistered % <id> GetRegistered <bool> -{ - GetObject { - null ne - } { - false - }ifelse -} bind def - -/GetRegistered % <id> GetRegistered <obj> -{ - dup GetObject not { - exch mark exch (Object ) exch ( isn't defined before needed (1).) //error exec - } if - % id obj - dup xcheck { - exch mark exch (Object ) exch ( isn't defined before needed (2).) //error exec - } { - dup null eq { - exch mark exch (Object ) exch ( isn't defined before needed (3).) //error exec - } if - exch pop % e - } ifelse -} bind def - -/StandardFontNames << - /Times-Roman true - /Helvetica true - /Courier true - /Symbol true - /Times-Bold true - /Helvetica-Bold true - /Courier-Bold true - /ZapfDingbats true - /Times-Italic true - /Helvetica-Oblique true - /Courier-Oblique true - /Times-BoldItalic true - /Helvetica-BoldOblique true - /Courier-BoldOblique true ->> def - -/CleanAllResources % - CleanAllResources - -{ //PDFR_DEBUG { - (CleanAllResources beg) = - } if - //PDFReader /ObjectRegistry get { - dup length 0 exch 1 exch 1 sub { % R i - 2 copy get dup xcheck { - % Don't clean a daemon. - pop pop - } { - dup null eq { - pop pop - } { - dup type /dicttype eq { /.Global known } { pop false } ifelse { - pop - } { - //PDFR_DEBUG { - (Dropping ) print dup = - } if - 1 index exch /DroppedObject put - } ifelse - } ifelse - } ifelse - } for - pop - }forall % Check each dictionary in the ObjectRegistry - FontDirectory length dict begin - FontDirectory { - pop - dup //StandardFontNames exch known not { - dup null def - } if - pop - } forall - currentdict - end { - pop - //PDFR_DEBUG { - (Undefining font ) print dup = - } if - undefinefont - } forall - //PDFR_DEBUG { - (CleanAllResources end) = - } if -} bind def - -/PrintReference % <array> PrintReference <array> -{ - //PDFR_DEBUG { - ({ ) print - dup { - =only ( ) print - } forall - ( }) = - } if -} bind def - -/R % <id> <gen> R <daemon> -{ % Make a reference daemon. - 0 ne { - exch mark exch (A referred object generation ) exch ( isn't 0.) //error exec - } if % id - [ % <id> proc <obj> - exch //GetRegistered /exec load - ] cvx - //PrintReference exec -} bind def - -/IsObjRef % <any> IsObjRef <bool> -{ - dup type /arraytype eq { - dup length 3 eq { - dup xcheck exch - dup 0 get type /integertype eq 3 2 roll and exch - dup 1 get //GetRegistered eq 3 2 roll and exch - 2 get /exec load eq and - } { - pop false - } ifelse - } { - pop false - } ifelse -} bind def - -/DoNothing -{ -} def - -/RunTypeDaemon % <id> <obj> RunTypeDaemon <id> <obj> -{ - dup type /dicttype eq { - dup /Type //knownget exec { - //PDFReader /TypeDaemons get exch - //knownget exec { - exec - } if - } if - } if -} bind def - -/obj % <id> <generation> obj <id> -{ - //PDFR_DEBUG { - (Defining ) print 1 index =only ( ) print dup =only ( obj) = - } if - 0 ne { - exch mark exch (An object generation ) exch ( isn't 0.) //error exec - } if -} bind def - -/endobj % <id> <obj> endobj - -{ - //PDFR_DEBUG { - (endobj ) = - } if - dup type /dicttype eq { - dup /.endobj_daemon //knownget exec { - //PDFR_DEBUG { (.endobj_daemon for ) print 2 index = } if - exec - } if - } if - dup type /dicttype eq { dup /ImmediateExec known } { false } ifelse { - pop pop - } { - //PDFR_DEBUG { - (Storing ) print 1 index = - } if - //RunTypeDaemon exec - //DoNothing 3 1 roll //Register exec - } ifelse -} bind def - -/StoreBlock % <buf> StoreBlock - -{ % Stores a (encoded) stream data block to the current object. - //PDFR_DEBUG { - (StoreBlock ) print //PDFReader /BlockCount get =only (, Length = ) print dup length = - } if - dup length string copy - //PDFReader /BlockCount get exch % i s - //PDFReader /CurrentObject get 3 1 roll % o i s - put % - //PDFReader /BlockCount get 1 add - //PDFReader exch /BlockCount exch put -} bind def - -/CheckLength % <val> CheckNumber <val> -{ dup type /integertype ne { - mark (Object length isn't an integer.) //error exec - } if -} bind def - -/ResolveD % <dict> <key> <check> ResolveD <value> -{ - 3 copy pop get % <> key {} e - dup //IsObjRef exec { - % We've got a reference daemon, execute it : - //PDFR_DEBUG { - (Resolving ) print //PrintReference exec - } if - exec % <> key {} val - exch exec % <> key val - } { - exch pop - } ifelse - dup 4 1 roll % val <> key val - put % val -} bind def - -/ResolveA % <array> <index> <check> ResolveA <value> -{ 2 index 2 index get - dup //IsObjRef exec { - exec - exch exec - 3 copy put - } { - exch pop - } ifelse - exch pop exch pop -} bind def - -/StoreStream % <id> <obj> StoreStream <id> <obj> -{ % Stores a (encoded) data stream copy to the current object. - dup //PDFReader exch /CurrentObject exch put % id obj - //PDFReader /BlockCount 0 put - dup /Length //CheckLength //ResolveD exec % id obj l - //PDFR_DEBUG { - (StoreStream Length = ) print dup = - } if - currentfile exch () /SubFileDecode filter % id obj file - { dup //BlockBuffer readstring { % id obj file buf - //StoreBlock exec - } { - //StoreBlock exec - exit - } ifelse % id obj file - } loop - pop % id obj - //PDFReader /CurrentObject null put - //PDFR_DEBUG { - (StoreStream end.) = - } if -} bind def - -/MakeStreamDumper % <file> MakeStreamDumper <file> -{ % Debug purpose only. - //PDFR_DEBUG { - (MakeStreamDumper beg.) = - } if - currentglobal exch dup gcheck setglobal - [ exch % f - 1 dict dup /c 0 put exch % d f - 1024 string % d f s - { readstring pop % d s - (StreamDumper ) print 1 index /c get =string cvs print ( ) print - dup length =string cvs print ( <) print dup print (>\n) print - dup length % d s l - 3 2 roll % s l d - dup /c get % s l d c - 3 2 roll % s d c l - add /c exch put % s - } /exec load - ] - cvx 0 () /SubFileDecode filter - exch setglobal - //PDFR_DEBUG { - (MakeStreamDumper end.) = - } if -} bind def - -/ShortFilterNames 15 dict begin - /AHx /ASCIIHexDecode def - /A85 /ASCII85Decode def - /LZW /LZWDecode def - /Fl /FlateDecode def - /RL /RunLengthDecode def - /CCF /CCITTFaxDecode def - /DCT /DCTDecode def -currentdict end readonly def - -/AppendFilters % <file> <dict> AppendFilters <file> -{ - //PDFR_DEBUG { - (AppendFilters beg.) = - } if - dup 3 1 roll % d f d - /Filter //knownget exec { % d f F - dup type /nametype eq { % d f /F - dup //ShortFilterNames exch //knownget exec { - exch pop - } if - 2 index /DecodeParms //knownget exec { % d f p /F - exch - } if - filter % d f' - } { % d f [] - dup 0 exch 1 exch length 1 sub { % d f [] i - 2 copy get % d f [] i /F - dup //ShortFilterNames exch //knownget exec { - exch pop - } if - 3 1 roll % d f /F [] i - 4 index /DecodeParms //knownget exec { % d f /F [] i DP - exch get % d f /F [] dp - } { % d f /F [] i - pop null % d f /F [] dp - } ifelse - dup null eq { % d f /F [] dp - pop 3 1 roll filter exch % d f' [] - } { % d f /F [] dp - 3 1 roll % d f dp /F [] - 4 1 roll filter exch % d f' [] - } ifelse - } for - pop % d f' - } ifelse - //PDFR_DEBUG //PDFR_DUMP and { - //MakeStreamDumper exec - } if - } if - exch pop - //PDFR_DEBUG { - (AppendFilters end.) = - } if -} bind def - -/ExecuteStream % <id> <obj> ExecuteStream <id> <obj> -{ % Executes a (encoded) data stream. - dup //PDFReader exch /CurrentObject exch put % id obj - dup /Length //CheckLength //ResolveD exec % id obj l - //PDFR_DEBUG { - (ExecuteStream id = ) print 2 index =only ( Length = ) print dup = - } if - //PDFReader /InitialGraphicState get - //PDFReader /GraphicState get copy pop - //PDFReader /Operators get begin - % currentfile exch () /SubFileDecode filter % id obj file - % We would like to use the code above, - % but HP LaserJet 1320 continues parsing after the byte count exceeds. - pop currentfile 0 (endstream) /SubFileDecode filter % id obj file - 1 index //AppendFilters exec - cvx mark exch % id obj mark file - exec - counttomark 0 ne { - mark (Data left on ostack after an immediate stream execution.) //error exec - } if - cleartomark % id obj - end % Operators - //PDFR_DEBUG { - (ExecuteStream end.) = - } if - //PDFReader /CurrentObject null put - dup /IsPage known { - dup /Context get /NumCopies //knownget exec { - 1 sub { - copypage - } repeat - } if - EPS2Write not {showpage} if - } if -} bind def - -/stream % <id> <obj> stream <id> <obj> -{ - //PDFR_DEBUG { - 1 index =only ( stream) = - } if % id obj - % Run the object definition daemon, if exists : - 1 index GetObject { - % id obj e - dup xcheck { - exec - % Disable the daemon : - 1 index null PutObject - } { - pop - } ifelse - }if - dup /ImmediateExec known { - dup /GlobalExec //knownget exec { - currentglobal 4 1 roll - setglobal - //ExecuteStream exec - 3 2 roll setglobal - } { - //ExecuteStream exec - } ifelse - } { - //StoreStream exec - } ifelse - dup /.CleanResources //knownget exec { - /All eq { - //CleanAllResources exec - } if - } if -} bind def - -/HookFont % <id> <obj> <font_descriptor> HookFont <id> <obj> -{ - //PDFR_DEBUG { - (Loaded the font ) print dup /FontName get = - } if - { - dup /FontFileType get dup /Type1 eq exch /MMType1 eq or { % id obj fd - % We assume that the Type 1 font has same name with no prefix - % due to pdfwrite specifics. - % We use it to find the font after it is defined. - % We could redefine 'definefont' for hooking the font, - % but we don't think that it could be guaranteedly portable : - % a 3d party PS interpreter may set a special context - % when running the font file. - % Note that this mechanizm does not depend on the - % font name uniquity, because the last 'definefont' - % is only important. - dup /FontName get % id obj fd fn - //PDFReader /RemoveFontNamePrefix get exec - findfont % id obj fd g f - exit - } if - dup /FontFileType get /TrueType eq { % id obj fd - //PDFReader /MakeType42 get exec - //PDFR_DEBUG { - (Font dict <<) = - dup { - 1 index /sfnts eq { - exch pop - (/sfnts [) print - { - (-string\() print length //=only exec (\)- ) = - } forall - (]) = - } { - exch //=only exec ( ) print == - } ifelse - } forall - (>>) = - } if - dup /FontName get exch definefont - exit - } if - mark (FontHook has no proc for ) 2 index /FontFileType get //error exec - } loop - /Font exch put % id obj -} bind def - -/endstream % <id> <obj> endstream <id> <obj> -{ -} bind def - -/xref % - xref - -{ - //PDFR_DEBUG { - (xref) = - //PDFR_DUMP { - //PDFReader /ObjectRegistry get == - } if - } if - end % The procset - count 0 ne { - mark (Excessive data on estack at the end of the interpretation.) //error exec - } if - currentfile 1 (%%EOF) /SubFileDecode filter - flushfile - cleardictstack -} bind def - -% ===================== Restoring the PDF Document Structure =============== - -/ResolveDict % <dict> /ResolveDict - -{ dup { % d key val - pop 1 index exch % d cp key - //DoNothing //ResolveD exec % d obj - pop % d - } forall - pop % -} bind def - -/SetupPageView % <obj> SetupPageView - -{ - //PDFR_DEBUG { - (SetupPageView beg) = - } if -//DSC_OPDFREAD not { - //GraphicState /InitialMatrix get setmatrix -} if - /MediaBox get aload pop % bx0 by0 bx1 by1 - 3 index neg 3 index neg translate % Temporary move to origin - 3 -1 roll sub 3 1 roll exch sub exch % bw bh - userdict /.HWMargins //knownget exec { - aload pop - } { - currentpagedevice /.HWMargins //knownget exec { - aload pop - } { - 0 0 0 0 - } ifelse - } ifelse - currentpagedevice /PageSize get aload pop - 3 -1 roll sub 3 1 roll exch sub exch % bw bh px0 py0 px1 py1 - exch 3 index sub exch 3 index sub % bw bh px0 py0 pw ph - //SetPageSize { - //PDFR_DEBUG { - (Setting page size to ) print 1 index //=only exec ( ) print dup = - } if - pop pop 3 index 3 index 2 copy % bw bh px0 py0 bw bh bw bh - currentglobal false setglobal 3 1 roll % bw bh px0 py0 bw bh bool bw bh - currentpagedevice dup /PageSize known { - /PageSize get aload pop % Get current page size - } { - 0 0 % dummy page size values if not known - }ifelse - % bw bh px0 py0 bw bh bool bw bh Width Height - round cvi 2 index round cvi eq % bw bh px0 py0 bw bh bool bw bh Width bool - exch round cvi 3 index round cvi eq and % bw bh px0 py0 bw bh bool bw bh bool - { % Page Size unchanged, do not emit setpagedevice - pop pop % bw bh px0 py0 bw bh bool - } { - /MediaRequested where { - % bw bh px0 py0 bw bh - /MediaRequested get aload pop % bw bh px0 py0 bw bh Width Height - round cvi 2 index round cvi eq % bw bh px0 py0 bw bh bool bw bh Width bool - exch round cvi 3 index round cvi eq and % bw bh px0 py0 bw bh bool bw bh bool - {pop pop false} % We already requested this media size, so don't re-request - {true} ifelse % Media request different to last request - } { - true % No stored media request, so apply setpagedevice - } ifelse - { - 2 array astore % bw bh px0 py0 bw bh bool [] - dup /MediaRequested exch def - << exch /PageSize exch >> setpagedevice % bw bh px0 py0 bw bh bool - /pagesave save def - } if - } ifelse - userdict /PDFR_InitialGS gstate put - setglobal % bw bh px0 py0 bw bh - } if - //RotatePages { - 2 copy gt 6 index 6 index gt ne { - % a rotation is useful except it fits with no rotation. - 1 index 5 index le 1 index 5 index le and not - } { - false - } ifelse - } { - false - } ifelse - { //CenterPages { - //PDFR_DEBUG { - (Rotating page, and then centering it) == - } if - 90 rotate - 0 5 index neg translate - 5 index 1 index exch sub 2 div - 2 index 6 index sub 2 div neg % bw bh px0 py0 pw ph lm bm - translate - } { - //FitPages { - 1 index 5 index div 1 index 7 index div % bw bh px0 py0 pw ph sx sy - 2 copy gt { - exch - } if - pop dup scale % bw bh px0 py0 pw ph - } if - 90 rotate - 0 5 index neg translate - } ifelse - } { - //CenterPages { - //PDFR_DEBUG { - (Ccentering page) == - } if - 1 index 6 index sub 2 div - 1 index 6 index sub 2 div % bw bh px0 py0 pw ph lm bm - translate - } { - //FitPages { - 1 index 6 index div 1 index 6 index div % bw bh px0 py0 pw ph sx sy - 2 copy gt { - exch - } if - pop dup scale % bw bh px0 py0 pw ph - } if - } ifelse - } ifelse - pop pop % bw bh px0 py0 - translate % bw bh - pop pop % - //PDFR_DEBUG { - (SetupPageView end) = - } if -} bind def - -/PageContentsDaemon % <id> <obj> <node> PageContentsDaemon <id> <obj> -{ % Note: an excessive operand from a prebond procedure. - //PDFR_DEBUG { - (Executing PageContentsDaemon for ) print 2 index = - } if % id obj node - 1 index exch /Context exch put % id obj - dup /ImmediateExec true put - dup /IsPage true put - SetPageSize {dup /Context get //SetupPageView exec} if -} bind def - -/FontFileDaemon % <id> <obj> <font_descriptor> FontFileDaemon <id> <obj> -{ % Note: an excessive operand from a prebond procedure. - //PDFR_DEBUG { - (Executing FontFileDaemon for ) print 2 index = - } if - % We need any font resource that refers this descriptor - % to know the font type. Assuming that FontDescriptorDaemon - % provided FontFileType. - dup /FontFileType get % id obj fd ft - 2 index exch % id obj fd obj ft - dup //ReadFontProcs exch //knownget exec { % id obj fd obj ft proc - exch pop exec % id obj fd - } { - mark (FontFile reader for ) 2 index ( isn't implemented yet.) //error exec - } ifelse - //PDFR_DEBUG { - (FontFileDaemon end) = - } if % id obj fd - pop -} bind def - -/FontDescriptorDaemon % <id> <obj> <font_resource> FontDescriptorDaemon <id> <obj> -{ % Note: an excessive operand from a prebond procedure. - //PDFR_DEBUG { - (Executing FontDescriptorDaemon for ) print 2 index = - } if % id obj fr - %HACK BEG assuming an own font for each font descriptor - % to provide an access to PDFEncoding - % from MakeType42, ComposeCharStrings. - 2 copy /FontResource exch put - %HACK END - /Subtype get 1 index exch /FontFileType exch put -} bind def - -/UnPDFEscape { % <namepdf> UnPDFEscape <nameps> - dup dup length string cvs % /namepdf (name) - dup (#) search { - % name contains PDF-style escapes ("#hh") that need to be removed - { % ... (po..st) (#) (pre) - pop % ... (po..st) (#) - (16#--) 2 index 0 2 getinterval % ... (po..st) (#) (16#--) (po) - 1 index 3 2 getinterval copy pop % ... (po..st) (#) (16#po) - cvi % ... (po..st) (#) 16#po - 0 exch put % ... (po..st); 16#po patched into (#) - 0 % ... (po..st) 0 - 1 index 2 1 index length 2 sub getinterval % ... (po..st) 0 (..st) - 3 copy putinterval % ... (..stst) 0 (XXst) - length % ... (..stst) 0 LEN_OF_(po..st)-2 - 3 copy exch put % ... (..st\0t) 0 LEN_OF_(po..st)-2 - getinterval % ... (..st), stored at begining of old (po..st) - (#) search not { - pop exit % /namepdf (nameps\0..) - } if - } loop - % we have a '\0' marker (not allowed in PDF names) after all usefull characters - (\0) search pop exch pop exch pop - cvn - exch pop - } { - pop pop - } ifelse -} bind def - -/TypeDaemons << % <id> <obj> proc <id> <obj> - /Page - { //PDFR_DEBUG { - (Recognized a page.) = - } if - dup /Contents //knownget exec { % id obj c - 0 get //DoNothing exch % id obj dn id1 - [ % <id> <obj> proc <id> <obj> - 3 index //PageContentsDaemon /exec load - ] cvx % id obj {} - //Register exec % id obj - } { - (fixme: page with no Contents won't be printed.) = - } ifelse - } bind - /FontDescriptor - { //PDFR_DEBUG { - (Recognized a font descriptor.) = - } if - dup /FontName //knownget exec { - 1 index /FontName 3 -1 roll //UnPDFEscape exec put - } if - dup dup /FontFile known {/FontFile} {/FontFile2} ifelse - //knownget exec { % id obj ff - 0 get //DoNothing exch % id obj dn id1 - [ % <id> <obj> proc <id> <obj> - 3 index //FontFileDaemon /exec load - ] cvx % id obj {} - //Register exec % id obj - } { - % FontFile3 are not implemented yet. - (Font descriptor ) print 1 index =only ( has no FontFile.) = - } ifelse - } bind - /Font - { //PDFR_DEBUG { - (Recognized a font resource.) = - } if - dup /BaseFont //knownget exec { - //UnPDFEscape exec 2 copy /BaseFont exch put - % cache the installed font (if any) before replacing it. - //PDFReader /RemoveFontNamePrefix get exec - currentglobal exch % A hack against HP LaserJet 1320 bug : - % It sets the local allocation mode - % when 'resourcestatus' fails. - dup /Font resourcestatus { - pop pop - //PDFReader /GetInstalledFont get exec pop - } { - pop - } ifelse - setglobal - } if - dup /FontDescriptor //knownget exec { % id obj fd - 0 get % id obj id1 - dup //IsRegistered exec { % id obj id1 - //PDFR_DEBUG { - (already registered ) print dup = - } if - pop - } { - //DoNothing exch % id obj dn id1 - [ % <id> <obj> proc <id> <obj> - 3 index //FontDescriptorDaemon /exec load - ] cvx % id obj {} - //Register exec % id obj - } ifelse - } if - } bind ->> def - -/MakeStreamReader % <obj> MakeStreamReader <file> -{ dup - [ - exch - //PDFR_DEBUG { - (Stream proc ) - /print load - //PDFR_STREAM { - (<) - /print load - } if - } if - 1 dict dup /i -1 put - /dup load - /i - /get load - 1 - /add load - /dup load - 3 - 1 - /roll load - /i - /exch load - /put load - //knownget - /exec load - /not load - { () } - /if load - //PDFR_DEBUG { - //PDFR_STREAM { - /dup load - /print load - (>) - /print load - } if - ( end of stream proc.\n) - /print load - } if - ] cvx - //PDFR_DEBUG { - (Stream reader ) print dup == - } if - 0 () /SubFileDecode filter - exch //AppendFilters exec -} bind def - -/RunDelayedStream % <stream_obj> RunDelayedStream - -{ - % Save InitialTextMatrix, as this is local to each content stream - //GraphicState /InitialTextMatrix get - //InitialTextMatrixStack //PDFReader /InitialTextMatrixStackPointer get - 2 copy get null eq { - 2 copy currentglobal true setglobal matrix exch setglobal put - } if - get copy pop - //PDFReader /InitialTextMatrixStackPointer 2 copy get 1 add put - % Execute the stream - //MakeStreamReader exec % file - mark exch - cvx exec % - counttomark 0 ne { - mark (Data left on ostack after a delayed stream execution.) //error exec - } if - cleartomark - % Restore InitialTextMatrix - //PDFReader /InitialTextMatrixStackPointer 2 copy get 1 sub put - //InitialTextMatrixStack //PDFReader /InitialTextMatrixStackPointer get get - //GraphicState /InitialTextMatrix get - copy pop -} bind def - -% ===================== Font Management ====================== - -//ReadFontProcs begin - /Type1 % <font_descriptor> <FontFile_object> Type1 <font_descriptor> - { //PDFR_DEBUG { - (ReadFontProcs.Type1) = - } if - dup /.endobj_daemon [ 4 index //HookFont /exec load ] cvx put - dup /ImmediateExec true put - /GlobalExec true put - } bind def - /MMType1 //Type1 def - /TrueType % <font_descriptor> <FontFile_object> TrueType <font_descriptor> - { //PDFR_DEBUG { - (ReadFontProcs.TrueType) = - } if - dup /.endobj_daemon [ 4 index //HookFont /exec load ] cvx put - pop - } bind def -end - -% A working dictionary to hold items related to reading a TrueType font -% and converting into a type 42 font, especially regarding creating the sfnts -% array of strings, and ensuring strings are split on table boundaries and -% for the glyf table, on glyph boundaries. -% -/.opdloadttfontdict 50 dict def -.opdloadttfontdict begin - -/maxstring 65400 def % less than the maximum length of a PostScript string, - % must be a multiple of 4 (for hmtx / loca / vmtx) -end - -% Uses an insertion sort to sort the contents of an array, -% the sorted array is returned. Takes the array to sort and a -% comparison procedure. The comparison procedure must take two -% arguments, and return a boolean. The return value should be -% false if arguments incorrectly ordered, true if they are -% already in the correct order. -% -% [Array to sort] {comparisaon proc} InsertionSort [Sorted array] -% -/.InsertionSort -{ - /CompareProc exch def - /Array exch def - 1 1 Array length 1 sub - { - /Ix exch def - /Value1 Array Ix get def - - /Jx Ix 1 sub def - { - Jx 0 lt { - exit - } if - /Value2 Array Jx get def - Value1 Value2 CompareProc { - exit - } if - - Array Jx 1 add Value2 put - /Jx Jx 1 sub def - } loop - Array Jx 1 add Value1 put - } for - Array -} bind def - -% -% Utility rourtines to insert a TrueType data type -% -% <string> <index> <integer> putu16 - -/putu16 { - 3 copy -8 bitshift put - exch 1 add exch 16#ff and put -} bind def -% <string> <index> <integer> putu32 - -/putu32 { - 3 copy -16 bitshift putu16 - exch 2 add exch 16#ffff and putu16 -} bind def - -% -% Utility routines to read TrueType table data, returning -% either a string or an array of strings depending on the -% table length. -% - -% Read a table as a single string. -% <file> <length> .readtable <string> -/.readtable { - dup dup 1 and add string - % Stack: f len str - dup 0 4 -1 roll getinterval - % Stack: f str str1 - % Because of the absurd PostScript specification that gives an - % error for reading into an empty string, we have to check for - % this explicitly here. - 3 -1 roll exch - dup () ne { readstring } if pop pop -} bind def - -% Read a big table (one that may exceed 64K). -% <file> <length> .readbigtable <string[s]> -/.readbigtable { - dup maxstring lt { - .readtable - } { - currentuserparams /VMReclaim get -2 vmreclaim - [ 4 2 roll { - % Stack: mark ... f left - dup maxstring le { exit } if - 1 index maxstring string readstring pop 3 1 roll maxstring sub - } loop .readtable ] - exch vmreclaim - } ifelse -} bind def - -% ReadTTF reads the tables and so on from a TreuType font into memory -% so that they are available for later processing. -% -% <filename> ReadTTF - -% -/ReadTTF -{ - .opdloadttfontdict begin - /TTFontFile exch def - - % Table directory: - % version - fixed (4 bytes) - % numTables - USHORT (2 bytes) - % searchRange - USHORT (2 bytes) - % entrySelector - USHORT (2 bytes) - % Read Table - /TableDir TTFontFile 12 string readstring pop def - - % There are numTables table directory entries: - % tag - ULONG (4 bytes) - % checkSum - ULONG (4 bytes) - % offset - ULONG (4 bytes) - % length - ULONG (4 bytes) - % Read entries - /tables TTFontFile TableDir 4 getu16 16 mul string readstring pop def - - % Create dictionary to store directory entries. - /tabarray tables length 16 idiv array def - - % Check version for TrueType collection - TableDir 0 4 getinterval (ttcf) eq { - QUIET not { (Can't handle TrueType font Collections.) = } if - /.loadttfonttables cvx /invalidfont signalerror - } { - % There are ((length of tables string) / 16) Table directory entries - % Get and store each in turn - 0 16 tables length 1 sub { - % Get each directory entry as a 16-byte string - dup % index index - tables exch 16 getinterval % index (string) - exch 16 div cvi exch % index/16 (string) - tabarray 3 1 roll put - } for - } ifelse - - % We need the tables in the order they occur in the file, so sort - % by 'offset'. - tabarray { exch 8 getu32 exch 8 getu32 gt} .InsertionSort pop - - % Now we read the content of each table in turn. If the table is < 64K - % then we store it in a single string. If its more, we store it in an - % array of strings. The table contents are stored in 'tabs' in the same - % order as they are read from the file, as per the sorted array 'tabarray'. - /Read TableDir length tables length add def - /tabs [ - tabarray { - % Get offset (from start of file) of next table - dup 8 getu32 % () offset - % Subtract amount read so far - Read sub % () offset-Read - dup 0 gt { - % Read and discard any extra padding bytes % () offset-Read - dup string TTFontFile exch readstring pop pop % () offset-Read - % Update bytes read - Read add /Read exch def % () - } { - pop % () - } ifelse - % Find length of this table and add it to bytes read - 12 getu32 % () tablelength - dup Read add % () tablelength tablelength+Read - /Read exch def % () tablelength - TTFontFile exch .readbigtable - } forall - ] def - end % .opdloadttfontdict -} bind def - -% GetLocaType finds the head table in tabarray, which gives -% an index into the 'tabs' array where the data is stored. -% From that data we extract the loca type (short or long). -% -% - GetLocaType - -% -/GetLocaType -{ - 0 1 tabarray length 1 sub{ - % control-variable - dup tabarray exch get % control-variable () - 0 4 getinterval (head) eq{ % control-variable bool - tabs exch get % () - 50 gets16 - /LocaType exch def - exit - } { - pop % control variable % - - } ifelse - } for -} bind def - -% GetNumGlyphs finds the maxp table in tabarray, which gives -% an index into the 'tabs' array where the data is stored. -% From that data we extract the number of glyphs in the font. -% -% - GetNumGlyphs - -% -/GetNumGlyphs -{ - 0 1 tabarray length 1 sub{ - % control-variable - dup tabarray exch get % control-variable () - 0 4 getinterval (maxp) eq{ % control-variable bool - % Get the maxp string - % from the tabs array - tabs exch get % () - 4 getu16 % int - /NumGlyphs exch def - exit % int - } { - pop % control variable % - - } ifelse - } for -} bind def - -% StringtoLoca takes a string, and an index in to an array -% where the loca results should be stored from. It reads -% along the string getting either 2-byte or 4-byte values -% (depends on loca type) and stores them in the array at -% successive locations. Leaves the next unused location -% on the stack at end (easy to process multiple strings). -% -% string ArrayIndex StringToLoca ArrayIndex -% -/StringToLoca -{ - /LocaIndex exch def % () - /StringOffset 0 def % () - { - dup length StringOffset gt { % () - dup % () - LocaType 1 eq{ - StringOffset getu32 % () loca - LocaArray LocaIndex 3 -1 roll put % () - /LocaIndex LocaIndex 1 add def % () - /StringOffset StringOffset 4 add % () - def - } { - StringOffset getu16 2 mul % () loca - LocaArray length LocaIndex gt { % take account of apdding in the string - LocaArray LocaIndex 3 -1 roll put % () - }{ % - pop % ignore indices off the end of the array - }ifelse % - /LocaIndex LocaIndex 1 add def % () - /StringOffset StringOffset 2 add % () - def - } ifelse - }{ % () - pop % - - LocaIndex % return index - exit - }ifelse - } loop -} bind def - -% GetSortedLoca reads the loca table, and sorts it by offset -% this is so that we can walk up the array looking for an approporiate -% place to split strings. The result is stored in LocArray -% -% - GetSortedLoca - -% -/GetSortedLoca -{ - NumGlyphs 1 add array /LocaArray exch def - - % Get the loca table - 0 1 tabarray length 1 sub{ - % control-variable - dup tabarray exch get % control-variable () - 0 4 getinterval (loca) eq{ % control-variable bool - % Get the loca string - % from the tabs array - tabs exch get % () - exit - } { - pop % control variable % - - } ifelse - } for - - % If its a single string handle the easy way - dup type /stringtype eq { - 0 StringToLoca pop - }{ - % Otherwise its an array, process each string in the array - 0 exch % Starting LocaArray index - { - exch StringToLoca - }forall - pop % final LocaArray index - }ifelse - - % Now we've read all the locations, sort them so - % we can figure out where to break the strings - LocaArray {gt} .InsertionSort pop -} bind def - -% Updates internal storage with a new string from the -% GlyfArray -% - GetWorkingString - -/GetWorkingString -{ - WorkString 0 - GlyfArray GlyfStringIndex get - putinterval - % Update the available bytes - /WorkBytes GlyfArray GlyfStringIndex get length def - % Set index to get data from next string in array - /GlyfStringIndex GlyfStringIndex 1 add def -} bind def - -% Returns a string with the requested number of bytes taken -% from WorkingString. There must be enough data in WorkingString to -% satisfy the request -% -/GetWorkingBytes -{ - /BytesToRead exch def - % Get 'BytesToRead' bytes from working store - WorkString 0 BytesToRead getinterval - dup length string copy - % Get remaining bytes from working store - WorkString BytesToRead WorkBytes BytesToRead sub getinterval - dup length string copy - % replace first 'n' bytes of working store with unread bytes - WorkString 0 3 -1 roll putinterval - % Subtract bytes read from bytes available - /WorkBytes WorkBytes BytesToRead sub def -} bind def - -% Read 'int' bytes from GlyfArray strings, return string composed -% of those bytes -% -% int GetGlyfBytes string -/GetGlyfBytes -{ - /ToRead exch def - - % If we have no available data, get soem from the array of - % glyf strings - WorkBytes 0 eq { - GetWorkingString - } if - - WorkBytes ToRead ge { - ToRead string dup 0 - ToRead GetWorkingBytes putinterval - }{ - % Create a string sized to hold the target data - ToRead string - % Get remaining stored bytes, and put at the start - % of the string - dup - % Start of string - 0 - % Get remaining bytes - WorkString 0 WorkBytes getinterval - % store at start of output string - putinterval - - dup - % Location in output to store data from next string - WorkBytes - % amout of data required to read from next string - ToRead WorkBytes sub - % Get the next string from the array of strings - GetWorkingString - % Get a string containing the required data, updating - % the internal data storage - GetWorkingBytes - % put the data at the end of the stored data in the - % output string - putinterval - } ifelse -} bind def - -% Given an array of glyf strings, returns an array of strings -% split on glyf boundaries -% -% [] SplitGlyf [] -% -/SplitGlyf -{ - /GlyfArray exch def - /DestArray GlyfArray length 2 mul array def - /DestArrayIndex 0 def - - /LastLoca 0 def - /NextLocaIndex 0 def - /LastLocaIndex 0 def - - /GlyfStringIndex 0 def - /WorkString maxstring string def - /WorkBytes 0 def - - % Find appropriate next loca - { - % Get location of next glyph - LocaArray NextLocaIndex get % int - % subtract location of last point to get - % the actual bytes between - LastLoca sub maxstring gt % int bool - { - LocaArray LastLocaIndex get LastLoca sub - GetGlyfBytes % () - DestArray DestArrayIndex 3 -1 roll put % - - /DestArrayIndex DestArrayIndex 1 add def % - - LocaArray LastLocaIndex get /LastLoca exch def % - - } { % int - /LastLocaIndex NextLocaIndex def % - - /NextLocaIndex NextLocaIndex 1 add def % - - NextLocaIndex NumGlyphs gt % bool - { - WorkBytes % int - GlyfStringIndex GlyfArray length lt { % int bool - GlyfArray GlyfStringIndex get length % int - add string dup % (d) (d) - 0 % (d) (d) 0 - WorkString 0 WorkBytes getinterval % (d) (d) (s) - putinterval % (d) - dup % (d) (d) - WorkBytes % (d) (d) int - GetWorkingString % (d) (d) int - WorkString 0 WorkBytes getinterval % (d) (d) int (s) - putinterval % (d) - } { - pop % - - WorkString 0 WorkBytes getinterval % () - } ifelse - dup length string copy - DestArray DestArrayIndex 3 -1 roll put - exit - } if - } ifelse - } loop - DestArray - -} bind def - -% ProcessTTData looks at the data stored in the 'tabs' array and does several things: -% 1) Make sure strings representing tables are multiples of 4 bytes long -% 2) For arrays representing tables, make sure the total string length is a multiple -% of 4 bytes long, to ensure the table is a multiple of 4 bytes. -% 3) Handle the glyf table specislly, each string in this array must be split on the -% boundary of a glyf. Use the loca table to determine where the split should happen -% and build a new array of strings split appropriately. -% -% - ProcessTTData - -% -/ProcessTTData -{ - .opdloadttfontdict begin - % Make sure all the strings are a multiple of 4 bytes - 0 1 tabarray length 1 sub{ - /ix exch def - tabarray ix get - 12 getu32 dup maxstring le { - % String < 64Kb, still need to check if its a multiple of 4 - dup 4 mod 0 ne { - 4 div cvi 1 add 4 mul string /newstring exch def - /oldstring tabs ix get def - newstring 0 oldstring putinterval - 0 1 newstring length oldstring length sub 1 sub { - newstring exch oldstring length add 0 put - } for - tabs ix newstring put - } { - % table size is a multiple of 4, don't need to promote it - pop - } ifelse - }{ - % table size > 64K, so this is an array of strings, not a string - % We still need to make sure that the tables end on 4-byte - % boundaries. - dup 4 mod 0 ne { - % First we need to work out how many strings of size maxstring - % are present, and how much they contribute to the overall size. - dup maxstring idiv maxstring mul sub - % Promote final string length to multiple of 4 - 4 idiv 1 add 4 mul string /newstring exch def - % Get array of strings - tabs ix get - % find size of table and get last string - dup length 1 sub dup /iy exch def get /oldstring exch def - newstring 0 oldstring putinterval - 0 1 newstring length oldstring length sub 1 sub { - newstring exch oldstring length add 0 put - } for - tabs ix get iy newstring put - } { - % table size is a multiple of 4, don't need to promote it - pop - } ifelse - } ifelse - } for - - % Now, if glyf table > 64Kb, then it will be an array of strings - % We need to make sure the strings are split on glyph boundaries - 0 1 tabarray length 1 sub { % int - dup tabarray exch get % int () - dup 12 getu32 maxstring gt { % int () bool - 0 4 getinterval dup (glyf) eq{ % int () bool - % Need to split the glyf strings on glyph boundaries, hmmm. - pop % int - % We need to know the number of glyphs (from the maxp table) and the - % position of each glyph (from the loca table). - GetLocaType % int - GetNumGlyphs % int - GetSortedLoca % int - % Get the array of strings from tabs - dup tabs exch get % int - SplitGlyf % int [] - tabs 3 1 roll put % - - } { % int () - (Warning, table ) print print ( > 64Kb\n) print - pop % - - } ifelse - }{ % int () - % Table less than 64K, so don't worry - pop % directory entry % int - pop % 'for' control variable % - - } ifelse - } for - end % .opdloadttfontdict -} bind def - -% Makesfnts uses the accumulated data to create an array of strings -% containing only the required data. -% -% - Makesfnts array -% -/Makesfnts -{ - .opdloadttfontdict begin - % Determine size of sfnts array - % length of tabarray + header - 0 - tabs { % int obj - dup type /stringtype eq { % int obj bool - pop % int - 1 add % int - }{ % int obj - { % int obj - type /stringtype eq { % int bool - 1 add % int - } if - } forall - } ifelse - } forall - - 1 add % add header and table directory - % to determine total # strings - % Need to recalculate the lengths of the TT - % tables, just in case any have changed. If required we - % could also resort the tables here, ideally we should do so - % and recalculate checksums, but this should never be necessary - % for fonts produced by pdfwrite. - /TTOffset - TableDir length % initial table offset is header length - tabarray length 16 mul add % + (NumTables * 16) bytes - def - - 0 - tabarray { % index () - exch dup 1 add % () index index+1 - 3 1 roll % index+1 () index - dup % index+1 () index index - tabs exch get % index+1 () index ()/[] - dup type /stringtype eq { % index+1 () index ()/[] bool - length % index+1 () index int - 2 index exch % index+1 () index () int - TTOffset - dup 3 1 roll add % add the running total of offsets - /TTOffset exch def % update running total of offsets - 8 exch putu32 % index+1 () index - exch tabarray 3 1 roll % index+1 [] index () - put % index+1 - } { % index+1 () index ()/[] - 0 exch % add all string lengths - { % starting from 0 - dup type /stringtype eq { - length add % - } { - pop - } ifelse - } forall % - 2 index exch % index+1 () index () int - TTOffset - dup 3 1 roll add % add the running total of offsets - /TTOffset exch def % update running total of offsets - 8 exch putu32 % index+1 () index - exch tabarray 3 1 roll % index+1 [] index () - put % index+1 - } ifelse - } forall - pop % index+1 - - array % [] - dup 0 % [] [] 0 - TableDir length - tables length add % [] [] 0 header_length - string % [] [] 0 () - dup 0 TableDir putinterval % [] [] 0 () - dup 12 tables putinterval % [] [] 0 () - put % [] - dup % [] [] - /ix 1 def - tabs { % [] [] obj - dup type /stringtype eq { % [] [] obj bool - ix exch % [] [] int obj - put dup % [] [] - /ix ix 1 add def % [] [] - }{ - { - dup type /stringtype eq { % [] [] obj bool - ix exch put dup % [] [] - /ix ix 1 add def % - } { - pop % [] [] - } ifelse - } forall - } ifelse - } forall - pop % [] - end %.opdloadttfontdict -} bind def - -/MakeType42 % <FontFile_object> <font_descriptor> MakeType42 <FontFile_object> <font_descriptor> <font> -{ - //PDFR_DEBUG { - (MakeType42 beg) = - } if - 10 dict begin - /FontName 1 index /FontName get def - /FontType 42 def - /FontMatrix [1 0 0 1 0 0] def - /FontBBox 1 index /FontBBox get def % fo fd - dup /FontResource get % fo fd fr - dup /Encoding known { % fo fd fr - //PDFReader /ObtainEncoding get exec % fo fd fr - /Encoding get % fo fd e - } { - pop null - } ifelse - /PDFEncoding exch def % fo fd - /CharStrings 2 index //PDFReader /MakeTTCharStrings get exec def - /sfnts 2 index //MakeStreamReader exec - ReadTTF - ProcessTTData - Makesfnts - def - /Encoding StandardEncoding def % A stub - will be replaced by font resource. - /PaintType 0 def - currentdict end - //PDFR_DEBUG { - (MakeType42 end) = - } if -} bind def - -/GetInstalledFont % <name> GetInstalledFont <font> -{ - dup //InstalledFonts exch knownget { % n f - exch pop % f - } { % n - dup findfont dup 3 1 roll % f n f - //InstalledFonts 3 1 roll put % f - } ifelse -} bind def - -/RemoveFontNamePrefix % <name> RemoveFontNamePrefix <name> -{ //=string cvs true - 0 1 5 { - 2 index exch get //IsUpper exec not { - pop false exit - } if - } for - { (+) search { - pop pop - } if - } if - cvn -} bind def - -/CheckFont % <key> <val> CheckFont <key> <val> -{ dup /Type get /Font ne { - mark (Resource ) 3 index ( must have /Type/Font .) //error exec - } if -} bind def - -/CheckEncoding % <key> <val> CheckEncoding <key> <val> -{ dup type /nametype ne { - dup /Type get /Encoding ne { - mark (Resource ) 3 index ( must have /Type/Encoding .) //error exec - } if - } if -} bind def - -/ObtainEncoding % <font_resource> ObtainEncoding <font_resource> -{ dup /Encoding known { - dup dup /Encoding //CheckEncoding //ResolveD exec % fr fr er|e|n - dup type dup /arraytype eq exch /packedarraytype eq or { - % Already resolved. - pop pop - } { - dup type /nametype eq { - /Encoding findresource % fr fr e - } { - dup /BaseEncoding //knownget exec not { - /StandardEncoding - } if - /Encoding findresource % fr fr er e - exch % fr fr e er - /Differences //knownget exec { % fr fr e d - exch dup length array copy exch - 0 exch % fr fr e 0 d - { % fr fr e i v - dup type /integertype eq { - exch pop - } { - 3 copy put pop % fr fr e i - 1 add - } ifelse - } forall - pop % fr fr e - } if % fr fr e - } ifelse % fr fr e - /Encoding exch put % fr - } ifelse - } { - dup /Encoding /StandardEncoding /Encoding findresource put - } ifelse -} bind def - -/ObtainMetrics % <font_resource> ObtainMetrics <font_resource> -{ dup /Widths //knownget exec { % fr W - 1 index /Encoding get % fr W E - 256 dict % fr W E M - 3 index /Subtype get /TrueType eq { - 1000 - } { - 1 - } ifelse % fr W E M s - 4 index /MissingWidth //knownget exec not { - 0 - } if % fr W E M s mw - 5 index /FirstChar //knownget exec not { - 0 - } if % fr W E M s mw c0 - 6 5 roll % fr E M s mw c0 W - dup 0 exch 1 exch length 1 sub { % fr E M s mw c0 W i - 2 copy get % fr E M s mw c0 W i w - exch 3 index add % fr E M s mw c0 W w c - 7 index exch get % fr E M s mw c0 W w n - dup dup null ne exch /.notdef ne and { - 6 index 3 1 roll exch % fr E M s mw c0 W M n w - 6 index div - 3 copy pop //knownget exec { - 0 eq - } { - true - } ifelse - { put % fr E M s mw c0 W - } { - pop pop pop - } ifelse - } { - pop pop - } ifelse - } for - pop pop pop pop exch pop % fr M - 1 index exch /Metrics exch put % fr - } { - dup /MissingWidth //knownget exec { % fr mw - 256 dict % fr mw M - 2 index /Encoding get { % fr mw M e - dup null ne { - 3 copy 3 2 roll put % fr mw M e - } if - pop % fr mw M - } forall - exch pop % fr M - 1 index exch /Metrics exch put % fr - } if - } ifelse -} bind def - -/NotDef % - NotDef - -{ % A Type 3 font is on dstack. - FontMatrix aload pop pop pop exch pop exch pop % sx sy - 1 exch div exch - 1 exch div exch % wx wy - 1 index 0 setcharwidth - 0 setlinewidth - 0 0 moveto - 2 copy rlineto - 1 index 0 rlineto - neg exch neg exch rlineto % - closepath stroke -} bind def - -%% These two routines may have more general application. -%% When executing BuildChar we need to run in the context of the font -%% as far as resources are concerned (in case the glyph uses another font) -%% but since we are executing a page stream, we must not lose the original -%% context, or we won't be able to find page resources. Originally this was -%% a simpler routine, but this failed when presented with a type 3 font -%% whose BuildChar/CharProcs used another type 3 font -/SaveResourcesToStack -{ - [ - //PDFReader /OldResources known { - //PDFReader /OldResources get - }{ - null - } ifelse - //PDFReader /CurrentObject get /Context get /Resources get - ] - //PDFReader /OldResources 3 -1 roll put -}bind def - -/RestoreResourcesFromStack -{ - //PDFReader /OldResources get dup - 0 get //PDFReader /OldResources 3 -1 roll put - 1 get //PDFReader /CurrentObject get /Context get /Resources 3 -1 roll put -} bind def - -/BuildChar % <font> <char_code> BuildChar - -{ //PDFR_DEBUG { - (BuildChar ) print dup //=only exec ( ) print - } if - exch begin - Encoding exch get % n - //PDFR_DEBUG { - dup = - } if - dup null eq { - pop //NotDef exec % - } - { % n - CharProcs exch//knownget exec - { - currentfont /Font get /Resources //knownget exec{ %% Does the Font have any Resources ? - exec %% Get them - SaveResourcesToStack %% Save the current Resources - //PDFReader /CurrentObject get /Context get %% Replace the current resources - /Resources 3 -1 roll put %% With the Font resources - //RunDelayedStream exec - RestoreResourcesFromStack %% Restore the previous Resources - } { - //RunDelayedStream exec - } ifelse - } - { - //NotDef exec - }ifelse - } ifelse % - end % font -} bind def - -/printdict % <dict> printdict - -{ (<<) = - { exch = == } forall - (>>) = -} bind def - -/printfont % <dict> printfont - -{ - dup { - exch dup = - dup /Encoding eq { - pop = - } { - dup /FontInfo eq exch /Private eq or { - //printdict exec - } { - == - } ifelse - } ifelse - } forall -} bind def - -/ScaleMetrics % <Metrics> <scale> ScaleMetrics <Metrics> -{ 1 index { % M s n v - 2 index div % M s n v' - 3 index % M s n v' M - 3 1 roll put % M s - } forall - pop -} bind def - -/ResolveAndSetFontAux % <resource_name> <size> ResolveAndSetFont - -{ exch dup % s rn rn - //PDFReader /CurrentObject get /Context get /Resources get - /Font //DoNothing //ResolveD exec - exch //CheckFont //ResolveD exec % s rn fr - dup /Font //knownget exec { % s rn fr f - exch pop exch pop - } { - { - dup /Subtype get dup dup /Type1 eq exch /TrueType eq or exch /MMType1 eq or { - % s rn fr - exch pop % s fr - dup /BaseFont get % s fr n - //RemoveFontNamePrefix exec % s fr n - //PDFR_DEBUG { - (Font ) print dup = - } if % s fr n - 1 index /FontDescriptor known { % s fr n - //PDFR_DEBUG { - (Font from a font descriptor.) = - } if - 1 index % s fr n fr - /FontDescriptor //DoNothing //ResolveD exec % s fr n fd - /Font //knownget exec { - exch pop % s fr fd - } { - //PDFR_DEBUG { - (Font descriptor has no Font resolved.) = - } if - //GetInstalledFont exec % s fr f - } ifelse - } { - //GetInstalledFont exec % s fr f - } ifelse - exch % s f fr - dup /Encoding known not { - 1 index /Encoding get 1 index exch /Encoding exch put - } if - //ObtainEncoding exec - //ObtainMetrics exec - exch - dup length dict copy % s fr f - dup 2 index /Encoding get % s fr f f e - /Encoding exch put % s fr f - 1 index /Metrics //knownget exec { % s fr f M - 2 index /Subtype get /TrueType ne { - 1 index /FontMatrix get 0 get - dup 0 eq { - % FontMatrix[0] == 0, so cannot downscale by it - % HACK: downscale by FontMatrix[1], and will get the target value of wx as wy - pop - 1 index /FontMatrix get 1 get - dup 0 eq { pop 1 } if % sorry, FontMatrix is singular so cannot enforce the PDF metrics - } if - 0.001 div - //ScaleMetrics exec - }{ - % Check if we got a /sfnts key in the dict - % If we did then we are probably OK (TT font from GS) - 1 index /sfnts known not { - % otherwise we need to check the FontMatrix - 1 index /FontMatrix get 0 get - dup 0 eq { - % FontMatrix[0] == 0, so cannot downscale by it - % HACK: downscale by FontMatrix[1], and will get the target value of wx as wy - pop - 1 index /FontMatrix get 1 get - dup 0 eq { pop 1 } if % sorry, FontMatrix is singular so cannot enforce the PDF metrics - } if - //ScaleMetrics exec - } if - } ifelse - 1 index exch /Metrics exch put % s fr f - } if - 1 index /BaseFont get % s fr f n - exch - dup /FID undef - dup /UniqueID undef - definefont % s fr f - dup 3 1 roll % s f fr f - /Font exch put % s f - exit - } if - dup /Subtype get /Type3 eq { % s rn fr - //ObtainEncoding exec - 2 copy exch /FontName exch put - dup /CharProcs get //ResolveDict exec - dup /FontType 3 put - dup /BuildChar //BuildChar put - dup dup /Font exch put - % Ignore Metrics because pdfwrite duplicates it - % from setcharwidth/setcachedevice. - dup 3 1 roll % s fr rn fr - definefont % s fr f - 2 copy ne { - % The interpreter copied the font dictionary while 'definefont' - % Need to update the font pointer in the resource. - 2 copy /Font exch put % s fr f - } if - exch pop % s f - exit - } if - dup /Subtype get /Type0 eq { % s rn fr - } if - dup /Subtype get /CIDFontType0 eq { % s rn fr - } if - dup /Subtype get /CIDFontType2 eq { % s rn fr - } if - mark (Unknown font type ) 2 index /Subtype get //error exec - } loop - } ifelse % s f - exch scalefont setfont % -} bind def - -/ResolveAndSetFont % <resource_name> <size> ResolveAndSetFont - -{ - //ResolveAndSetFontAux exec -} bind def - -%%beg TrueType -% ================= Auxiliary procedures for True Type cmap Decoder ============= - -/.knownget -{ 2 copy known { - get true - } { - pop pop false - } ifelse -} bind def - -/.min -{ 2 copy lt { - exch - } if - pop -} bind def - -/.max -{ 2 copy gt { - exch - } if - pop -} bind def - -/.dicttomark -{ >> -} bind def - -% ===================== True Type cmap Decoder ============= -% The following procedures are copied from gs/lib/gs_ttf.ps with no change. - -% <string> <index> getu16 <integer> -/getu16 { - 2 copy get 8 bitshift 3 1 roll 1 add get add -} bind def - -% <string> <index> gets16 <integer> -/gets16 { - getu16 16#8000 xor 16#8000 sub -} bind def - -% <string> <index> getu32 <integer> -/getu32 { - 2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add -} bind def - -% <string> <index> gets32 <integer> -/gets32 { - 2 copy gets16 16 bitshift 3 1 roll 2 add getu16 add -} bind def - -% Each procedure in this dictionary is called as follows: -% <encodingtable> proc <glypharray> -/cmapformats mark - 0 { % Apple standard 1-to-1 mapping. - 6 256 getinterval { } forall 256 packedarray - } bind - 2 { % Apple 16bit CJK (ShiftJIS etc) - - % /sHK_sz subHeaderKey_size % 1 * uint16 - % /sH_sz subHeader_size % 4 * uint16 - % /sH_len subHeader_length - % /cmapf2_tblen total table length - % /cmapf2_lang language code (not used) - % /sHKs subHeaderKeys - - /sHK_sz 2 def - /sH_sz 8 def - dup 2 getu16 /cmapf2_tblen exch def - - dup 4 getu16 /cmapf2_lang exch def - - dup 6 256 sHK_sz mul getinterval /sHKs exch def - - 0 % initialization value for /sH_len - 0 1 255 { - sHKs exch - 2 mul getu16 - 1 index % get current max - 1 index % get current subHeaderKey - lt {exch} if pop - } for - /sH_len exch def - - dup 6 256 sHK_sz mul add - cmapf2_tblen 1 index sub getinterval - /sH_gIA exch def - - /cmapf2_glyph_array 65535 array def - - /.cmapf2_putGID { - /cmapf2_ch cmapf2_ch_hi 8 bitshift cmapf2_ch_lo add def - firstCode cmapf2_ch_lo le - cmapf2_ch_lo firstCode entryCount add lt - and { % true: j is inside - sH_offset idRangeOffset add % offset to gI - cmapf2_ch_lo firstCode sub 2 mul % rel. pos. in range - add 6 add % offset in sH_gIA - sH_gIA exch getu16 - dup 0 gt { % - idDelta add - cmapf2_glyph_array exch cmapf2_ch exch put - } { - pop - % cmapf2_glyph_array cmapf2_ch 0 put - } ifelse - } { % false: j is outside - % cmapf2_glyph_array cmapf2_ch 0 put - } ifelse - } def - - 16#00 1 16#ff { % hi_byte scan - /cmapf2_ch_hi exch def - sHKs cmapf2_ch_hi sHK_sz mul getu16 - /sH_offset exch def - sH_gIA sH_offset sH_sz getinterval - dup 0 getu16 /firstCode exch def - dup 2 getu16 /entryCount exch def - dup 4 gets16 /idDelta exch def - dup 6 getu16 /idRangeOffset exch def - pop - sH_offset 0 eq { - /cmapf2_ch_lo cmapf2_ch_hi def - /cmapf2_ch_hi 0 def - .cmapf2_putGID - } { - 16#00 1 16#ff { % lo_byte scan - /cmapf2_ch_lo exch def - .cmapf2_putGID - } for - } ifelse - } for - pop - 0 1 cmapf2_glyph_array length 1 sub { % rewrite null -> 0. - dup cmapf2_glyph_array exch get - null eq { cmapf2_glyph_array exch 0 put } {pop} ifelse - } for - cmapf2_glyph_array - } bind - 4 { % Microsoft/Adobe segmented mapping. - /etab exch def - /nseg2 etab 6 getu16 def - 14 /endc etab 2 index nseg2 getinterval def - % The Apple TrueType documentation omits the 2-byte - % 'reserved pad' that follows the endCount vector! - 2 add - nseg2 add /startc etab 2 index nseg2 getinterval def - nseg2 add /iddelta etab 2 index nseg2 getinterval def - nseg2 add /idroff etab 2 index nseg2 getinterval def - % The following hack allows us to properly handle - % idiosyncratic fonts that start at 0xf000: - pop - /firstcode startc 0 getu16 16#ff00 and dup 16#f000 ne { pop 0 } if def - /striptopbyte false def - /putglyph { - glyphs code 3 -1 roll put /code code 1 add def - } bind def - % Do a first pass to compute the size of the glyphs array. - /numcodes 0 def /glyphs 0 0 2 nseg2 3 sub { - % Stack: /glyphs numglyphs i2 - /i2 exch def - /scode startc i2 getu16 def - /ecode endc i2 getu16 def - ecode lastcode gt { - /lastcode ecode def - } if - } for pop - % If the glyph range is within 0x..00 to 0x..FF, make sure that we strip - % off any top bytes. - firstcode 16#f000 ge lastcode firstcode sub 255 le and { - lastcode 255 and - /striptopbyte true def - } { - lastcode - }ifelse - 1 add - array def - % prefill the array with 0's faster than a { 0 putglyph } repeat - glyphs length 1024 ge { - .array1024z 0 1024 glyphs length 1023 sub { glyphs exch 2 index putinterval } for - glyphs dup length 1024 sub 3 -1 roll - putinterval - } { - 0 1 glyphs length 1 sub { glyphs exch 0 put } for - } ifelse - % Now fill in the array. - /numcodes 0 def /code 0 def - 0 2 nseg2 3 sub { - /i2 exch def - /scode startc i2 getu16 def - /ecode endc i2 getu16 def - numcodes scode firstcode sub - % Hack for fonts that have only 0x0000 and 0xf000 ranges - %dup 16#e000 ge { 255 and } if - % the previous line is obstructive to CJK fonts, so it was removed - exch sub 0 .max dup /code exch code exch add def - ecode scode sub 1 add add numcodes add /numcodes exch def - /delta iddelta i2 gets16 def - TTFDEBUG { - (scode=) print scode =only - ( ecode=) print ecode =only - ( delta=) print delta =only - ( droff=) print idroff i2 getu16 = - } if - idroff i2 getu16 dup 0 eq { - pop scode delta add 65535 and 1 ecode delta add 65535 and - striptopbyte { - /code scode 255 and def - } { - /code scode def - } ifelse - { putglyph } for - } { % The +2 is for the 'reserved pad'. - /gloff exch 14 nseg2 3 mul add 2 add i2 add add def - striptopbyte { - /code scode 255 and def - } { - /code scode def - } ifelse - 0 1 ecode scode sub { - 2 mul gloff add etab exch getu16 - dup 0 ne { delta add 65535 and } if putglyph - } for - } ifelse - } for glyphs /glyphs null def % for GC - } bind - 6 { % Single interval lookup. - dup 6 getu16 /firstcode exch def dup 8 getu16 /ng exch def - firstcode ng add array - % Stack: tab array - % Fill elements 0 .. firstcode-1 with 0 - 0 1 firstcode 1 sub { 2 copy 0 put pop } for - dup firstcode ng getinterval - % Stack: tab array subarray - % Fill elements firstcode .. firstcode+nvalue-1 with glyph values - 0 1 ng 1 sub { - dup 2 mul 10 add 4 index exch getu16 3 copy put pop pop - } for pop exch pop - } bind -.dicttomark readonly def % cmapformats - -% <cmaptab> cmaparray <glypharray> -/cmaparray { - dup 0 getu16 cmapformats exch .knownget { - TTFDEBUG { - (cmap: format ) print 1 index 0 getu16 = flush - } if exec - } { - (Can't handle format ) print 0 getu16 = flush - 0 1 255 { } for 256 packedarray - } ifelse - TTFDEBUG { - (cmap: length=) print dup length = dup == - } if -} bind def - -% Define remapping for misnamed glyphs in TrueType 'post' tables. -% There are probably a lot more than this! -/postremap mark - /Cdot /Cdotaccent - /Edot /Edotaccent - /Eoverdot /Edotaccent - /Gdot /Gdotaccent - /Ldot /Ldotaccent - /Zdot /Zdotaccent - /cdot /cdotaccent - /edot /edotaccent - /eoverdot /edotaccent - /gdot /gdotaccent - /ldot /ldotaccent - /zdot /zdotaccent -.dicttomark readonly def - -/get_from_stringarray % <array|string> <offset> get_from_stringarray <int> -{ 1 index type /stringtype eq { - get - } { - exch { % o () - 2 copy length ge { - length sub - } { - exch get exit - } ifelse - } forall - } ifelse -} bind def - -/getinterval_from_stringarray % <array|string> <offset> <length> getinterval_from_stringarray <string> -{ % May allocate a string in VM. - 2 index type /stringtype eq { - getinterval - } { - string exch 0 % [] s o p - 4 3 roll { % s o p Si - dup length % s o p Si lSi - dup 4 index lt { - 3 index exch sub % s o p Si o' - exch pop 3 1 roll exch pop % s o' p - } { % s o p Si lSi - dup 3 1 roll % s o p lSi Si lSi - 4 index sub % s o p lSi Si lSi-o - 5 index length 4 index sub % s o p lSi Si lSi-o ls-p - 2 copy gt { exch } if pop % s o p lSi Si minl - dup 3 1 roll % s o p lSi minl Si minl - 5 index exch getinterval % s o p lSi minl from - 5 index 4 index 3 index % s o p lSi minl from s p minl - getinterval % s o p lSi minl from to - copy pop % s o p lSi minl - exch pop add exch pop 0 exch % s 0 p' - dup 3 index length ge { exit } if - } ifelse - } forall - pop pop % s - } ifelse -} bind def - -/string_array_size % <array|string> string_array_size <int> - { dup type /stringtype eq { - length - } { - 0 exch { length add } forall - } ifelse -} bind def - -% Each procedure in this dictionary is called as follows: -% posttable <<proc>> glyphencoding -/postformats mark - 16#00010000 { % 258 standard Macintosh glyphs. - pop MacGlyphEncoding - } - 16#00020000 { % Detailed map, required by Microsoft fonts. - dup dup type /arraytype eq { 0 get } if length 36 lt { - TTFDEBUG { (post format 2.0 invalid.) = flush } if - pop [ ] - } { - /postglyphs exch def - /post_first postglyphs dup type /arraytype eq { 0 get } if def - post_first 32 getu16 /numglyphs exch def - /glyphnames numglyphs 2 mul 34 add def - % Build names array in the order they occur in the 'post' table - /postpos glyphnames def - /total_length postglyphs //string_array_size exec def - numglyphs array 0 1 numglyphs 1 sub { - postpos total_length ge { - % Fill the rest with .notdef - 1 numglyphs 1 sub { 1 index exch /.notdef put } for - exit - } if - % No name available, /postnames will be defined as an empty - % array and the glyph won't get a name attached. - postglyphs postpos //get_from_stringarray exec - postglyphs postpos 1 add 2 index //getinterval_from_stringarray exec cvn - exch postpos add 1 add /postpos exch def - 2 index 3 1 roll - put - } for - /postnames exch def - numglyphs array 0 1 numglyphs 1 sub { - dup 2 mul 34 add postglyphs exch 2 //getinterval_from_stringarray exec - dup 0 get 8 bitshift exch 1 get add dup 258 lt { - MacGlyphEncoding exch get - } { - dup 32768 ge { - % According to the published TrueType spec, such values are - % "reserved for future use", but at least some PDF files - % produced by the Adobe PDF library contain entries with a - % value of 16#ffff. - pop /.notdef - } { - % Get the name for this glyph - 258 sub dup postnames length ge { - TTFDEBUG { ( *** warning: glyph index past end of 'post' table) = flush } if - pop - exit - } if - postnames exch get - % At least some of Microsoft's TrueType fonts use incorrect - % (Adobe-incompatible) names for some glyphs. - % Correct for this here. - postremap 1 index .knownget { exch pop } if - } ifelse - } ifelse - 2 index 3 1 roll put - } for - - } - ifelse - } bind - 16#00030000 { % No map. - pop [ ] - } bind -.dicttomark readonly def % postformats - -/first_post_string % - first_post_string <string> -{ - post dup type /arraytype eq { 0 get } if -} bind def - -% - .getpost - -% Uses post, defines glyphencoding -/.getpost { - /glyphencoding post null eq { - TTFDEBUG { (post missing) = flush } if [ ] - } { - postformats first_post_string 0 getu32 .knownget { - TTFDEBUG { - (post: format ) print - first_post_string - dup 0 getu16 =only (,) print 2 getu16 = flush - } if - post exch exec - } { - TTFDEBUG { (post: unknown format ) print post 0 getu32 = flush } if [ ] - } ifelse - } ifelse def -} bind def - -% ===================== True Type Interpretation ============= - -/TTParser << - /Pos 0 - /post null ->> def - -/readu8 % <file> readu8 <int> -{ read not { - mark (Insufficient data in the stream.) //error exec - } if -} bind def - -/readu16 % <file> readu16 <int> -{ dup //readu8 exec 8 bitshift exch //readu8 exec or -} bind def - -/reads16 % <file> reads16 <int> -{ //readu16 exec 16#8000 xor 16#8000 sub -} bind def - -/readu32 % <file> readu32 <int> -{ dup //readu16 exec 16 bitshift exch //readu16 exec or -} bind def - -/reads32 % <file> reads32 <int> -{ dup //reads16 exec 16 bitshift exch //readu16 exec or -} bind def - -/SkipToPosition % <file> <int> SkipToPosition - -{ dup //TTParser /Pos get % f P P p - exch //TTParser exch /Pos exch put % f P p - sub % f P-p - //PDFR_DEBUG { - (Skipping ) print dup //=only exec ( bytes.) = - } if - dup 0 eq { - pop pop - } { - dup 3 1 roll % P-p f P-p - () /SubFileDecode filter % P-p f' - exch % f' P-p - { 1 index //BlockBuffer readstring pop length - dup 0 eq { pop exch pop exit } if - sub - } loop - 0 ne { - mark (Insufficient data in the stream for SkipToPosition.) //error exec - } if - } ifelse -} bind def - -/TagBuffer 4 string def - -/ParseTTTableDirectory % <file> ParseTTTableDirectory <dict> -{ //PDFR_DEBUG { - (ParseTTTableDirectory beg) = - } if - 15 dict begin - dup //readu32 exec 16#00010000 ne { - mark (Unknown True Type version.) //error exec - } if - dup //readu16 exec /NumTables exch def - dup //readu16 exec /SearchRange exch def - dup //readu16 exec /EntrySelector exch def - dup //readu16 exec /RangeShift exch def - //PDFR_DEBUG { - (NumTables = ) print NumTables = - } if - NumTables { - dup //TagBuffer readstring not { - mark (Could not read TT tag.) //error exec - } if - cvn - [ 2 index //readu32 exec pop % CheckSum - 2 index //readu32 exec % Offset - 3 index //readu32 exec % Length - ] - //PDFR_DEBUG { - 2 copy exch //=only exec ( ) print == - } if - def - } repeat - pop % file - //TTParser /Pos 12 NumTables 16 mul add put - currentdict end - //PDFR_DEBUG { - (ParseTTTableDirectory end) = - } if -} bind def - -/ParseTTcmap % <file> <TableDirectory> ParseTTcmap <dict> -{ //PDFR_DEBUG { - (ParseTTcmap beg) = - } if - /cmap get aload pop % f o L - 3 1 roll % L f o - 7 dict begin - //PDFR_DEBUG { - (Current position = ) print //TTParser /Pos get = - (cmap position = ) print dup = - } if - 1 index exch //SkipToPosition exec % L f - //TTParser /Pos get /TablePos exch def - dup //readu16 exec pop % version - dup //readu16 exec /NumEncodings exch def - //PDFR_DEBUG { - (NumEncodings = ) print NumEncodings = - } if - null % L f null - NumEncodings { - 1 index //readu32 exec % platformID, specificID % L f null id - 2 index //readu32 exec % offset % L f null id o - 3 array dup 3 2 roll 0 exch put % L f []|null id [] - 2 index null ne { - dup 0 get 3 index 0 get sub % L f []|null id [] l - 3 index exch 1 exch put % L f []|null id [] - } if - dup 4 3 roll pop 3 1 roll % L f [] id [] - def - } repeat % L f [] - dup 0 get % L f [] o - 4 3 roll exch sub % f [] L-o - 1 exch put % f - //PDFR_DEBUG { - currentdict { - exch dup type /integertype eq { - //PrintHex exec ( ) print == - } { - pop pop - } ifelse - } forall - } if - 4 NumEncodings 8 mul add /HeaderLength exch def - //TTParser /Pos //TTParser /Pos get HeaderLength add put - 0 % f o - NumEncodings { - 16#7FFFFFF null % f o om null|[] - % Choosing a table with minimal offset greater than 'o' : - currentdict { - 1 index type /integertype eq { % f o om null|[] id [] - exch pop dup 0 get % f o om null|[] [] oi - dup 5 index gt { - dup 4 index lt { - 4 1 roll % f o oi om null|[] [] - exch pop exch pop % f o oi [] - } { - pop pop - } ifelse - } { - pop pop - } ifelse % f o oi [] - } { - pop pop - } ifelse - } forall % f o om' [] - //PDFR_DEBUG { - (Obtaining subtable for ) print dup == - } if - 3 2 roll pop % f o' [] - 3 copy pop % f o' [] f o' - TablePos add //SkipToPosition exec % f o' [] - 3 copy exch pop 1 get % f o' [] l - //TTParser /Pos //TTParser /Pos get 3 index add put - string % f o' [] f () - readstring not { - mark (Can't read a cmap subtable.) //error exec - } if % f o' [] () - 2 exch put % f o' - } repeat - pop pop % - currentdict end - //PDFR_DEBUG { - (ParseTTcmap end) = - } if -} bind def - -/GetTTEncoding % <file> <TTcmapHeader> <platformIDspecificID> GetTTEncoding <array> -{ //PDFR_DEBUG { - (GetTTEncoding beg) = - } if - get % f [] - exch pop % [] - 2 get - 10 dict begin % For local variables. - /TTFDEBUG //PDFR_DEBUG def - //cmaparray exec - end - //PDFR_DEBUG { - (GetTTEncoding end) = - dup == - } if -} bind def - -/InverseEncoding % <encoding> InverseEncoding <dict> -{ - 256 dict begin - dup length 1 sub -1 0 { % E i - 2 copy get % E i n - exch % E n i - 1 index currentdict exch //knownget exec { % E n i e - dup type /arraytype eq { - aload length 1 add array astore % E n e' - } { - 2 array astore % E n e' - } ifelse - } if - def - } for - pop - currentdict end -} bind def - -/GetMacRomanEncodingInverse -{ //PDFReader /MacRomanEncodingInverse get - dup null eq { - pop - MacRomanEncoding //InverseEncoding exec - dup //PDFReader exch /MacRomanEncodingInverse exch put - } if -} bind def - -/PutCharStringSingle % <cmap_array> <glyph_name> <char_code> PutCharStringSingle <cmap_array> -{ - dup 3 index length lt { % cmap name code - 2 index exch get % cmap name glyphindex - dup 0 ne { - def % cmap - } { - pop pop - } ifelse - } { - pop pop % cmap - } ifelse -} bind def - -/PutCharString % <cmap_array> <glyph_name> <char_code> PutCharString <cmap_array> -{ 1 index type /nametype ne { - mark (Bad charstring name) //error exec - } if - dup type /arraytype eq { - { % cmap name code - 3 copy //PutCharStringSingle exec % cmap name code cmap - pop pop % cmap name - } forall - pop % cmap - } { - //PutCharStringSingle exec - } ifelse -} bind def - -/ComposeCharStrings % <cmaparray> <dict> ComposeCharStrings <dict> -{ - //PDFR_DEBUG { - (ComposeCharStrings beg) = - } if - 1 index length 1 add dict begin % cmap d - % fixme : the dict length estimation doesn't account 'post'. - /.notdef 0 def - exch % d cmap - //TTParser /post get % d cmap [post]|null - dup null ne { - exch % d [] cmap - 1 index length 1 sub -1 0 { % d [] cmap code - dup 3 index exch get exch % d [] cmap name code - dup 0 eq 2 index /.notdef eq or { % do not re-encode GID 0, or the - % /.notdef glyph name - pop pop - } { - def - } ifelse - } for - } if - exch pop exch % cmap d - { % cmap name code - //PutCharString exec - } forall % cmap - pop % - currentdict end - //PDFR_DEBUG { - (ComposeCharStrings end) = - } if -} bind def - -/ParseTTpost % <file> <TableDirectory> ParseTTpost - -{ % Defines TTparser.post - an array, - % which maps glyph indices to glyph names. - //PDFR_DEBUG { - (ParseTTpost beg) = - } if - /post get aload pop % f o L - 3 1 roll % L f o - //PDFR_DEBUG { - (Current position = ) print //TTParser /Pos get = - (post position = ) print dup = - } if - 1 index exch //SkipToPosition exec % L f - //TTParser /Pos //TTParser /Pos get 4 index add put - exch dup 65535 le { - string % f s - readstring not { - mark (Insufficient data in the stream for ParseTTpost.) //error exec - } if % s - } { - % f s - [ 3 1 roll % [ f s - dup 16384 div floor cvi % [ f s numblocks - exch 1 index 16384 mul % [ f numblocks s bytesinblocks - sub exch % [ f remainder numblocks - 1 sub 0 1 3 -1 roll % [ f remainder 0 1 numblocks - { - 1 add index % [ f remainder () ()... f - 16384 string readstring not { - mark (Insufficient data in the stream for ParseTTpost.) //error exec - } if - } for - % [ f remainder () ()... - counttomark -2 roll % [ () ()... f remainder - string readstring not{ - mark (Insufficient data in the stream for ParseTTpost.) //error exec - } if - ] - } ifelse - 1 dict begin % A bridge to the code from /gs/lib/gs_ttf.ps . - /post exch def - //.getpost exec - //TTParser /post glyphencoding put - //PDFR_DEBUG { - (ParseTTpost end) = - glyphencoding == - } if - end -} bind def - -/MakeTTCharStrings % <FontFile_object> MakeTTCharStrings <CharStrings> -{ //MakeStreamReader exec % f - dup dup //ParseTTTableDirectory exec % f f d - % Since the file isn't positionable, - % we must pick up either 'post' or 'cmap' first. - % Deside which one we do first : - //TTParser /post null put - dup /post //knownget exec { - 0 get - 1 index /cmap get 0 get - lt { - 2 copy //ParseTTpost exec % f f d - //ParseTTcmap exec % f ch - } { - 2 copy //ParseTTcmap exec % f f d ch - 3 1 roll % f ch f d - //ParseTTpost exec % f ch - } ifelse - } { - //ParseTTcmap exec % f ch - } ifelse - { - dup 16#00030001 known { - //PDFR_DEBUG { - (Using the TT cmap encoding for Windows Unicode.) = - } if - 16#00030001 //GetTTEncoding exec - AdobeGlyphList //ComposeCharStrings exec - exit - } if - dup 16#00010000 known { - //PDFR_DEBUG { - (Using the TT cmap encoding for Macintosh Roman.) = - } if - 16#00010000 //GetTTEncoding exec - PDFEncoding dup null eq { - pop //GetMacRomanEncodingInverse exec - } { - //InverseEncoding exec - } ifelse - //ComposeCharStrings exec - exit - } if - dup 16#00030000 known { - //PDFR_DEBUG { - (Using the TT cmap encoding 3.0 - not sure why Ghostscript writes it since old versions.) = - } if - % Same algorithm as for 16#00010000. - 16#00030000 //GetTTEncoding exec - PDFEncoding dup null eq { - pop //GetMacRomanEncodingInverse exec - } { - //InverseEncoding exec - } ifelse - //ComposeCharStrings exec - exit - } if - mark (True Type cmap has no useful encodings.) //error exec - } loop - //PDFR_DEBUG { - (CharStrings <<) = - dup { - exch - dup type /nametype eq { - //=only exec - } { - == - } ifelse - ( ) print == - } forall - (>>) = - } if -} bind def - -%%end TrueType - -% ===================== Functions ============================ - -/ScaleVal % <value> <Range> ScaleVal <scaled_value> -{ - aload pop % v r0 r1 - 1 index sub % v r0 r1-r0 - 3 2 roll mul add -} bind def - -/ScaleArg % <arg> <Domain> ScaleArg <scaled_arg> -{ - aload pop % a d0 d1 - 1 index sub % a d0 d1-d0 - 3 1 roll % d1-d0 a d0 - sub exch div % (a-d0)/(d1-d0) -} bind def - -/ScaleArgN % <arg1> ... <argN> <Domain> ScaleArg <scaled_arg1> ... <scaled_argN> -{ - dup length 2 sub -2 0 { % a1 ... an [] 2i - 2 % a1 ... an [] 2i 2 - 2 index 3 1 roll getinterval % a1 ... an [] [] - 3 2 roll % a1 ... [] [] an - exch //ScaleArg exec % a1 ... [] an' - 1 index length 2 idiv 1 add 1 roll % an' a1 ... [] - } for % a1' ... an' [] - pop % a1' ... an' -} bind def - - -/ComputeFunction_10 % <scaled_arg> <sample_array> ComputeFunction_10 <result> -{ % Assuming a 1-argument 1-result function type 0. - //PDFR_DEBUG { - (ComputeFunction_10 beg ) print 1 index //=only exec ( stack=) print count = - } if - exch % [] x - dup 1 eq { - pop dup length 1 sub get % y - } { - 1 index length 1 sub mul % [] x*(l-1) - dup dup floor sub % [] x*(l-1) f - dup 0 eq { - pop cvi get % y - } { - 3 1 roll floor cvi % f [] i - 2 getinterval % f [] - aload pop % f y0 y1 - 2 index mul 3 2 roll 1 exch sub 3 2 roll mul add % y1*f+(1-f)*y0 - } ifelse - } ifelse - //PDFR_DEBUG { - (ComputeFunction_10 end ) print dup //=only exec ( stack=) print count = - } if -} bind def - -/ComputeFunction_n0 % <arg1> .... <argn> <sample_array> <n> ComputeFunction_n0 <result> -{ % Assuming a n-argument 1-result function type 0. - //PDFR_DEBUG { - (ComputeFunction_n0 beg N=) print dup //=only exec ( stack=) print count = - } if - dup 0 eq { % v 0 - pop % v - } { - dup 2 add -1 roll % a2 .... an [] n a1 - dup 3 index length 1 sub ge { - pop 1 sub % a2 .... an [] n-1 - exch dup length 1 sub get exch - //PDFReader /ComputeFunction_n0 get exec - } { - dup floor cvi dup % a2 .... an [] n a1 i i - 4 index exch get % a2 .... an [] n a1 i [i] - 3 index dup % a2 .... an [] n a1 i [i] n n - 5 add copy % a2 .... an [] n a1 i [i] n a2 .... an [] n a1 i [i] n - 6 2 roll % a2 .... an [] n a1 i [i] n a2 .... an [i] n [] n a1 i - pop pop pop pop % a2 .... an [] n a1 i [i] n a2 .... an [i] n - 1 sub % a2 .... an [] n a1 i [i] n a2 .... an [i] n-1 - //PDFReader /ComputeFunction_n0 get exec % a2 .... an [] n a1 i [i] n v0 - 3 2 roll pop % a2 .... an [] n a1 i n v0 - exch % a2 .... an [] n a1 i v0 n - 4 3 roll exch % a2 .... an [] n i v0 a1 n - 4 add 2 roll 1 add % v0 a1 a2 .... an [] n i+1 - 3 2 roll exch get % v0 a1 a2 .... an n [i+1] - exch 1 sub % v0 a1 a2 .... an [i+1] n-1 - //PDFReader /ComputeFunction_n0 get exec % v0 a1 v1 - 1 index mul % v0 a1 v1*a1 - 3 1 roll % v1*a1 v0 a1 - 1 exch sub mul add % v1*a1+v0*(1-a1) - } ifelse - } ifelse - //PDFR_DEBUG { - (ComputeFunction_n0 end ) print dup //=only exec ( stack=) print count = - } if -} bind def - -/FunctionToProc_x01 % <function_dict> FunctionToProc_x01 <proc> -{ % Assuming a n-argument 1-result function type 0. - % The stream is already converted to the array /Data. - dup /Domain get exch - dup /Data get 0 get exch - /Size get length - [ 4 1 roll - //PDFR_DEBUG { - { (function beg, stack =) print count //=only exec (\n) print } /exec load - 5 2 roll - } if - dup 1 gt { % a1 ... an Domain Data n - { mark exch % a1 ... an Domain Data [ n - 3 add 2 roll % Data [ a1 ... an Domain - //ScaleArgN exec % Data [ a1 ... an - counttomark dup % Data [ a1 ... an n n - 3 add -2 roll % a1 ... an n Data [ - pop exch % a1 ... an Data n - //ComputeFunction_n0 exec - } /exec load - } { - pop % a1 Domain Data - 3 1 /roll load //ScaleArg /exec load % Data a1s - /exch load - //ComputeFunction_10 /exec load - } ifelse - //PDFR_DEBUG { - (function end, stack =) /print load /count load //=only /exec load (\n) /print load - } if - ] cvx - //PDFR_DEBUG { - (Made a procedure for the 1-result function :) = - dup == - } if -} bind def - -/FunctionProcDebugBeg % - FunctionProcDebugBeg - -{ (FunctionProcDebugBeg ) print count = -} bind def - -/FunctionProcDebugEnd % - FunctionProcDebugEnd - -{ (FunctionProcDebugEnd ) print count = -} bind def - -/FunctionToProc_x0n % <function_dict> <m> FunctionToProc_x0n <proc> -{ % Assuming a n-argument m-result function type 0. - % The stream is already converted to the array /Data. - % - % Making the procedure : { Domain //ScaleArg exec ... n copy {} exec n+1 1 roll ... } - % except "n copy" for the last chunk. - % - PDFR_DEBUG { - (FunctionToProc_x0n beg m=) print dup = - } if - 1 index /Size get length exch % f n m - dup 7 mul 2 add array % f n m [] - PDFR_DEBUG { - dup 0 //FunctionProcDebugBeg put - } { - dup 0 //DoNothing put - } ifelse - dup 1 /exec load put - dup 2 5 index /Domain get put - 2 index 1 eq { - dup 3 //ScaleArg put - } { - dup 3 //ScaleArgN put - } ifelse - dup 4 /exec load put - 1 index 1 sub 0 exch 1 exch { % f n m [] i - dup 7 mul 5 add % f n m [] i i1 - 1 index 4 index 1 sub ne { - dup 3 index exch 6 index put 1 add - dup 3 index exch /copy load put 1 add - } if - [ % f n m [] i i1 [ - 6 index /Data get 3 index get % f n m [] i i1 [ di - 6 index 1 eq { - //ComputeFunction_10 /exec load - } { - 6 index - //ComputeFunction_n0 /exec load - } ifelse - ] cvx % f n m [] i i1 {} - 3 index exch 2 index exch put 1 add % f n m [] i i1 - 2 index 1 index /exec load put 1 add - 1 index 4 index 1 sub ne { - 2 index 1 index 6 index 1 add put 1 add - 2 index 1 index 1 put 1 add - 2 index 1 index /roll load put % f n m [] i i1 - } if - pop pop % f n m [] - } for - PDFR_DEBUG { - dup dup length 2 sub //FunctionProcDebugEnd put - } { - dup dup length 2 sub //DoNothing put - } ifelse - dup dup length 1 sub /exec load put - cvx exch pop exch pop exch pop - //PDFR_DEBUG { - (Made a procedure for the n-argument function :) = - dup == - } if - PDFR_DEBUG { - (FunctionToProc_x0n end) = - } if -} bind def - -/MakeTableRec % <func_obj> <n> MakeTableRec <array> -{ - 0 % to be bound below - exec -} bind def - -/MakeTable % <func_obj> <n> MakeTable <array> -{ //PDFR_DEBUG { - (MakeTable beg ) print count = - } if - 1 index /Size get exch % f S N - 1 sub dup % f S n n - 3 1 roll % f n S n - get % f n s - array % f n [] - 1 index 0 eq { - exch pop exch pop % [] - } { - dup length 1 sub -1 0 { % f n [] i - 3 index 3 index //MakeTableRec exec % f n [] i [] - 2 index 3 1 roll put % f n [] - } for - exch pop exch pop - } ifelse - //PDFR_DEBUG { - (MakeTable end ) print count = - } if -} bind def - -//MakeTableRec 0 //MakeTable put - -/StoreSample % <value> <table> <dimensions> StoreSample - -{ % The reader is on the dictionary stack. - 1 sub - dup 0 eq { - pop % v [] - } { - -1 1 { % v T i - I exch get get % v T[I[i]] - } for % v [] - } ifelse - I 0 get 3 2 roll put -} bind def - -/ReadSample32 % - ReadSample32 <value> -{ - 4 { - File read not { - mark (Insufficient data for function.) //error exec - } if - } repeat - pop % Ignore the last byte because it can't fit into 'real'. - 3 1 roll exch - 256 mul add 256 mul add - //1_24_bitshift_1_sub div -} bind def - -/ReadSample % - ReadSample <value> -{ % The reader in on the dictionary stack. - Buffer BitsLeft BitsPerSample - { 2 copy ge { - exit - } if - 3 1 roll - 8 add 3 1 roll - 256 mul File read not { - mark (Insufficient data for function.) //error exec - } if - add - 3 1 roll - } loop % b bl pbs - sub dup % b bl-bps bl-bps - 2 index exch % b bl-bps b bl-bps - neg bitshift % b bl-bps v - 2 copy exch bitshift % b bl-bps v v<<(bl-bps) - 4 3 roll exch sub % bl-bps v b-(v<<(bl-bps)) - /Buffer exch def % bl-bps v - exch /BitsLeft exch def % v - Div div % v/(1<<pbs-1) -} bind def - -/ReadSamplesRec % <dimensions> ReadSamplesRec - -{ 0 % Will be bound below - exec -} bind def - -/ReadSamples % <dimensions> ReadSamples - -{ % The reader in on the dictionary stack. - //PDFR_DEBUG { - (ReadSamples beg ) print count = - } if - dup 1 eq { - pop - 0 1 Size 0 get 1 sub { - I exch 0 exch put - 0 1 M 1 sub { - dup Range exch 2 mul 2 getinterval % m r - //PDFR_DEBUG { - (Will read a sample ... ) print - } if - BitsPerSample 32 eq { //ReadSample32 } { //ReadSample } ifelse - exec exch //ScaleVal exec % m v - //PDFR_DEBUG { - (value=) print dup = - } if - exch Table exch get % v [] - Size length //StoreSample exec % - } for - } for - } { - 1 sub - dup Size exch get 0 exch 1 exch 1 sub { % d-1 i - I exch 2 index exch put % d-1 - dup //ReadSamplesRec exec % d-1 - } for - pop - } ifelse - //PDFR_DEBUG { - (ReadSamples end ) print count = - } if -} bind def - -//ReadSamplesRec 0 //ReadSamples put - -/StreamToArray % <obj> StreamToArray - -{ //PDFR_DEBUG { - (StreamToArray beg ) print count = - } if - userdict /FuncDataReader get begin % f - dup /BitsPerSample get /BitsPerSample exch def - dup /Size get length /N exch def - dup /Range get length 2 idiv /M exch def - 1 BitsPerSample bitshift 1 sub /Div exch def - /BitsLeft 0 def - /Buffer 0 def - dup /Size get /Size exch def % f - dup /Range get /Range exch def % f - /File 1 index //MakeStreamReader exec def % f - /I [ N { 0 } repeat ] def % f - M array % f [] - dup length 1 sub -1 0 { % f [] m - 2 index N //MakeTable exec % f [] m T - 2 index 3 1 roll put % f [] - } for - /Table exch def % f - N //ReadSamples exec % f - PDFR_DEBUG { - (Table = ) print Table == - } if - /Data Table put % - end - //PDFR_DEBUG { - (StreamToArray end ) print count = - } if -} bind def - -/FunctionToProc10 % <function_dict> FunctionToProc10 <proc> -{ % Assuming a 1-argument function type 0. - PDFR_DEBUG { - (FunctionToProc10 beg, Range = ) print dup /Range get == - } if - dup /Order //knownget exec { - 1 ne { - (Underimplemented function Type 0 Order 3.) = - } if - } if - dup //StreamToArray exec % f - dup /Range get length dup 2 eq { - pop //FunctionToProc_x01 exec % proc - } { - 2 idiv //FunctionToProc_x0n exec % proc - } ifelse - PDFR_DEBUG { - (FunctionToProc10 end) = - } if -} bind def - -/FunctionToProc12 % <function_dict> FunctionToProc12 <proc> -{ begin - currentdict /C0 //knownget exec { length 1 eq } { true } ifelse { - N - currentdict /C0 //knownget exec { - 0 get - } { - 0 - } ifelse - currentdict /C1 //knownget exec { - 0 get - } { - 1 - } ifelse - 1 index sub - [ 4 1 roll - { % x n c0 c1-c0 - 4 2 roll % c0 c1-c0 x n - excp mul add % y - } aload pop - ] cvx - } { - [ - 0 1 C0 length 1 sub { - N % [ ... i n - C0 2 index get % [ ... i n c0 - C1 3 index get % [ ... i n c0 c1 - 4 3 roll pop % [ ... n c0 c1 - 1 index sub % [ ... n c0 c1-c0 - [ /dup load % [ ... n c0 c1-c0 [ dup - 5 2 roll % [ ... [ dup n c0 c1-c0 - { % x x n c0 c1-c0 - 4 2 roll % x c0 c1-c0 x n - exp mul add % x y - exch % y x - } aload pop - ] cvx - /exec load - } for - /pop load - ] cvx - } ifelse - end - //PDFR_DEBUG { - (FunctionType2Proc : ) print dup == - } if -} bind def - - -/FunctionToProc14 % <function_dict> FunctionToProc14 <proc> -{ //MakeStreamReader exec cvx exec - //PDFR_DEBUG { - (FunctionType4Proc : ) print dup == - } if -} bind def - -/FunctionToProc1 % <function_dict> FunctionToProc <proc> -{ % Assuming a 1-argument function. - dup /FunctionType get - { dup 0 eq { - pop //FunctionToProc10 exec exit - } if - dup 2 eq { - pop //FunctionToProc12 exec exit - } if - dup 4 eq { - pop //FunctionToProc14 exec exit - } if - mark exch (Function type ) exch ( isn't implemented yet.) //error exec - } loop -} bind def - -/FunctionToProc20 % <function_dict> FunctionToProc20 <proc> -{ % Assuming a 2-argument function type 0. - PDFR_DEBUG { - (FunctionToProc20, Range = ) print dup /Range get == - } if - dup /Order //knownget exec { - 1 ne { - (Underimplemented function Type 0 Order 3.) = - } if - } if - dup //StreamToArray exec % f - dup /Range get length dup 2 eq { - pop //FunctionToProc_x01 exec % proc - } { - 2 idiv //FunctionToProc_x0n exec % proc - } ifelse -} bind def - -/FunctionToProc % <function_dict> FunctionToProc <proc> -{ //PDFR_DEBUG { - (FunctionToProc beg ) print count = - } if - dup type /dicttype eq { - dup /Domain get length 2 idiv - { - dup 1 eq { - pop //FunctionToProc1 exec exit - } if - dup 2 eq { - pop //FunctionToProc20 exec exit - } if - mark (Functions with many arguments aren't implemented yet.) //error exec - } loop - } { - //PDFR_DEBUG {(Not a function dict, assume already a procedure.) print } if - } ifelse - //PDFR_DEBUG { - (FunctionToProc end ) print count = - } if -} bind def - -/spotfunctions mark % Copied from pdf_draw.ps - /Round { - abs exch abs 2 copy add 1 le { - dup mul exch dup mul add 1 exch sub - } { - 1 sub dup mul exch 1 sub dup mul add 1 sub - } ifelse - } - /Diamond { - abs exch abs 2 copy add .75 le { - dup mul exch dup mul add 1 exch sub - } { - 2 copy add 1.23 le { - .85 mul add 1 exch sub - } { - 1 sub dup mul exch 1 sub dup mul add 1 sub - } ifelse - } ifelse - } - /Ellipse { - abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt { - pop dup mul exch .75 div dup mul add 4 div 1 exch sub - } { - dup 1 gt { - pop 1 exch sub dup mul exch 1 exch sub - .75 div dup mul add 4 div 1 sub - } { - .5 exch sub exch pop exch pop - } ifelse - } ifelse - } - /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub } - /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub } - /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub } - /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub } - /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub } - /Line { exch pop abs neg } - /LineX { pop } - /LineY { exch pop } - /Square { abs exch abs 2 copy lt { exch } if pop neg } - /Cross { abs exch abs 2 copy gt { exch } if pop neg } - /Rhomboid { abs exch abs 0.9 mul add 2 div } - /DoubleDot { 2 {360 mul sin 2 div exch } repeat add } - /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg } - /SimpleDot { dup mul exch dup mul add 1 exch sub } - /InvertedSimpleDot { dup mul exch dup mul add 1 sub } - /CosineDot { 180 mul cos exch 180 mul cos add 2 div } - /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add } - /InvertedDouble { - exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg - } -.dicttomark readonly def - -% ===================== Color Spaces and Colors ============== - -/CheckColorSpace % <key> <val> CheckColorSpace <key> <val> -{ - dup type /arraytype ne { - mark (Resource ) 3 index ( must be an array.) //error exec - } if -} bind def - -/SubstitutePDFColorSpaceRec % <array> SubstitutePDFColorSpace <array> -{ 0 % Will be bound below - exec -} bind def - -/SubstitutePDFColorSpace % <array> SubstitutePDFColorSpace <array> -{ - { - dup 0 get /Pattern eq { - dup length 1 gt { - dup dup 1 //CheckColorSpace //ResolveA exec - dup type /nametype ne { - //SubstitutePDFColorSpaceRec exec - } if - 1 exch put - } if - exit - } if - dup 0 get /Indexed eq { - exit - } if - dup 0 get /Separation eq { - dup dup 2 //CheckColorSpace //ResolveA exec - dup type /nametype ne { - //SubstitutePDFColorSpaceRec exec - } if - 2 exch put - exit - } if - dup 0 get /CalGray eq { - 1 get % dict - dup /Gamma //knownget exec { - [ exch [ exch /exp load ] cvx dup dup ] - 1 index exch /DecodeLMN exch put - } if - [ exch /CIEBasedA exch ] % [] - exit - } if - dup 0 get /CalRGB eq { - 1 get % dict - dup /Matrix //knownget exec { - 1 index exch /MatrixLMN exch put - } if - dup /Gamma //knownget exec { - aload pop - [ exch /exp load ] cvx - 3 1 roll - [ exch /exp load ] cvx - 3 1 roll - [ exch /exp load ] cvx - 3 1 roll - 3 array astore - 1 index exch /DecodeLMN exch put - } if - [ exch /CIEBasedABC exch ] % [] - exit - } if - dup 0 get /Lab eq { - 1 get % dict - begin - currentdict /Range //knownget exec { aload pop } { -100 100 -100 100 } ifelse - 0 100 6 2 roll 6 array astore - /RangeABC exch def - /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind] def - /MatrixABC [1 1 1 1 0 0 0 0 -1] def - { dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } - /DecodeLMN [ - % Store white point implicitly inside procedures. - [ 3 index aload pop WhitePoint 0 get /mul load ] cvx - [ 4 index aload pop WhitePoint 1 get /mul load ] cvx - [ 5 index aload pop WhitePoint 2 get /mul load ] cvx - ] def pop - //PDFR_DEBUG { - (Constructed from Lab <<) = - currentdict { exch = == } forall - (>>) = - } if - [ /CIEBasedABC currentdict ] % [] - end - exit - pop - } if - % Check if this is an already substituted space - dup 0 get /CIEBasedA eq {exit} if - dup 0 get /CIEBasedABC eq {exit} if - mark exch (Unimplemented color space ) exch //error exec - } loop -} bind def - -//SubstitutePDFColorSpaceRec 0 //SubstitutePDFColorSpace put - -/ResolveArrayElement % <array> <index> ResolveArrayElement <array> -{ 2 copy get - dup type dup /arraytype eq exch - /packedarraytype eq or { % make sure its a procedure/executable array - xcheck { - 2 copy get % Get executable array - dup 0 get type /integertype eq % ensure first element is an integer - 1 index 1 get type dup /arraytype - eq exch - /packedarraytype eq or % ensure second element is executable array - and { - exec - 2 index 4 1 roll put - } { - pop pop - } ifelse - } { - pop - } ifelse - } { - pop pop - } ifelse -} bind def - -/ResolveColorSpaceArrayRec % <color_space> ResolveColorSpaceArrayRec <color_space> -{ 0 % Will be bond below. - exec -} bind def - -/SetColorSpaceSafe % <color_space> SetColorSpaceSafe - -{ - % This works against applying a pattern over a pattern space, - % which may happen due to duplication of stroking and non-stroking colors. - % gs3.70 fails when setting a pattern space and - % the (old) current color space is a pattern space. - % - % If the new color space is an array and it appears equal to the old one, - % do nothing. Otherwise set the new color space. - PDFR_DEBUG { - (SetColorSpaceSafe beg) = - } if - currentcolorspace dup type /arraytype eq { % cs cs' - 1 index type /arraytype eq { - dup length 2 index length eq { - false exch % cs b cs' - dup length 0 exch 1 exch 1 sub { % cs b cs' i - dup % cs b cs' i i - 4 index exch get exch % cs b cs' csi i - 2 index exch get % cs b cs' csi cs'i - ne { % cs b cs' - exch pop true exch exit - } if - } for % cs b cs' - pop % cs b - { - setcolorspace - } { - pop - } ifelse % - } { - pop setcolorspace - } ifelse - } { - pop setcolorspace - } ifelse - } { % cs cs' - pop setcolorspace - } ifelse - PDFR_DEBUG { - (SetColorSpaceSafe end) = - } if -} bind def - -/ResolveColorSpaceArray % <color_space> ResolveColorSpaceArray <color_space> -{ - //PDFR_DEBUG { - (ResolveColorSpaceArray beg ) print dup == - } if - dup 0 get /Indexed eq { - 1 //ResolveArrayElement exec - dup dup 1 get - dup type /arraytype eq { - //SubstitutePDFColorSpace exec - //ResolveColorSpaceArrayRec exec - 1 exch put - } { - pop pop - } ifelse - } if - dup 0 get /Separation eq { - 3 //ResolveArrayElement exec - dup 3 get //FunctionToProc exec - 2 copy 3 exch put - pop - } if - dup 0 get/Pattern eq{ - dup length 1 gt { - dup dup 1 get dup type /arraytype eq { - ResolveColorSpaceArray - 1 index 1 3 -1 roll put - }{ - pop - }ifelse - }if - }if - PDFR_DEBUG { - (Construcrted color space :) = - dup == - } if - //PDFR_DEBUG { - (ResolveColorSpaceArray end ) print dup == - } if -} bind def - -//ResolveColorSpaceArrayRec 0 //ResolveColorSpaceArray put - -/ResolveColorSpace % <name> ResolveColorSpace <color_space> -{ - //PDFR_DEBUG { - (ResolveColorSpace beg ) print dup = - } if - dup //SimpleColorSpaceNames exch known not { - dup //PDFColorSpaces exch //knownget exec { - exch pop - //PDFR_DEBUG { - (ResolveColorSpace known ) = - } if - } { - dup % n n - //PDFReader /CurrentObject get /Context get /Resources get - /ColorSpace //DoNothing //ResolveD exec - exch //CheckColorSpace //ResolveD exec % n cs - dup type /arraytype eq { - //SubstitutePDFColorSpace exec - //ResolveColorSpaceArray exec - dup //PDFColorSpaces 4 2 roll put % [] - } if - } ifelse - } if - //PDFR_DEBUG { - (ResolveColorSpace end ) print dup == - } if -} bind def - -/CheckPattern % <key> <val> CheckPattern <key> <val> -{ - dup /PatternType //knownget exec { - dup 1 ne { - mark (Resource ) 4 index ( is a shading, which can't be handled at level 2. ) //error exec - } if - pop - } if - dup /Type knownget { % /Type is optional for type 1 pattern dictionaries - /Pattern ne { - mark (Resource ) 4 index ( must have /Type/Pattern .) //error exec - } if - } if -} bind def - -/PaintProc % -{ /Context get % pattern_object - //RunDelayedStream exec -} bind def - -/ResolvePattern % <name> ResolvePattern <pattern> -{ - dup % n n - % Since makepattern makes a local dictionary, - % we cahche them in userdict, which is in local VM. - % Assuming unique resource name through the document - userdict /PDFR_Patterns get % n n d - exch //knownget exec { % n p - exch pop % p - } { % n - dup % n n - //PDFReader /CurrentObject get /Context get /Resources get - /Pattern //DoNothing //ResolveD exec - exch //CheckPattern //ResolveD exec % n o - dup dup /Context exch put - dup /Resources //DoNothing //ResolveD exec pop - dup /PaintProc //PaintProc put - gsave userdict /PDFR_InitialGS get setgstate - currentglobal exch false setglobal % gs3_70 compatibility - dup /Matrix get - makepattern % n p - exch setglobal % gs3_70 compatibility - grestore - dup userdict /PDFR_Patterns get % n p p d - 4 2 roll % p d n p - put % p - } ifelse -} bind def - -/SetColor % Same arguments and result as for scn -{ //PDFR_DEBUG { - (SetColor beg) = - } if - currentcolorspace dup type /nametype eq { - pop setcolor - } { - 0 get /Pattern eq { - //ResolvePattern exec setpattern - } { - setcolor - } ifelse - } ifelse - //PDFR_DEBUG { - (SetColor end) = - } if -} bind def - -% ===================== Images =============================== - -/ImageKeys 15 dict begin - /BPC /BitsPerComponent def - /CS /ColorSpace def - /D /Decode def - /DP /DecodeParms def - /F /Filter def - /H /Height def - /IM /ImageMask def - % /Intent is undefined - pdfwrite must take care of. - /I /Interpolate def - /W /Width def -currentdict end readonly def - -/ImageValues 15 dict begin - /G /DeviceGray def - /RGB /DeviceRGB def - /CMYK /DeviceCMYK def - /I /Indexed def - /AHx /ASCIIHexDecode def - /A85 /ASCII85Decode def - /LZW /LZWDecode def - /Fl /FlateDecode def - /RL /RunLengthDecode def - /CCF /CCITTFaxDecode def - /DCT /DCTDecode def -currentdict end readonly def - -/GetColorSpaceRange -{ 2 index /ColorSpace get - dup type /arraytype eq { - 1 get - } if - exch //knownget exec { - exch pop - } if -} bind def - -/DecodeArrays 15 dict begin - /DeviceGray { [0 1] } def - /DeviceRGB { [0 1 0 1 0 1] } def - /DeviceCMYK { [0 1 0 1 0 1 0 1] } def - /Indexed { - dup /BitsPerComponent get 1 exch bitshift 1 sub [exch 0 exch] - } def - /Separation { [0 1] } def - /CIEBasedA { [0 1] /RangeA //GetColorSpaceRange exec } def - /CIEBasedABC { [0 1 0 1 0 1] /RangeABC //GetColorSpaceRange exec } def -currentdict end readonly def - -/Substitute % <key> <dict> Substitute <key> -{ 1 index //knownget exec { - exch pop - } if -} bind def - -/DebugImagePrinting % <image_dict> DebugImagePrinting <image_dict> -{ - //PDFR_DEBUG { - (Image :) = - dup { exch //=only exec ( ) print == - } forall - } if -} bind def - -/CompleteImage % <dict> CompleteImage <image_dict> -{ - dup /ColorSpace known { - dup /ColorSpace //CheckColorSpace //ResolveD exec pop - } if - dup /Decode known not { - dup /ColorSpace //knownget exec { - dup type /arraytype eq { - 0 get - } if - //DecodeArrays exch get exec - } { - [0 1] - } ifelse - 1 index exch /Decode exch put - } if - dup /ImageMatrix [2 index /Width get 0 0 5 index /Height get neg - 0 7 index /Height get] put % Not sure why upside down ? - //DebugImagePrinting exec -} bind def - -/CompleteInlineImage % <dict> CompleteInlineImage <image_dict> -{ - //PDFR_DEBUG { - (CompleteInlineImage beg) = - } if - dup /ImageType known not { - dup /ImageType 1 put - } if - dup length dict exch { % d key val - exch //ImageKeys //Substitute exec - dup /Filter eq { - exch //ImageValues //Substitute exec exch - } if - dup /ColorSpace eq { - exch - dup //ImageValues exch //knownget exec { - exch pop - } { - //ResolveColorSpace exec - } ifelse - exch - } if - exch - 2 index 3 1 roll put - } forall - //CompleteImage exec - dup /DataSource 2 copy get % d d /n f - 2 index //AppendFilters exec put - //PDFR_DEBUG { - (CompleteInlineImage end) = - } if -} bind def - -/CompleteOutlineImage % <dict> CompleteOutlineImage <image_dict> -{ - currentglobal exch dup gcheck setglobal - //PDFR_DEBUG { - (CompleteOutlineImage beg) = - } if - % todo: ResetStreamReader if DataSource already exists. - dup dup //MakeStreamReader exec /DataSource exch put - dup /ImageType known not { - //CompleteImage exec - dup /ImageType 1 put - dup /ColorSpace known { - dup /ColorSpace //CheckColorSpace //ResolveD exec - dup type /arraytype eq { - //ResolveColorSpaceArray exec - //SubstitutePDFColorSpace exec - 1 index exch /ColorSpace exch put - } { - pop - } ifelse - } if - } if - //PDFR_DEBUG { - (CompleteOutlineImage end) = - } if - exch setglobal -} bind def - -/DoImage % <image_dict> DoImage - -{ - //PDFR_DEBUG { - (DoImage beg) = - } if - gsave - dup /ColorSpace //knownget exec { setcolorspace } if - dup /ImageMask //knownget exec not { false } if - { imagemask } { image } ifelse - grestore - //PDFR_DEBUG { - (DoImage end) = - } if -} bind def - -% ===================== Viewer State =============== - -/GSave % - GSave - -{ - gsave - //PDFReader /GraphicStateStackPointer get - dup //GraphicStateStack exch get null eq { - dup //GraphicStateStack exch //InitialGraphicState length dict put - } if - dup //GraphicStateStack exch get - //GraphicState exch copy pop - 1 add //PDFReader exch /GraphicStateStackPointer exch put -} bind def - -/GRestore % - GRestore - -{ - grestore - //PDFReader /GraphicStateStackPointer get - 1 sub dup - //PDFReader exch /GraphicStateStackPointer exch put - //GraphicStateStack exch get - //GraphicState copy pop -} bind def - - -% ===================== Interpret Data Streams =============== - -/SetFont % <resource_name> <size> SetFont - -{ dup //GraphicState exch /FontSize exch put - //ResolveAndSetFont exec - //GraphicState /FontMatrixNonHV currentfont /FontMatrix get 1 get 0 ne put -} bind def - -/ShowText % <string> ShowText - -{ //GraphicState /TextRenderingMode get 0 eq { - //GraphicState /WordSpacing get 0 - 32 - //GraphicState /CharacterSpacing get 0 - 6 5 roll - //GraphicState /FontMatrixNonHV get { - % Use xshow to force wy in text space to be 0 (PDF1.7 5.3.3 "Text Space Details") - %stack: wordspacing_wx wordspacing_wy space_char charspacing_wx charspacing_wy string - [ % wwx wwy sp cwx cwy str [ - 7 -2 roll pop % sp cwx cwy str [ ww - 5 -2 roll pop % sp str [ ww cw - 5 -1 roll % str [ ww cw sp - { % str [ ... ww cw sp c wx wy - exch % will be removed, unless FontMatrix.xx == 0 (FontMatrixNonHV already true) - pop % str [ ... ww cw sp c w - 3 index add % str [ ... ww cw sp c w+cw - exch 2 index eq { 3 index add } if % str [ ... ww cw sp w+cw[+ww] - 4 1 roll % str [ ... w+cw[+ww] ww cw sp - } - currentfont /FontMatrix get 0 get 0 ne { - 1 1 index length 1 sub getinterval cvx % drop the "exch" - } if - 5 index % str [ ww cw sp {cshowproc} str - cshow % str [ widths... ww cw sp - pop pop pop ] % str [widths...] - xshow - } { - awidthshow - } ifelse - } { - //GraphicState /CharacterSpacing get 0 eq - //GraphicState /FontMatrixNonHV get not and - //GraphicState /WordSpacing get 0 eq and { - true charpath - } { - % Emulate with "{ charpath } cshow". - % Not sure how it works with CID fonts. - { % c wx wy - exch % will be removed, unless FontMatrixNonHV && FontMatrix.xx == 0 - pop 0 % (PDF1.7 5.3.3 "Text Space Details") - currentpoint 5 4 roll % wx wy x y c - ( ) dup 0 3 index put true charpath % wx wy x y c - 5 1 roll % c wx wy x y - moveto rmoveto % c - //GraphicState /CharacterSpacing get 0 rmoveto % c - 32 eq { % - //GraphicState /WordSpacing get 0 rmoveto - } if - } - //GraphicState /FontMatrixNonHV get dup not exch { - pop currentfont /FontMatrix get 0 get 0 ne - } if { - 1 1 index length 1 sub getinterval cvx - } if - exch cshow - } ifelse - } ifelse -} bind def - -/ShowTextBeg % - ShowTextBeg - -{ //GraphicState /TextRenderingMode get 0 ne { - currentpoint newpath moveto - } if -} bind def - -/ShowTextEnd % - ShowTextEnd - -{ //GraphicState /TextRenderingMode get - { dup 1 eq { - stroke exit - } if - dup 2 eq { - gsave fill grestore stroke exit - } if - dup 3 eq { - currentpoint newpath moveto - } if - dup 4 eq { - gsave fill grestore clip exit - } if - dup 5 eq { - gsave stroke grestore clip exit - } if - dup 6 eq { - gsave fill grestore gsave stroke grestore fill exit - } if - dup 7 eq { - clip exit - } if - exit - } loop - pop -} bind def - -/ShowTextWithGlyphPositioning % <array> ShowTextWithGlyphPositioning - -{ //ShowTextBeg exec - { dup type /stringtype eq { - //ShowText exec - } { - neg 1000 div //GraphicState /FontSize get mul 0 rmoveto - } ifelse - } forall - //ShowTextEnd exec -} bind def - -/CheckFont % key val CheckFont key val -{ dup /Type get /ExtGState ne { - mark (Resource ) 3 index ( must have /Type/ExtGState.) //error exec - } if -} bind def - -/SetTransfer % <operand> SetTransfer - -{ - //PDFR_DEBUG { (SetTransfer beg ) print count = } if - dup type /arraytype eq 1 index xcheck not and { - 0 4 getinterval aload pop - setcolortransfer - } { - settransfer - } ifelse - //PDFR_DEBUG { (SetTransfer end ) print count = } if -} bind def - -/CheckExtGState % <id> <obj> CheckExtGState <id> <obj> -{ dup /Type get /ExtGState ne { - mark (Resource ) 3 index ( must have /Type/ExtGState.) //error exec - } if -} bind def - -/CheckHalftone % <id> <obj> CheckHalftone <id> <obj> -{ dup /HalftoneType known not { - mark (Resource ) 3 index ( must have /HalftoneType.) //error exec - } if -} bind def - -/ResolveFunction % <dict> <name> ResolveFunction <dict> <proc> -{ - //PDFR_DEBUG { (ResolveFunction beg ) print dup = count = } if - 2 copy get //IsObjRef exec { - 2 copy //DoNothing //ResolveD exec - 3 copy put pop - } if - 2 copy get dup type /arraytype eq exch xcheck and not { - 2 copy get - dup type /arraytype eq 1 index xcheck not and { - dup length 1 sub -1 0 { - 2 copy //DoNothing ResolveA - dup /Identity eq { - pop 2 copy {} put - } { - //FunctionToProc exec - 3 copy put pop - } ifelse - pop - } for - } { - dup /Default eq { - % Leave it. ExtGState methods will resolve. - } { - dup /Identity eq { - pop {} - } { dup type /nametype eq { - //spotfunctions exch get - } { - //FunctionToProc exec - } ifelse - } ifelse - } ifelse - } ifelse - 3 copy put - exch pop - } { - 1 index exch get - } ifelse - //PDFR_DEBUG { (ResolveFunction end ) print dup == count = } if -} bind def - -/ResolveFunctionSafe % <dict> <name> ResolveFunctionSafe <dict> -{ 2 copy known { - //ResolveFunction exec - } if - pop -} bind def - -/CreateHalftoneThresholds % <halftone_dict> CreateHalftoneThresholds <halftone_dict> -{ - dup /Thresholds known not { - dup /HalftoneType get 10 eq { - dup dup //MakeStreamReader exec - /Thresholds exch put - } if - dup /HalftoneType get dup 3 eq exch 6 eq or { - dup dup //MakeStreamReader exec - //BlockBuffer readstring pop - dup length - dup 0 eq { - mark (Could not read Thresholds) //error exec - } if - string copy /Thresholds exch put - dup /HalftoneType 3 put % replace Type 6 with Type 3. - } if - } if -} bind def - - -/SetExtGState % <name> SetExtGState - -{ - //PDFReader /CurrentObject get /Context get /Resources get - /ExtGState //DoNothing //ResolveD exec - exch //CheckExtGState //ResolveD exec % s gs - dup /LW //knownget exec { - setlinewidth - } if - dup /LC //knownget exec { - setlinecap - } if - dup /LJ //knownget exec { - setlinejoin - } if - dup /ML //knownget exec { - setmeterlimit - } if - dup /D //knownget exec { - setdash - } if - dup /RI //knownget exec { - % Ghostscript never writes it. - mark (Unimplemented ExtGState.RI) //error exec - } if - dup /OP //knownget exec { - % pdfwrite must take care of stroking/filling - setoverprint - } if - dup /op //knownget exec { - setoverprint - } if - dup /OPM //knownget exec { - % pdfwrite must take care of. - mark (Unimplemented ExtGState.OPM) //error exec - } if - dup /Font //knownget exec { - % Ghostscript never writes it. - mark (Unimplemented ExtGState.Font) //error exec - } if - dup /BG known { - /BG //ResolveFunction exec - setblackgeneration - } if - dup /BG2 known { - /BG2 //ResolveFunction exec - dup /Default eq { - //InitialExtGState /BG2 get - } if - setblackgeneration - } if - dup /UCR known { - /UCR //ResolveFunction exec - setundercolorremoval - } if - dup /UCR2 known { - /UCR2 //ResolveFunction exec - dup /Default eq { - //InitialExtGState /UCR2 get - } if - setundercolorremoval - } if - dup /TR known { - /TR //ResolveFunction exec - //SetTransfer exec - } if - dup /TR2 known { - /TR2 //ResolveFunction exec - dup /Default eq { - pop //InitialExtGState /TR2 get - aload pop setcolortransfer - } { - //SetTransfer exec - } ifelse - } if - dup /HT //knownget exec { - dup /Default eq { - pop //InitialExtGState /HT get - sethalftone - } { - //PDFR_DEBUG { (Ht beg) = } if - pop dup /HT //CheckHalftone //ResolveD exec - /SpotFunction //ResolveFunctionSafe exec - /TransferFunction //ResolveFunctionSafe exec - null exch - dup /HalftoneType get dup 5 eq exch dup 4 eq exch 2 eq or or { - dup { % null h n v - dup //IsObjRef exec { - pop - 1 index exch //CheckHalftone ResolveD - } if - dup type /dicttype eq { - dup /SpotFunction //ResolveFunctionSafe exec - /TransferFunction //ResolveFunctionSafe exec - //CreateHalftoneThresholds exec - dup /HalftoneType get 5 gt { % null h n v - 4 3 roll pop - dup 4 1 roll - } if - } if - pop pop - } forall - } if - //CreateHalftoneThresholds exec - //PDFR_DEBUG { - (HT:)= - dup { - 1 index /Default eq { - (Default <<)= - exch pop - { exch = == } forall - (>>)= - } { - exch = == - } ifelse - } forall - (HT end)= flush - } if - exch dup null ne { - (Warning: Ignoring a halftone with a Level 3 component halftone Type ) print dup /HalftoneType get = - pop pop - } { - pop - dup /HalftoneType get 5 gt { - (Warning: Ignoring a Level 3 halftone Type ) print dup /HalftoneType get = - pop - } { - sethalftone - } ifelse - } ifelse - //PDFR_DEBUG { (HT set)= flush } if - } ifelse - } if - dup /FL //knownget exec { - setflattness - } if - dup /SM //knownget exec { - setsmoothness - } if - dup /SA //knownget exec { - setstrokeadjust - } if - dup /BM //knownget exec { - % pdfwrite must take care of. - mark (Unimplemented ExtGState.BM) //error exec - } if - dup /SMask //knownget exec { - % pdfwrite must take care of. - mark (Unimplemented ExtGState.SMask) //error exec - } if - dup /CA //knownget exec { - % pdfwrite must take care of. - mark (Unimplemented ExtGState.CA) //error exec - } if - dup /ca //knownget exec { - % pdfwrite must take care of. - mark (Unimplemented ExtGState.ca) //error exec - } if - dup /AIS //knownget exec { - % pdfwrite must take care of. - mark (Unimplemented ExtGState.AIS) //error exec - } if - dup /TK //knownget exec { - % pdfwrite must take care of. - mark (Unimplemented ExtGState.TK) //error exec - } if - pop -} bind def - -/CheckXObject % <id> <obj> CheckHalftone <id> <obj> -{ dup /Subtype get dup /Image ne exch dup /Form ne exch /PS ne and and { - mark (Resource ) 3 index ( must have /Subtype /Image or /Form or /PS.) //error exec - } if -} bind def - -/DoXObject % <name> DoXObject - -{ - //PDFReader /CurrentObject get /Context get /Resources get - /XObject //DoNothing //ResolveD exec - exch //CheckXObject //ResolveD exec - dup /Subtype get - dup /Image eq { - pop - //CompleteOutlineImage exec - //DoImage exec - } { - dup /PS eq { - PDFR_DEBUG { - (Executing a PS Xobject) = - } if - pop - //RunDelayedStream exec - } { - dup /Form eq { - pop - PDFR_DEBUG { - (Executing a Form XObject) = - } if - //PDFReader /CurrentObject get exch - dup //PDFReader exch << exch /Context exch >> /CurrentObject exch put - dup /Matrix get concat - dup /BBox get aload pop exch 3 index sub exch 2 index sub rectclip - //RunDelayedStream exec - //PDFReader exch /CurrentObject exch put - } { - mark exch (unimplemented XObject type ) exch //error exec - } ifelse - } ifelse - } ifelse -} bind def - -/Operators 50 dict begin - /q { //GSave exec } bind def - /Q { //GRestore exec } bind def - /cm { //TempMatrix astore concat } bind def - /i { 1 .min setflat } bind def - /J /setlinecap load def - /d /setdash load def - /j /setlinejoin load def - /w /setlinewidth load def - /M /setmiterlimit load def - /gs { SetExtGState } bind def - - /g /setgray load def - /rg /setrgbcolor load def - /k /setcmykcolor load def - /cs { //ResolveColorSpace exec //SetColorSpaceSafe exec - } bind def - /sc /setcolor load def - /scn { //SetColor exec } bind def - /G /setgray load def - /RG /setrgbcolor load def - /K /setcmykcolor load def - /CS //cs def - /ri { SetColorRenderingIntent } bind def - /SC /setcolor load def - /SCN { //SetColor exec } bind def - - /m /moveto load def - /l /lineto load def - /c /curveto load def - /v { currentpoint 6 2 roll curveto } bind def - /y { 2 copy curveto } bind def - /re { - 4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto - closepath - } def - /h /closepath load def - /n /newpath load def - /S /stroke load def - /s { closepath stroke } bind def - /f /fill load def - /f* /eofill load def - /B { gsave fill grestore stroke } bind def - /b { closepath gsave fill grestore stroke } bind def - /B* { gsave eofill grestore stroke } bind def - /b* { closepath gsave eofill grestore stroke } bind def - /W /clip load def - /W* /eoclip load def - /sh { % Reserved for ps3write. - ResolveShading - dup /Background known { - gsave - dup /ColorSpace get setcolorspace - dup /Background get aload pop setcolor - pathbbox % x0 y0 x1 y1 - 2 index sub exch 3 index sub exch - rectfill - grestore - } if - shfill - } bind def - - /Do { //DoXObject exec } bind def - - /BI { currentglobal false setglobal << } bind def - /ID { >> - dup /DataSource currentfile - % HACK BEG - % This hack provides a compatibility to HP LaserJet 1320, - % which sometimes closes the underlying stream when EOD - % is reached in the ASCII85Decode filter. - % This portion is not required by the Postscript language definition. - 2 index /F //knownget exec { - /A85 eq { - 0 (~>) /SubFileDecode filter - } if - } if - % HACK END - put - //CompleteInlineImage exec - exch setglobal - //DoImage exec - } bind def - /EI {} bind def - - /BT { gsave //GraphicState /InitialTextMatrix get currentmatrix pop } bind def - /ET { grestore } bind def - /Tc { //GraphicState exch /CharacterSpacing exch put } bind def - /TL { //GraphicState exch /TextLeading exch put } bind def - /Tr { //GraphicState exch /TextRenderingMode exch put } bind def - /Ts { % Ghostscript never generates it. - mark (Unimplemented SetTextRise) //error exec - } bind def - /Tw { //GraphicState exch /WordSpacing exch put } bind def - /Tz { % Ghostscript never generates it. - mark (Unimplemented SetHorizontalTextScaling) //error exec - } bind def - /Td { translate 0 0 moveto } bind def - /TD { dup neg //TL exec //Td exec } bind def - /Tm { //GraphicState /InitialTextMatrix get setmatrix - //TempMatrix astore concat - 0 0 moveto } bind def - /T* { 0 //GraphicState /TextLeading get neg //Td exec } bind def - /Tj { //ShowTextBeg exec //ShowText exec //ShowTextEnd exec } bind def - /' { //T* exec //ShowText exec //ShowTextEnd exec } bind def - /" { 3 2 roll //Tw exec exch //Tc exec //' exec} bind def - /TJ //ShowTextWithGlyphPositioning def - /Tf //SetFont def - - /d0 /setcharwidth load def - /d1 /setcachedevice load def - - /BDC { pop pop } bind def - /BMC { pop } bind def - /EMC { } bind def - /BX { BeginCompatibilitySection } bind def - /EX { EndCompatibilitySection } bind def - /DP { DefineMarkedContentPointWithPropertyList } bind def - /MP { DefineMarkedContentPoint } bind def - /PS { cvx exec } bind def -currentdict end def - -//PDFR_STREAM { - % Rebind operators with a debug tracing. - //Operators length dict begin - //Operators { % n p - exch dup % p n n - [ exch //=only /exec load % p n [ n =only exec - ( ) /print load % p n [ n =only exec () print - 8 7 roll % n [ n =only exec () print p - dup type /arraytype eq { - /exec load % n [ n =only exec () print p exec - } if - ( ) /print load - ] cvx % n {} - def - } forall - currentdict end /Operators exch def -} if - -% Functions for handling Ghostscript library files that define encodings. - -/.registerencoding -{ pop pop -} bind def - -/.defineencoding -{ def -} bind def - -/.findencoding -{ load -} bind def - - -% Leaving the procset on the dictionary stack to provide -% definitions of obj, endobj, stream, endstream, R, xref. -%%EndPrologue |