home *** CD-ROM | disk | FTP | other *** search
/ Mixa 155: Dogs / MIXA 155: Dogs.iso / pc / Viewer / BROWSER(W) / フィルタ / PDF / LIB / pdfwrite.ps < prev   
Encoding:
Text File  |  2002-10-29  |  6.8 KB  |  256 lines

  1. %    Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is licensed to a single customer by Artifex Software Inc.
  3. % under the terms of a specific OEM agreement.
  4.  
  5. % $RCSfile: pdfwrite.ps,v $ $Revision: 1.1 $
  6. % Writer for transmuting PDF files.
  7.  
  8. % NOTES:
  9. % We do editing by replacing objects (in the cache) and then doing a
  10. %   simple recursive walk with object renumbering.
  11. % Free variables:
  12. %   RMap [per input file] (dict): input_obj# => output_obj#
  13. %   PDFfile (file): current input file
  14. %   OFile (file): current output file
  15. %   XRef (dict): output_obj# => output_file_pos
  16. %   ToWrite: 0..N-1 => [obj# gen#]
  17.  
  18. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  19. .currentglobal true .setglobal
  20.  
  21. /PDEBUG where { pop } { /PDEBUG false def } ifelse
  22.  
  23. % ================ Object mapping ================ %
  24.  
  25. % Initialize the object number and location map.
  26. /omapinit {        % - omapinit -
  27.   /RMap 100 dict def
  28.   /XRef 100 dict def
  29. } def
  30.  
  31. % Map an object number.
  32. /omapnew {        % <oldobj#> omap <newobj#> <isnew>
  33.   RMap 1 index .knownget {
  34.     exch pop false
  35.   } {
  36.     RMap dup length 1 add 2 index exch dup 5 1 roll put pop true
  37.   } ifelse
  38. } def
  39. /omap {            % <oldobj#> omap <newobj#>
  40.   omapnew pop
  41. } bind def
  42.  
  43. % Save and restore the object map.
  44. % Note that currentomap either returns a copy or calls omapinit.
  45. /currentomap {        % <copy> currentomap <omap>
  46.   {
  47.     [RMap dup length dict copy XRef dup length dict copy]
  48.   } {
  49.     [RMap XRef] omapinit
  50.   } ifelse
  51. } bind def
  52. /setomap {        % <omap> setomap -
  53.   aload pop /XRef exch def /RMap exch def
  54. } bind def
  55.  
  56. % ================ Writing ================ %
  57.  
  58. % ---------------- Low-level output ---------------- %
  59.  
  60. % Write a string on the output file.
  61. /ows {            % <string> ows -
  62.   OFile exch writestring
  63. } def
  64.  
  65. % ---------------- Scalars ---------------- %
  66.  
  67. /pdfnamechars (!"$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~) readonly def
  68. /pdfwritename {        % <name> pdfwritename -
  69.   (/) ows .namestring {
  70.     ( ) dup 0 4 -1 roll put
  71.     //pdfnamechars 1 index search {
  72.       pop pop pop
  73.     } {
  74.       pop 256 add 16 =string cvrs
  75.       dup 0 (#) 0 get put
  76.     } ifelse ows
  77.   } forall
  78. } def
  79.  
  80. % ---------------- Composite objects ---------------- %
  81.  
  82. /pdfwriteprocs mark
  83.   /resolveR { pdfwriteref }
  84.   /O { pdfwritenewref }
  85. .dicttomark readonly def
  86. /pdfwritearray {    % <array> pdfwritearray -
  87.   dup xcheck {
  88.     aload pop //pdfwriteprocs exch get exec
  89.   } {
  90.     ([) ows { pdfwritevalue (\n) ows } forall (]) ows
  91.   } ifelse
  92. } def
  93.  
  94. /pdfwritedict {        % <dict> pdfwritedict -
  95.   dup xcheck {
  96.     pdfwritestream
  97.   } {
  98.     (<<) ows {
  99.       exch pdfwritevalue ( ) ows pdfwritevalue (\n) ows
  100.     } forall (>>) ows
  101.   } ifelse
  102. } def
  103.  
  104. % ---------------- References ---------------- %
  105.  
  106. /pdfwritenewref {    % <newobj#> pdfwritenewref -
  107.   OFile exch write=only ( 0 R) ows
  108. } def
  109.  
  110. /pdfwriteref {        % <obj#> <gen#> pdfwriteref -
  111.   1 index omapnew {
  112.     ToWrite dup length 5 -2 roll 2 packedarray put
  113.   } {
  114.     exch pop exch pop
  115.   } ifelse
  116.   pdfwritenewref
  117. } def
  118.  
  119. /pdfcopystring 200 string def
  120. /pdfwritestream {    % <streamdict> pdfwritestream -
  121.     % Remove File, FilePosition, and StreamKey;
  122.     % optimize by replacing an indirect Length.
  123.   dup dup length dict copy
  124.     % Stack: origdict dict
  125.   dup /File undef dup /FilePosition undef dup /StreamKey undef
  126.   dup /Length get dup oforce ne {
  127.     dup /Length 2 copy oget put
  128.   } if
  129.   exch dup /File get dup 3 -1 roll /FilePosition get setfileposition
  130.   pdfcopystream
  131. } def
  132.  
  133. % We put copying the stream contents in separate procedures so that we
  134. % can replace this function if desired.
  135. /pdfcopybytes {        % <fromfile> <tofile> <length> pdfcopybytes -
  136.   {
  137.     dup 0 eq { exit } if
  138.     //pdfcopystring 0 2 index 2 index length .min getinterval
  139.     3 index exch readstring 3 1 roll
  140.     3 index 1 index writestring length sub exch not { exit } if
  141.   } loop pop pop pop
  142. } def
  143. /pdfcopystream {    % <newstreamdict> <file> pdfcopystream -
  144.             %   (file has been positioned)
  145.   1 index pdfwritevalue (stream\n) ows
  146.   exch /Length get OFile exch pdfcopybytes
  147.   (endstream) ows
  148. } def
  149.  
  150. % ---------------- General values/objects ---------------- %
  151.  
  152. /pdfwritetypes mark
  153.     % Scalars
  154.   /nulltype { =string cvs ows }
  155.   /integertype 1 index
  156.   /booleantype 1 index
  157.   /realtype { OFile exch write===only }
  158.   /stringtype 1 index
  159.   /nametype { pdfwritename }
  160.     % Composite/reference objects
  161.   /arraytype { pdfwritearray }
  162.   /packedarraytype 1 index
  163.   /dicttype { pdfwritedict }
  164. .dicttomark readonly def
  165.  
  166. /pdfwritevalue {    % <obj> pdfwritevalue -
  167.   PDEBUG { (****Writing: ) print dup === flush } if
  168.   //pdfwritetypes 1 index type get exec
  169. } def
  170.  
  171. % We make pdfwriteobjdef a separate procedure for external use.
  172. /pdfwriteobjheader {    % <newobj#> pdfwriteobjheader -
  173.   XRef 1 index OFile .fileposition put
  174.   OFile exch write=only ( 0 obj\n) ows
  175. } def
  176. /pdfwriteobjdef {    % <newobj#> <value> pdfwriteobjdef -
  177.   exch pdfwriteobjheader
  178.   pdfwritevalue (\nendobj\n) ows
  179. } def
  180. /pdfwriteobj {        % <obj#> <gen#> pdfwriteobj -
  181.   1 index exch resolveR exch omap exch pdfwriteobjdef
  182. } def
  183.  
  184. % ---------------- File-level entities ---------------- %
  185.  
  186. % Write a PDF file header.
  187. % Free variables: OFile, PDFversion.
  188. /pdfwriteheader {    % - pdfwriteheader -
  189.   (%PDF-) ows OFile PDFversion write=
  190.   (%\347\363\317\323\n) ows
  191. } bind def
  192.  
  193. % Write a cross-reference table and trailer.
  194. /pdfwritexref {        % <firstobj#> <#objs> pdfwritexref -
  195.   (xref\n) ows
  196.   OFile 2 index write=only ( ) ows OFile 1 index write=
  197.   1 index add 1 sub 1 exch {
  198.     dup 0 eq {
  199.       pop (0000000000 65535 f \n) ows
  200.     } {
  201.       XRef exch get 1000000000 add =string cvs
  202.       dup 0 (0) 0 get put
  203.       ows ( 00000 n \n) ows
  204.     } ifelse
  205.   } for
  206. } bind def
  207. /pdfwritetrailer {    % <trailer> pdfwritetrailer -
  208.   (trailer\n) ows pdfwritevalue (\n) ows
  209. } bind def
  210. /pdfwritestartxref {    % <startpos> pdfwritestartxref -
  211.   (startxref\n) ows OFile exch write=
  212.   (%%EOF\n) ows
  213. } bind def
  214.  
  215. % ================ Top-level control ================ %
  216.  
  217. /pdfwrite {        % <file> <trailer> pdfwrite -
  218.   10 dict begin
  219.   /trailer exch def
  220.   /OFile exch def
  221.   /ToWrite 100 dict def
  222.   omapinit
  223.  
  224.     % Write the PDF file header.
  225.  
  226.   pdfwriteheader
  227.  
  228.     % Write the objects.
  229.  
  230.   trailer {
  231.     exch pop dup xcheck {    % The only executable objects are references.
  232.       aload pop pop pdfwriteobj
  233.     } {
  234.       pop
  235.     } ifelse
  236.   } forall
  237.     % Walk the object graph.
  238.   {
  239.     ToWrite dup length dup 0 eq { pop pop exit } if
  240.     1 sub 2 copy get 3 1 roll undef aload pop pdfwriteobj
  241.   } loop
  242.  
  243.     % Write the xref table and trailer.
  244.  
  245.   /xref OFile fileposition def
  246.   0 XRef length 1 add pdfwritexref
  247.   trailer dup length 1 add dict copy
  248.   dup /Size XRef length 1 add put pdfwritetrailer
  249.   xref pdfwritestartxref
  250.  
  251.   end
  252. } def
  253.  
  254. .setglobal
  255.