diff options
author | Reinhard Kotucha <reinhard.kotucha@web.de> | 2010-05-12 19:25:45 +0000 |
---|---|---|
committer | Reinhard Kotucha <reinhard.kotucha@web.de> | 2010-05-12 19:25:45 +0000 |
commit | dc55d4f5cde421a3704c183bc6ceb3fcdb6b0653 (patch) | |
tree | db0890c2f5f2714d527a42ad3fb7955ac5b1f545 /Master/tlpkg/tlgs/lib/pdfwrite.ps | |
parent | 053ead4487e776b05721ec15b941fe0bc1b7d513 (diff) |
tlgs: 8.70 => 8.71
git-svn-id: svn://tug.org/texlive/trunk@18215 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlgs/lib/pdfwrite.ps')
-rw-r--r--[-rwxr-xr-x] | Master/tlpkg/tlgs/lib/pdfwrite.ps | 794 |
1 files changed, 397 insertions, 397 deletions
diff --git a/Master/tlpkg/tlgs/lib/pdfwrite.ps b/Master/tlpkg/tlgs/lib/pdfwrite.ps index 69e23191ee7..9d4c51d78eb 100755..100644 --- a/Master/tlpkg/tlgs/lib/pdfwrite.ps +++ b/Master/tlpkg/tlgs/lib/pdfwrite.ps @@ -1,397 +1,397 @@ -% Copyright (C) 1999, 2000, 2001 Aladdin Enterprises. 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.
-%
-% For more information about licensing, please refer to
-% http://www.ghostscript.com/licensing/. For information on
-% commercial licensing, go to http://www.artifex.com/licensing/ or
-% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
-% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
-
-% $Id: pdfwrite.ps 9246 2008-11-27 01:58:54Z alexcher $
-% Writer for transmuting PDF files.
-
-% NOTES:
-% We do editing by replacing objects (in the cache) and then doing a
-% simple recursive walk with object renumbering.
-% Free variables:
-% RMap [per input file] (dict): input_obj# => output_obj#
-% PDFfile (file): current input file
-% OFile (file): current output file
-% XRef (dict): output_obj# => output_file_pos
-% ToWrite: 0..N-1 => [obj# gen#]
-
-.languagelevel 2 .setlanguagelevel
-.currentglobal true .setglobal
-
-/PDFWRDEBUG where { pop } { /PDFWRDEBUG false def } ifelse
-
-% ======== Long dictionary support =============== %
-
-% The key must be a non-negative iteger.
-
-/ld_dict { % <len> ld_dict <ldict>
- pop << 0 <<>> >>
-} bind def
-
-/ld_length { % <ldict> ld_length <length>
- 0 exch { exch pop length add } forall
-} bind def
-
-/ld_get { % <ldict> <key> ld_get <any>
- dup 3 1 roll -15 bitshift get exch get
-} bind def
-
-/ld_put { % <ldict> <key> <any> ld_put -
- 3 1 roll dup % any ldict key key
- 4 1 roll -15 bitshift % key any ldict key>>15
- 2 copy known {
- get % key any subdict
- 3 1 roll put % -
- } {
- 64 dict dup 6 1 roll % <<>> key any ldict key>>15 <<>>
- put put
- } ifelse % -
-} bind def
-
-/ld_known { % <ldict> <key> ld_known <bool>
- dup 3 1 roll -15 bitshift % key <<>> key<<15
- 2 copy known {
- get exch known
- } {
- pop pop pop //false
- } ifelse
-} bind def
-
-/ld_knownget { % <ldict> <key> ld_known false | <any> true
- dup 3 1 roll -15 bitshift % key <<>> key<<15
- 2 copy known {
- get exch .knownget
- } {
- pop pop pop //false
- } ifelse
-} bind def
-
-/ld_def { % <key> <any> ld_def -
- currentdict 3 1 roll ld_put
-} bind def
-
-/ld_forall { % <ldict> <proc} ld_forall -
- { forall exch pop } aload pop
- 4 2 roll 4 packedarray cvx forall
-} bind def
-
-/ld_clone { % <ldict> ld_clone <ldict copy>
- << exch { dup length dict copy } forall >>
-} bind def
-
-% ================ Object mapping ================ %
-
-% Initialize the object number and location map.
-/omapinit { % - omapinit -
- /RMap 100 ld_dict def
- /XRef 100 ld_dict def
- PDFWRDEBUG { (omapinit) = } if
-} bind def
-
-% Map an object number.
-/omapnew { % <oldobj#> omap <newobj#> <isnew>
- RMap 1 index ld_knownget {
- exch pop //false
- } {
- PDFWRDEBUG { (omap\() print dup =only } if
- RMap dup ld_length 1 add % old# <<>> len+1
- 2 index exch dup % old# <<>> old# len+1 len+1
- 5 1 roll % len+1 old# <<>> old# len+1
- ld_put pop //true % len+1 true
- PDFWRDEBUG { (\) = ) print 1 index = } if
- } ifelse
-} bind def
-/omap { % <oldobj#> omap <newobj#>
- omapnew pop
-} bind def
-
-% Save and restore the object map.
-% Note that currentomap either returns a copy or calls omapinit.
-/currentomap { % <copy> currentomap <omap>
- {
- [RMap ld_clone XRef ld_clone]
- } {
- [RMap XRef] omapinit
- } ifelse
-} bind def
-/setomap { % <omap> setomap -
- aload pop /XRef exch def /RMap exch def
- PDFWRDEBUG {
- (setomap: #Xref = ) print XRef ld_length =only
- (, #RMap = ) print RMap ld_length =
- } if
-} bind def
-
-% ================ Writing ================ %
-
-% ---------------- Low-level output ---------------- %
-
-% Write a string on the output file.
-/ows { % <string> ows -
- OFile exch writestring
-} bind def
-
-% ---------------- Scalars ---------------- %
-
-% Note that the '#' character isn't legal in a name unless it is a prefix
-% for a hex encoded character (for PDF 1.2 and later). The following assumes
-% that the names are already valid PDF 1.2+ names so that we can treat the
-% '#' as a legal character. The next two hex characters are already in the
-% set of valid name characters. PDF 1.1 and earlier allowed spaces in names
-% which probably wouldn't make it past the tokenizer anyway.
-/pdfnamechars
- (!"$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~)
-readonly def
-/pdfwritename { % <name> pdfwritename -
- (/) ows .namestring {
- ( ) dup 0 4 -1 roll put
- //pdfnamechars 1 index search {
- pop pop pop
- } {
- pop 0 get 256 add 16 =string cvrs
- dup 0 (#) 0 get put
- } ifelse ows
- } forall
-} bind def
-
-% ---------------- Composite objects ---------------- %
-
-/pdfwriteprocs mark
- /resolveR { pdfwriteref }
- /O { pdfwritenewref }
-.dicttomark readonly def
-/pdfwritearray { % <array> pdfwritearray -
- dup xcheck {
- aload pop //pdfwriteprocs exch get exec
- } {
- % Because of a bug in Acrobat's parser for linearization parameters,
- % we have to include some whitespace after the opening [ (!).
- ([ ) ows { pdfwritevalue (\n) ows } forall (]) ows
- } ifelse
-} bind def
-
-/pdfwritedict { % <dict> pdfwritedict -
- dup xcheck {
- pdfwritestream
- } {
- (<<) ows {
- exch pdfwritevalue ( ) ows pdfwritevalue (\n) ows
- } forall (>>) ows
- } ifelse
-} bind def
-
-% ---------------- References ---------------- %
-
-/pdfwritenewref { % <newobj#> pdfwritenewref -
- OFile exch write=only ( 0 R) ows
-} bind def
-
-/pdfwriteref { % <obj#> <gen#> pdfwriteref -
- 1 index omapnew {
- ToWrite dup length 5 -2 roll 2 packedarray put
- } {
- exch pop exch pop
- } ifelse
- pdfwritenewref
-} bind def
-
-/pdfcopystring 200 string def
-/pdfwritestream { % <streamdict> pdfwritestream -
- % Remove File, FilePosition, and StreamKey;
- % optimize by replacing an indirect Length.
- dup dup length dict copy
- % Stack: origdict dict
- dup /File undef dup /FilePosition undef dup /StreamKey undef
- dup /Length known {
- dup /Length get dup oforce ne {
- dup /Length 2 copy oget put
- } if
- } {
- 1 index /File get dup
- 3 index /FilePosition get setfileposition
- dup 0 (endstream) /SubFileDecode filter flushfile
- .fileposition 9 sub
- 2 index /FilePosition get sub
- 1 index exch /Length exch put
- } ifelse
- exch dup /File get dup 3 -1 roll /FilePosition get setfileposition
- pdfcopystream
-} bind def
-
-% We put copying the stream contents in separate procedures so that we
-% can replace this function if desired.
-/pdfcopybytes { % <fromfile> <tofile> <length> pdfcopybytes -
- {
- dup 0 eq { exit } if
- //pdfcopystring 0 2 index 2 index length .min getinterval
- 3 index exch readstring 3 1 roll
- 3 index 1 index writestring length sub exch not { exit } if
- } loop pop pop pop
-} bind def
-/pdfcopystream { % <newstreamdict> <file> pdfcopystream -
- % (file has been positioned)
- 1 index pdfwritevalue (stream\n) ows
- exch /Length get OFile exch pdfcopybytes
- (endstream) ows
-} bind def
-
-% ---------------- General values/objects ---------------- %
-
-/pdfwritetypes mark
- % Scalars
- /nulltype { pop (null) ows } bind
- /integertype { =string cvs ows } bind
- /booleantype 1 index
- /realtype {
- =string cvs
- (e) search { % PDF has no exponential format
- exch pop % exp pre
- exch cvi exch
- (-) anchorsearch { ows } if
- (.) search {
- exch pop % exp (frac) (int)
- 1 index length % exp (frac) (int) len
- 3 1 roll % exp len (frac) (int)
- exch concatstrings % exp len (int_frac)
- 3 1 roll sub % (int_frac) exp-len
- exch % exp-len (int_frac)
- } if % exp (mant)
- 1 index 0 ge {
- ows { (0) ows } repeat (.) ows
- } {
- dup length % exp (mant) len
- 3 -1 roll add % (mant) exp+len
- dup 0 le {
- (0.) ows neg { (0) ows } repeat ows
- } {
- 2 copy 0 exch getinterval ows
- (.) ows
- 1 index length 1 index sub getinterval ows
- } ifelse
- } ifelse
- } {
- ows
- } ifelse
- } bind
- /stringtype { OFile exch write===only } bind
- /nametype { pdfwritename } bind
- % Composite/reference objects
- /arraytype { pdfwritearray } bind
- /packedarraytype 1 index
- /dicttype { pdfwritedict } bind
-.dicttomark readonly def
-
-/pdfwritevalue { % <obj> pdfwritevalue -
- PDFWRDEBUG { (****Writing: ) print dup === flush } if
- //pdfwritetypes 1 index type get exec
-} bind def
-
-% We make pdfwriteobjdef a separate procedure for external use.
-/pdfwriteobjheader { % <newobj#> pdfwriteobjheader -
- XRef 1 index OFile .fileposition ld_put
- PDFWRDEBUG { (XRef\() print dup =only (\) = ) print XRef 1 index ld_get = } if
- OFile exch write=only ( 0 obj\n) ows
-} bind def
-/pdfwriteobjdef { % <newobj#> <value> pdfwriteobjdef -
- exch pdfwriteobjheader
- pdfwritevalue (\nendobj\n) ows
-} bind def
-/pdfwriteobj { % <obj#> <gen#> pdfwriteobj -
- 1 index exch resolveR exch omap exch pdfwriteobjdef
-} bind def
-
-% ---------------- File-level entities ---------------- %
-
-% Write a PDF file header.
-% Free variables: OFile, PDFversion.
-/pdfwriteheader { % - pdfwriteheader -
- (%PDF-) ows OFile PDFversion write=
- (%\347\363\317\323\n) ows
-} bind def
-
-% Write a cross-reference table and trailer.
-/pdfwritexref { % <firstobj#> <#objs> pdfwritexref -
- (xref\n) ows
- OFile 2 index write=only ( ) ows OFile 1 index write=
- 1 index add 1 sub 1 exch {
- dup 0 eq {
- pop (0000000000 65535 f \n) ows
- } {
- XRef exch ld_get 1000000000 add =string cvs
- dup 0 (0) 0 get put
- ows ( 00000 n \n) ows
- } ifelse
- } for
-} bind def
-/pdfwritetrailer { % <trailer> pdfwritetrailer -
- (trailer\n) ows
- % Since we always write a complete "classic" xref, the Trailer may need to be adjusted:
- % - remove keys that pertain to xref-streams and hybrid-xref PDFs;
- % - if it's a PDF stream, turn it into a PDF dict by removing keys used for
- % PDF streams (both standard and GS-specific), and the executable attribute
- dup /XRefStm known 1 index xcheck or {
- dup length dict copy
- dup {/Type/Index/W /XRefStm /Filter/DecodeParms/Length/File/FilePosition} {
- undef dup
- } forall pop
- % note: the executable attribute is "removed" by not being copied
- } if
- pdfwritevalue
- (\n) ows
-} bind def
-/pdfwritestartxref { % <startpos> pdfwritestartxref -
- (startxref\n) ows OFile exch write=
- (%%EOF\n) ows
-} bind def
-
-% ================ Top-level control ================ %
-
-/pdfwrite { % <file> <trailer> pdfwrite -
- 10 dict begin
- /trailer exch def
- /OFile exch def
- /ToWrite 100 dict def
- omapinit
-
- % Write the PDF file header.
-
- pdfwriteheader
-
- % Write the objects.
-
- trailer {
- exch pop dup xcheck { % The only executable objects are references.
- aload pop pop pdfwriteobj
- } {
- pop
- } ifelse
- } forall
- % Walk the object graph.
- {
- ToWrite dup length dup 0 eq { pop pop exit } if
- 1 sub 2 copy get 3 1 roll undef aload pop pdfwriteobj
- } loop
-
- % Write the xref table and trailer.
-
- /xref OFile fileposition def
- 0 XRef ld_length 1 add pdfwritexref
- trailer dup length 1 add dict copy trailer xcheck { cvx } if
- dup /Size XRef ld_length 1 add put pdfwritetrailer
- xref pdfwritestartxref
-
- end
-} bind def
-
-.setglobal .setlanguagelevel
+% Copyright (C) 1999, 2000, 2001 Aladdin Enterprises. 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. +% +% For more information about licensing, please refer to +% http://www.ghostscript.com/licensing/. For information on +% commercial licensing, go to http://www.artifex.com/licensing/ or +% contact Artifex Software, Inc., 101 Lucas Valley Road #110, +% San Rafael, CA 94903, U.S.A., +1(415)492-9861. + +% $Id: pdfwrite.ps 9246 2008-11-27 01:58:54Z alexcher $ +% Writer for transmuting PDF files. + +% NOTES: +% We do editing by replacing objects (in the cache) and then doing a +% simple recursive walk with object renumbering. +% Free variables: +% RMap [per input file] (dict): input_obj# => output_obj# +% PDFfile (file): current input file +% OFile (file): current output file +% XRef (dict): output_obj# => output_file_pos +% ToWrite: 0..N-1 => [obj# gen#] + +.languagelevel 2 .setlanguagelevel +.currentglobal true .setglobal + +/PDFWRDEBUG where { pop } { /PDFWRDEBUG false def } ifelse + +% ======== Long dictionary support =============== % + +% The key must be a non-negative iteger. + +/ld_dict { % <len> ld_dict <ldict> + pop << 0 <<>> >> +} bind def + +/ld_length { % <ldict> ld_length <length> + 0 exch { exch pop length add } forall +} bind def + +/ld_get { % <ldict> <key> ld_get <any> + dup 3 1 roll -15 bitshift get exch get +} bind def + +/ld_put { % <ldict> <key> <any> ld_put - + 3 1 roll dup % any ldict key key + 4 1 roll -15 bitshift % key any ldict key>>15 + 2 copy known { + get % key any subdict + 3 1 roll put % - + } { + 64 dict dup 6 1 roll % <<>> key any ldict key>>15 <<>> + put put + } ifelse % - +} bind def + +/ld_known { % <ldict> <key> ld_known <bool> + dup 3 1 roll -15 bitshift % key <<>> key<<15 + 2 copy known { + get exch known + } { + pop pop pop //false + } ifelse +} bind def + +/ld_knownget { % <ldict> <key> ld_known false | <any> true + dup 3 1 roll -15 bitshift % key <<>> key<<15 + 2 copy known { + get exch .knownget + } { + pop pop pop //false + } ifelse +} bind def + +/ld_def { % <key> <any> ld_def - + currentdict 3 1 roll ld_put +} bind def + +/ld_forall { % <ldict> <proc} ld_forall - + { forall exch pop } aload pop + 4 2 roll 4 packedarray cvx forall +} bind def + +/ld_clone { % <ldict> ld_clone <ldict copy> + << exch { dup length dict copy } forall >> +} bind def + +% ================ Object mapping ================ % + +% Initialize the object number and location map. +/omapinit { % - omapinit - + /RMap 100 ld_dict def + /XRef 100 ld_dict def + PDFWRDEBUG { (omapinit) = } if +} bind def + +% Map an object number. +/omapnew { % <oldobj#> omap <newobj#> <isnew> + RMap 1 index ld_knownget { + exch pop //false + } { + PDFWRDEBUG { (omap\() print dup =only } if + RMap dup ld_length 1 add % old# <<>> len+1 + 2 index exch dup % old# <<>> old# len+1 len+1 + 5 1 roll % len+1 old# <<>> old# len+1 + ld_put pop //true % len+1 true + PDFWRDEBUG { (\) = ) print 1 index = } if + } ifelse +} bind def +/omap { % <oldobj#> omap <newobj#> + omapnew pop +} bind def + +% Save and restore the object map. +% Note that currentomap either returns a copy or calls omapinit. +/currentomap { % <copy> currentomap <omap> + { + [RMap ld_clone XRef ld_clone] + } { + [RMap XRef] omapinit + } ifelse +} bind def +/setomap { % <omap> setomap - + aload pop /XRef exch def /RMap exch def + PDFWRDEBUG { + (setomap: #Xref = ) print XRef ld_length =only + (, #RMap = ) print RMap ld_length = + } if +} bind def + +% ================ Writing ================ % + +% ---------------- Low-level output ---------------- % + +% Write a string on the output file. +/ows { % <string> ows - + OFile exch writestring +} bind def + +% ---------------- Scalars ---------------- % + +% Note that the '#' character isn't legal in a name unless it is a prefix +% for a hex encoded character (for PDF 1.2 and later). The following assumes +% that the names are already valid PDF 1.2+ names so that we can treat the +% '#' as a legal character. The next two hex characters are already in the +% set of valid name characters. PDF 1.1 and earlier allowed spaces in names +% which probably wouldn't make it past the tokenizer anyway. +/pdfnamechars + (!"$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~) +readonly def +/pdfwritename { % <name> pdfwritename - + (/) ows .namestring { + ( ) dup 0 4 -1 roll put + //pdfnamechars 1 index search { + pop pop pop + } { + pop 0 get 256 add 16 =string cvrs + dup 0 (#) 0 get put + } ifelse ows + } forall +} bind def + +% ---------------- Composite objects ---------------- % + +/pdfwriteprocs mark + /resolveR { pdfwriteref } + /O { pdfwritenewref } +.dicttomark readonly def +/pdfwritearray { % <array> pdfwritearray - + dup xcheck { + aload pop //pdfwriteprocs exch get exec + } { + % Because of a bug in Acrobat's parser for linearization parameters, + % we have to include some whitespace after the opening [ (!). + ([ ) ows { pdfwritevalue (\n) ows } forall (]) ows + } ifelse +} bind def + +/pdfwritedict { % <dict> pdfwritedict - + dup xcheck { + pdfwritestream + } { + (<<) ows { + exch pdfwritevalue ( ) ows pdfwritevalue (\n) ows + } forall (>>) ows + } ifelse +} bind def + +% ---------------- References ---------------- % + +/pdfwritenewref { % <newobj#> pdfwritenewref - + OFile exch write=only ( 0 R) ows +} bind def + +/pdfwriteref { % <obj#> <gen#> pdfwriteref - + 1 index omapnew { + ToWrite dup length 5 -2 roll 2 packedarray put + } { + exch pop exch pop + } ifelse + pdfwritenewref +} bind def + +/pdfcopystring 200 string def +/pdfwritestream { % <streamdict> pdfwritestream - + % Remove File, FilePosition, and StreamKey; + % optimize by replacing an indirect Length. + dup dup length dict copy + % Stack: origdict dict + dup /File undef dup /FilePosition undef dup /StreamKey undef + dup /Length known { + dup /Length get dup oforce ne { + dup /Length 2 copy oget put + } if + } { + 1 index /File get dup + 3 index /FilePosition get setfileposition + dup 0 (endstream) /SubFileDecode filter flushfile + .fileposition 9 sub + 2 index /FilePosition get sub + 1 index exch /Length exch put + } ifelse + exch dup /File get dup 3 -1 roll /FilePosition get setfileposition + pdfcopystream +} bind def + +% We put copying the stream contents in separate procedures so that we +% can replace this function if desired. +/pdfcopybytes { % <fromfile> <tofile> <length> pdfcopybytes - + { + dup 0 eq { exit } if + //pdfcopystring 0 2 index 2 index length .min getinterval + 3 index exch readstring 3 1 roll + 3 index 1 index writestring length sub exch not { exit } if + } loop pop pop pop +} bind def +/pdfcopystream { % <newstreamdict> <file> pdfcopystream - + % (file has been positioned) + 1 index pdfwritevalue (stream\n) ows + exch /Length get OFile exch pdfcopybytes + (endstream) ows +} bind def + +% ---------------- General values/objects ---------------- % + +/pdfwritetypes mark + % Scalars + /nulltype { pop (null) ows } bind + /integertype { =string cvs ows } bind + /booleantype 1 index + /realtype { + =string cvs + (e) search { % PDF has no exponential format + exch pop % exp pre + exch cvi exch + (-) anchorsearch { ows } if + (.) search { + exch pop % exp (frac) (int) + 1 index length % exp (frac) (int) len + 3 1 roll % exp len (frac) (int) + exch concatstrings % exp len (int_frac) + 3 1 roll sub % (int_frac) exp-len + exch % exp-len (int_frac) + } if % exp (mant) + 1 index 0 ge { + ows { (0) ows } repeat (.) ows + } { + dup length % exp (mant) len + 3 -1 roll add % (mant) exp+len + dup 0 le { + (0.) ows neg { (0) ows } repeat ows + } { + 2 copy 0 exch getinterval ows + (.) ows + 1 index length 1 index sub getinterval ows + } ifelse + } ifelse + } { + ows + } ifelse + } bind + /stringtype { OFile exch write===only } bind + /nametype { pdfwritename } bind + % Composite/reference objects + /arraytype { pdfwritearray } bind + /packedarraytype 1 index + /dicttype { pdfwritedict } bind +.dicttomark readonly def + +/pdfwritevalue { % <obj> pdfwritevalue - + PDFWRDEBUG { (****Writing: ) print dup === flush } if + //pdfwritetypes 1 index type get exec +} bind def + +% We make pdfwriteobjdef a separate procedure for external use. +/pdfwriteobjheader { % <newobj#> pdfwriteobjheader - + XRef 1 index OFile .fileposition ld_put + PDFWRDEBUG { (XRef\() print dup =only (\) = ) print XRef 1 index ld_get = } if + OFile exch write=only ( 0 obj\n) ows +} bind def +/pdfwriteobjdef { % <newobj#> <value> pdfwriteobjdef - + exch pdfwriteobjheader + pdfwritevalue (\nendobj\n) ows +} bind def +/pdfwriteobj { % <obj#> <gen#> pdfwriteobj - + 1 index exch resolveR exch omap exch pdfwriteobjdef +} bind def + +% ---------------- File-level entities ---------------- % + +% Write a PDF file header. +% Free variables: OFile, PDFversion. +/pdfwriteheader { % - pdfwriteheader - + (%PDF-) ows OFile PDFversion write= + (%\347\363\317\323\n) ows +} bind def + +% Write a cross-reference table and trailer. +/pdfwritexref { % <firstobj#> <#objs> pdfwritexref - + (xref\n) ows + OFile 2 index write=only ( ) ows OFile 1 index write= + 1 index add 1 sub 1 exch { + dup 0 eq { + pop (0000000000 65535 f \n) ows + } { + XRef exch ld_get 1000000000 add =string cvs + dup 0 (0) 0 get put + ows ( 00000 n \n) ows + } ifelse + } for +} bind def +/pdfwritetrailer { % <trailer> pdfwritetrailer - + (trailer\n) ows + % Since we always write a complete "classic" xref, the Trailer may need to be adjusted: + % - remove keys that pertain to xref-streams and hybrid-xref PDFs; + % - if it's a PDF stream, turn it into a PDF dict by removing keys used for + % PDF streams (both standard and GS-specific), and the executable attribute + dup /XRefStm known 1 index xcheck or { + dup length dict copy + dup {/Type/Index/W /XRefStm /Filter/DecodeParms/Length/File/FilePosition} { + undef dup + } forall pop + % note: the executable attribute is "removed" by not being copied + } if + pdfwritevalue + (\n) ows +} bind def +/pdfwritestartxref { % <startpos> pdfwritestartxref - + (startxref\n) ows OFile exch write= + (%%EOF\n) ows +} bind def + +% ================ Top-level control ================ % + +/pdfwrite { % <file> <trailer> pdfwrite - + 10 dict begin + /trailer exch def + /OFile exch def + /ToWrite 100 dict def + omapinit + + % Write the PDF file header. + + pdfwriteheader + + % Write the objects. + + trailer { + exch pop dup xcheck { % The only executable objects are references. + aload pop pop pdfwriteobj + } { + pop + } ifelse + } forall + % Walk the object graph. + { + ToWrite dup length dup 0 eq { pop pop exit } if + 1 sub 2 copy get 3 1 roll undef aload pop pdfwriteobj + } loop + + % Write the xref table and trailer. + + /xref OFile fileposition def + 0 XRef ld_length 1 add pdfwritexref + trailer dup length 1 add dict copy trailer xcheck { cvx } if + dup /Size XRef ld_length 1 add put pdfwritetrailer + xref pdfwritestartxref + + end +} bind def + +.setglobal .setlanguagelevel |