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

  1. %    Copyright (C) 1994, 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: pdf_font.ps,v $ $Revision: 1.14 $
  6. % pdf_font.ps
  7. % PDF font operations.
  8.  
  9. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  10. .currentglobal true .setglobal
  11. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  12. GS_PDF_ProcSet begin
  13. pdfdict begin
  14.  
  15. % We cache the PostScript font in an additional element of the
  16. % font resource dictionary, called PSFont.
  17.  
  18. % ---------------- Encodings ---------------- %
  19.  
  20. % Apply a list of differences to an Encoding.
  21. % Note that the differences may cause the array to grow.
  22. /updateencoding {    % <encoding> <differences> updateencoding <enc'>
  23.     % Calculate the length of the result.
  24.   exch 0 2 index {
  25.     dup type /nametype ne { exch pop } { pop 1 add } ifelse
  26.   } forall
  27.   1 index length .max array dup 0 4 -1 roll putinterval
  28.   exch 0 exch {
  29.         % Stack: enc' code element
  30.     dup type /nametype ne
  31.       { exch pop }
  32.       { 3 copy put pop 1 add }
  33.     ifelse
  34.   } forall pop
  35. } bdef
  36.  
  37. % Get the Encoding for a font.
  38. /getencoding        % <base-encoding> <font-resource> getencoding <enc>
  39.  { /Encoding knownoget
  40.     { dup type /nametype eq
  41.        {
  42.          % The published PDF specification says the Encoding name
  43.          % "must be" one of the 3 predefined Encodings, implying
  44.          % that an error should occur if it isn't.  However, Acrobat
  45.          % Reader simply ignores unknown names, and since there are
  46.          % some buggy applications that rely on this, we do the same.
  47.  
  48.          dup dup dup /MacRomanEncoding eq
  49.          exch /MacExpertEncoding eq or 
  50.          exch /WinAnsiEncoding eq or
  51.            { exch pop findencoding
  52.            }
  53.            { pop
  54.            }
  55.          ifelse
  56.        }
  57.        { dup /BaseEncoding knownoget
  58.       { findencoding 3 -1 roll pop exch
  59.       }
  60.      if
  61.      /Differences knownoget { updateencoding } if
  62.        }
  63.       ifelse
  64.     }
  65.    if
  66.  } bdef
  67.  
  68. % Rename a font with a generated name.
  69. /renamefont {        % <fontdict> renamefont <font'>
  70.   dup /FontName 2 copy get genfontname dup 5 1 roll put definefont
  71. } bind def
  72.  
  73. % Adjust a font according to the Encoding and Widths in the font resource.
  74. /adjustfont {        % <font-resource> <font> adjustfont <font'>
  75.   getfontencoding
  76.   getfontmetrics 4 -1 roll pop .updatefont { renamefont } if
  77. } bind def
  78.  
  79. % Get the (possibly modified) encoding of a font.
  80. /getfontencoding {    % <font-resource> <font> getfontencoding
  81.             %   <font-resource> <font> <Encoding|null>
  82.   1 index /Encoding known {
  83.     dup /Encoding .knownget { 2 index getencoding } { null } ifelse
  84.   } {
  85.     null
  86.   } ifelse
  87. } bdef
  88.  
  89. % Get the metrics of a font, if specified.
  90. /getfontmetrics {    % <font-resource> <font> <Encoding|null> getfontmetrics
  91.             %   <font-resource> <font> <Encoding|null>
  92.             %   <Metrics|null>
  93.   2 index /Widths known {
  94.     dup null eq { pop dup /Encoding get } if
  95.     4 dict begin
  96.       /Encoding exch def
  97.       /Metrics Encoding length dict def
  98.       exch
  99.       dup /Widths oget /Widths exch def
  100.         % Stack: font font-res
  101.         % Note that widths are always based on a 1000-unit
  102.         % character space, but the FontMatrix may specify
  103.         % some other scale factor.  Compensate for this here,
  104.         % by scaling the Widths if necessary.
  105.       0.001 2 index /FontMatrix get 0 get div
  106.         % Stack: font font-res mscale
  107.       1 index /FirstChar oget dup 1 4 index /LastChar oget
  108.        {    % Stack: font font-res mscale first-char index
  109.      Encoding 1 index get
  110.      Widths 2 index 4 index sub oget
  111.          % Stack: font font-res mscale first-char index charname width
  112.      4 index mul
  113.         % There is a hack here to deal with encodings where the
  114.         % same character appears more than once, because the Metrics
  115.         % dictionary works by character name, not by character code.
  116.         % Because of this, we can't deal with Width vectors that
  117.         % specify different widths for the same character name
  118.         % appearing multiple times in the Encoding.
  119.      Metrics 2 index .knownget not { 0 } if 0 ne {
  120.        pop pop
  121.      } {
  122.         % Work around a bug in pdfTeX, which can generate Encoding
  123.         % vectors containing nulls.
  124.        1 index null ne {
  125.          Metrics 3 1 roll put
  126.        } {
  127.          pop pop
  128.        } ifelse
  129.      }
  130.      ifelse pop
  131.        }
  132.       for pop
  133.         % Now fill in the MissingWidth for any encoded characters
  134.         % that aren't in Metrics already.  Note that built-in
  135.         % fonts may have Widths/FirstChar/LastChar but no
  136.         % FontDescriptor, so we must check for this.
  137.         % Stack: font font-res mscale
  138.       1 index /FontDescriptor knownoget {
  139.     Metrics exch
  140.     /MissingWidth knownoget { 2 index mul } { 0 } ifelse exch
  141.     Encoding {
  142.         % Stack: font font-res mscale missing-width metrics charname
  143.         % Work around the abovementioned pdfTeX bug.
  144.       dup null ne {
  145.         2 copy known not { 2 copy 4 index put } if pop
  146.       } {
  147.         pop
  148.       } ifelse
  149.     } forall pop pop pop
  150.       } {
  151.     pop
  152.       } ifelse
  153.     exch Encoding Metrics end
  154.   } {
  155.     null
  156.   } ifelse
  157. } bdef
  158.  
  159. % ---------------- Descriptors ---------------- %
  160.  
  161. % Partial descriptors for the 14 built-in fonts.  Note that
  162. % from PDF 1.1 to PDF 1.2, the meaning of the Flag 6 in the FontDescriptor
  163. % object has undergone a subtle change in its meaning which has serious
  164. % consequences for searching with Acrobat:
  165. % In PDF 1.1, the flag meant: Font has StandardEncoding
  166. % In PDF 1.2, the flag means: Font has (subset of) StandardRomanCharacterSet
  167. /standardfontdescriptors mark
  168.   /Courier mark /Flags 16#23 .dicttomark
  169.   /Courier-Oblique 1 index
  170.   /Courier-Bold 1 index
  171.   /Courier-BoldOblique 1 index
  172.   /Helvetica mark /Flags 16#20 .dicttomark
  173.   /Helvetica-Oblique 1 index
  174.   /Helvetica-Bold 1 index
  175.   /Helvetica-BoldOblique 1 index
  176.   /Times-Roman mark /Flags 16#22 .dicttomark
  177.   /Times-Bold 1 index
  178.   /Times-Italic mark /Flags 16#62 .dicttomark
  179.   /Times-BoldItalic 1 index
  180.   /Symbol mark /Flags 16#4 .dicttomark
  181.   /ZapfDingbats 1 index
  182. .dicttomark readonly def
  183.  
  184. % ---------------- Utilities ---------------- %
  185.  
  186. % Fabricate a font name by adding ?'s on the end.
  187. /genfontname        % <name> genfontname <name>
  188.  { dup length string cvs
  189.     { (?) concatstrings
  190.       dup cvn FontDirectory exch known not { cvn exit } if
  191.     }
  192.    loop
  193.  } bdef
  194.  
  195. % Find a font, and adjust its encoding if necessary.
  196. /.pdfdfndict mark
  197.   /defaultfontname /Helvetica
  198. .dicttomark readonly def
  199. /pdffindfont {        % <font-resource> <fontname> pdffindfont <font>
  200.         % If the font isn't available, synthesize one based on
  201.         % its descriptor.
  202.   dup /Font resourcestatus {
  203.     pop pop findfont
  204.   } {
  205.     1 index /FontDescriptor knownoget {
  206.         % Stack: font-res fontname fontdesc
  207.       dup /Flags oget
  208.       dup 16#40 and -6 bitshift        % 1, oblique/italic
  209.       1 index 16#40000 and -17 bitshift add    % 2, bold
  210.       exch 16#2 and 2 bitshift add    % 8, serif
  211.         % We should look at the fixed flag, too.
  212.         % Stack: font-res fontname fontdesc properties
  213.       1 index /FontName oget exch
  214.         % Analyzes font name and extract "Narrow" property
  215.         % which is not described by the FontDescriptor Flags.
  216.       0 2 index .fontnameproperties 4 and or
  217.         % Rebind the default font name to Helvetica so that
  218.         % fonts with no properties are handled correctly.
  219.       //.pdfdfndict begin .substitutefontname end
  220.         % Stack: font-res fontname fontdesc substname|null
  221.       Fontmap 1 index known not {
  222.         % No available good substitution, use the standard one.
  223.     pop 1 index .substitutefont
  224.       } if
  225.       QUIET not {
  226.     (Substituting font ) print dup =only
  227.     ( for ) print 2 index =only (.) = flush
  228.       } if
  229.       3 -1 roll pop findfont
  230.         % Stack: font-res fontdesc font
  231.         % If this is a small-caps font, replace the CharString
  232.         % entries for a..z.
  233.       exch /Flags oget 16#20000 and 0 ne {
  234.     true .copyfontdict
  235.     dup /CharStrings 2 copy get dup length dict .copydict
  236.     4 index /FirstChar get 97 .max
  237.     5 index /LastChar get 122 .min 1 exch {
  238.         % Stack: font-res font' font' /CharStrings charstrings code
  239.         % Note that this only remaps a-z, not accented characters.
  240.       5 index /Widths oget 1 index 7 index /FirstChar get sub oget
  241.       1 string dup 0 5 -1 roll put
  242.         % Stack: font-res font' font' /CharStrings charstrings code
  243.         %   width (x)
  244.       2 index exch dup cvn exch
  245.       dup 0 2 copy get 32 sub put 4 -1 roll {
  246.             % Stack: operand (X) width
  247.         0 setcharwidth exch pop
  248.         currentfont /FontMatrix get matrix invertmatrix concat
  249.         0.7 dup scale 0 0 moveto show
  250.       } /exec cvx 4 packedarray cvx put
  251.     } for put
  252.     renamefont
  253.       } if
  254.     } {
  255.         % No descriptor available, use the default algorithm.
  256.       findfont
  257.     } ifelse
  258.   } ifelse adjustfont
  259. } bdef
  260.  
  261. % ---------------- Type 1 fonts ---------------- %
  262.  
  263. /buildType1        % <Type1-font-resource> buildType1 <font>
  264.  { dup /BaseFont get pdffindfont
  265.  } bdef
  266.  
  267. % The state dictionary for the embedded Type 1 font reading procedure
  268. % has the following keys and values:
  269. %    data - stream (filter)
  270. %    buffer, buffer2 - string
  271. %    hexify - procedure to convert buffer to hex if needed
  272. %    leftstr - string containing (non-negative) integer
  273. %    sectionstr - string containing a character 0 .. 2
  274. %    stream - (stream) dictionary
  275. %    proc - procedure of the form {-dict- type1read}
  276. % When the procedure is executing, this dictionary is current.
  277. % leftstr and sectionstr are strings so that we can change their values
  278. % reliably in case the font executes a restore!
  279. % We also have to do something special about embedded fonts that
  280. % execute definefont more than once -- that is the function of topFontDict.
  281.  
  282. % Read an embedded Type 1 font.
  283. /readfontfilter {    % <proc> readfontfilter <filter>
  284.   0 () /SubFileDecode filter
  285. } bdef
  286. /readtype1dict 5 dict dup begin
  287.   /definefont {
  288.     dup topFontDict eq topFontDict null eq or {
  289.       dup wcheck not { dup length dict copy } if
  290.       exch pop savedFontName exch
  291.     } if
  292.     //systemdict /definefont get exec
  293.   } bdef
  294.   /eexec {
  295.         % Assume the font dictionary is on the top of the stack.
  296.     count 0 gt { /topFontDict 1 index cvlit store } if
  297.     55665 /eexecDecode filter
  298.     //systemdict begin readtype1dictcopy begin cvx stopped
  299.     currentdict readtype1dictcopy eq { end } if
  300.     currentdict //systemdict eq { end } if
  301.      { stop } if
  302.   } bdef
  303. end readonly def
  304. /readtype1 {        % <font-resource> <stream-dict> readtype1 <font>
  305.         % Read the definition, using a procedure-based filter
  306.         % that turns binary/hex conversion on and off
  307.         % at the right times.
  308.    1 index exch
  309.    PDFfile fileposition 3 1 roll
  310.    10 dict begin
  311.      /leftstr (          ) 10 string copy def
  312.        dup /Length1 oget leftstr cvs pop
  313.      /sectionstr <00> 1 string copy def
  314.      /stream 1 index def
  315.      true resolvestream /data exch def
  316.      /buffer 1000 string def        % arbitrary
  317.      /buffer2 buffer length 2.1 div cvi 1 sub string def
  318.      /hexify /buf2hex load def
  319.    currentdict end
  320.    /type1read cvx 2 array astore cvx dup 0 get /proc 2 index put
  321.    readfontfilter
  322.         % Some buggy embedded fonts leave extra junk on the stack,
  323.         % so we have to make a closure that records the stack depth
  324.         % in a fail-safe way.
  325.    //systemdict begin
  326.         % The PDF specification is somewhat muddy about whether
  327.         % an embedded font's name is supposed to be the BaseFont
  328.         % from the Font object or the FontName from the descriptor.
  329.         % Acrobat Distiller requires the former.  Save away the
  330.         % name so we can substitute it at definefont time.
  331.    //readtype1dict dup length 3 add dict copy begin
  332.    1 index /BaseFont oget /savedFontName exch def
  333.    /topFontDict null def
  334.    /readtype1dictcopy currentdict def
  335.     { run } aload pop count 1 sub 2 packedarray cvx exec
  336.    end end
  337.    count exch sub { pop } repeat
  338.    PDFfile 3 -1 roll setfileposition
  339.    /BaseFont oget findfont
  340.    adjustfont
  341.  } bdef
  342.  
  343. % Execute the appropriate reading procedure.
  344. /type1read        % <dict> type1read <string>
  345.  { begin leftstr cvi
  346.     { type1read1 type1read2 type1read3 } sectionstr 0 get get exec
  347.    (          ) leftstr copy cvs pop end
  348.  } bdef
  349.  
  350. % Read the next block of data into the buffer.
  351. /type1readdata        % <left> <buffer> type1readdata <substring> <left'>
  352.  { 0 2 index 2 index length min getinterval
  353.         % Adobe requires readstring to signal an error if given
  354.         % an empty string.  Work around this nonsense here.
  355.    dup length 0 ne { data exch readstring pop } if
  356.    dup length 3 -1 roll exch sub
  357.    DEBUG
  358.     { dup =only ( read ) print
  359.       1 index length =only (: ) print
  360.       1 index == flush
  361.     } if
  362.  } bdef
  363.  
  364. % Read the next block of the initial text portion.
  365. /type1read1 {        % <left> type1read1 <string> <left'>
  366.   DEBUG { (read1 ) print } if
  367.   dup 0 eq {
  368.     pop sectionstr 0 1 put
  369.     stream /Length2 oget
  370.             % Determine whether to hexify data for eexec.
  371.     dup 8 lt {
  372.       type1read2    % Hexify.
  373.     } {
  374.       DEBUG { (read2 ) print } if
  375.       buffer2 type1readdata exch
  376.             % The check doesn't have to be 100% accurate:
  377.             % hexifying is always OK.
  378.       dup 0 8 getinterval 0 exch { or } forall
  379.       128 ge {
  380.     /hexify { } store
  381.     /buffer2 buffer def    % We don't need an intermediate buffer.
  382.       } if hexify exch
  383.     } ifelse
  384.   } {
  385.     buffer type1readdata
  386.   } ifelse
  387. } bdef
  388.  
  389. % Convert a string from binary to hex for eexec.
  390. % Free variables: buffer.
  391. /buf2hex {        % <string> buf2hex <hexstring>
  392.   buffer /ASCIIHexEncode filter dup 3 -1 roll writestring closefile
  393.   buffer (>) search pop exch pop exch pop
  394. } bdef
  395.  
  396. % Read the next block of the encrypted portion.
  397. /type1trailer
  398. (0000000000000000000000000000000000000000000000000000000000000000\n\
  399. 0000000000000000000000000000000000000000000000000000000000000000\n\
  400. 0000000000000000000000000000000000000000000000000000000000000000\n\
  401. 0000000000000000000000000000000000000000000000000000000000000000\n\
  402. 0000000000000000000000000000000000000000000000000000000000000000\n\
  403. 0000000000000000000000000000000000000000000000000000000000000000\n\
  404. 0000000000000000000000000000000000000000000000000000000000000000\n\
  405. 0000000000000000000000000000000000000000000000000000000000000000\n\
  406. cleartomark\n)
  407. readonly def
  408. /type1read2 {        % <left> type1read2 <string> <left'>
  409.   DEBUG { (read2 ) print } if
  410.    dup 0 eq
  411.     { pop sectionstr 0 2 put
  412.       stream /Length3 oget
  413.       dup 0 eq
  414.        { DEBUG { (trailer ) print } if
  415.      type1trailer exch
  416.        }
  417.        { type1read3
  418.        }
  419.       ifelse
  420.     }
  421.     { buffer2 type1readdata exch hexify exch
  422.     }
  423.    ifelse
  424. } bdef
  425.  
  426. % Read the next block of the final text portion.
  427. % When finished, this procedure returns an empty string.
  428. /type1read3        % <left> type1read3 <string> <left'>
  429.  { DEBUG { (read3 ) print } if
  430.    buffer type1readdata
  431.  } bdef
  432.  
  433. % ---------------- Type 3 fonts ---------------- %
  434.  
  435. /.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
  436.  
  437. /buildType3 {        % <Type3-font-resource> buildType3 <font>
  438.   8 dict begin
  439.     /FontType 3 def
  440.     /Resources 1 index /Resources knownoget { oforce } { 0 dict } ifelse def
  441.     /FontBBox 1 index /FontBBox get cvx def
  442.     /FontMatrix 1 index /FontMatrix oget def
  443.     /CharProcs 1 index /CharProcs oget def
  444.     1 index /Widths knownoget {
  445.       /Widths exch def
  446.       /FirstChar 1 index /FirstChar oget def
  447.       /LastChar 1 index /LastChar oget def
  448.     } if
  449.     /FontName 1 index /Name get genfontname def
  450.     /Encoding .notdefEncoding 2 index getencoding def
  451.         % We have to define BuildChar rather than BuildGlyph:
  452.         % there is no PDF equivalent of glyphshow, and we need
  453.         % the character code to access the Widths.
  454.     /BuildChar {
  455.         % Stack: font charcode
  456.       1 index begin 3 dict begin
  457.       /Font 3 -1 roll def /CharCode 1 index def
  458.       Encoding exch get CharProcs exch oget
  459.       PDFfile fileposition exch
  460.       false resolvestream
  461.         % Stack: filepos stream
  462.         % Don't let setgcolor set the color inside the BuildGlyph
  463.         % procedure, because this causes an /undefined error.
  464.       q null /FillColor gput null /StrokeColor gput
  465.       Font /Resources get exch pdfopdict .pdfruncontext
  466.       Q
  467.       PDFfile exch setfileposition
  468.       end end
  469.     } bdef
  470.     FontName currentdict end definefont exch pop
  471. } bdef
  472. /.adjustcharwidth {    % <wx> <wy> .adjustcharwidth <wx'> <wy'>
  473.   /Widths where {
  474.     begin
  475.     CharCode FirstChar ge CharCode LastChar le and {
  476.       exch pop Widths CharCode FirstChar sub get exch
  477.     } if end
  478.   } if
  479. } bdef
  480.  
  481. % ---------------- TrueType fonts ---------------- %
  482.  
  483. /TTfonts mark
  484.   /Arial /Helvetica
  485.   /Arial,Italic /Helvetica-Oblique
  486.   /Arial,Bold /Helvetica-Bold
  487.   /Arial,BoldItalic /Helvetica-BoldOblique
  488.   /CourierNew /Courier
  489.   /CourierNew,Bold /Courier-Bold
  490.   /TimesNewRoman /Times-Roman
  491.   /TimesNewRoman,Italic /Times-Italic
  492.   /TimesNewRoman,Bold /Times-Bold
  493.   /TimesNewRoman,BoldItalic /Times-BoldItalic
  494. .dicttomark readonly def
  495.  
  496. /buildTrueType {    % <TrueType-font-resource> buildTrueType <font>
  497.   dup /BaseFont get
  498.   dup TTfonts exch .knownget {
  499.     exch pop
  500.         % Hack required by the PDF specification: if the
  501.         % font resource has Subtype = /TrueType but the actual
  502.         % (installed) font is not a TrueType font, ignore the
  503.         % Encoding in the font resource.  However, all current
  504.         % versions of Acrobat Reader have the 14 base TrueType
  505.         % fonts built in, so this produces incorrect output for
  506.         % badly designed PDF files that specify these file names
  507.         % with /Subtype = /TrueType but no embedded definition.
  508.         % Compensate for this by removing the /Subtype key when
  509.         % looking up the font.
  510.     exch dup length dict copy dup /Subtype null put exch
  511.   } if pdffindfont
  512. } bdef
  513.  
  514. % Read an embedded TrueType font.
  515. /readtruetype {        % <font-resource> <stream-dict> readtruetype <font>
  516.         % This is much simpler than readtype1, because we don't
  517.         % have to deal with the tripartite .PFB format.
  518.   1 index exch
  519.   PDFfile fileposition 3 1 roll
  520.   true resolvestream readfontfilter
  521.         % Stack: filepos fontres stream
  522.   1 index /Subtype get /CIDFontType2 eq {
  523.     .loadttcidfont
  524.         % Stack: filepos fontres cidfont
  525.     1 index /CIDToGIDMap knownoget {
  526.       dup /Identity eq {
  527.     pop
  528.       } {
  529.     true resolvestream
  530.         % The following doesn't work for CIDToGIDMaps with more
  531.         % than 32K-1 entries.  We'll fix it later if necessary.
  532.         % Stack: filepos fontres font mapstream
  533.     dup 2 index /CIDCount oget 2 mul string readstring pop exch closefile
  534.     exch dup length 5 add dict .copydict
  535.     dup /FID undef
  536.     dup /CIDMap 4 -1 roll put
  537.     dup /CIDFontName get exch /CIDFont defineresource
  538.       } ifelse
  539.     } if
  540.   } {
  541.     null 2 index getencoding .loadpdfttfont
  542.   } ifelse
  543.   exch pop
  544.   PDFfile 3 -1 roll setfileposition
  545.         % Ignore both the Encoding and the Widths.
  546.   exch pop
  547. } bdef
  548.  
  549. % ---------------- Type 0 fonts ---------------- %
  550.  
  551. % Predefine the known CMaps, but only create them on demand.
  552. /knownCMaps mark
  553.   /Identity-H { /Identity-H 0 makeIdentityCMap }
  554.   /Identity-V { /Identity-V 1 makeIdentityCMap }
  555. .dicttomark def
  556.  
  557. /makeIdentityCMap {        % <cmapname> <wmode> .makeIdentityCMap -
  558.   .currentglobal true .setglobal 3 1 roll
  559.   /CIDInit /ProcSet findresource begin
  560.   12 dict begin
  561.     begincmap
  562.     /WMode exch def
  563.     /CMapName exch def
  564.     /CIDSystemInfo 3 dict dup begin
  565.       /Registry (Adobe) def
  566.       /Ordering (Japan1) def
  567.       /Supplement 0 def
  568.     end def
  569.     %/CMapName (see above)
  570.     /CMapVersion 1 def
  571.     /CMapType 1 def
  572.     %WMode (see above)
  573.     % The PDF documentation says that these CMaps map CIDs
  574.     % "1 to 65,536".  This is a misprint for 0 to 65,535.
  575.     1 begincodespacerange
  576.     % <0001> <00ff>  <0100> <ffff>
  577.       <0000> <ffff>
  578.     endcodespacerange
  579.     1 begincidrange
  580.     % <0001> <00ff> 1   <0100> <ffff> 256
  581.       <0000> <ffff> 0
  582.     endcidrange
  583.     endcmap
  584.     CMapName currentdict /CMap defineresource
  585.     knownCMaps CMapName 2 index put
  586.   end        % CMap
  587.   end        % CIDInit ProcSet
  588.   exch .setglobal
  589. } bdef
  590.  
  591. /buildType0 {        % <Type0-font-resource> buildType0 <font>
  592.   dup /BaseFont get    % FontName
  593.   1 index /Encoding oget
  594.   dup type /nametype eq {
  595.     dup /CMap resourcestatus {
  596.     pop pop /CMap findresource
  597.     } {
  598.     knownCMaps 1 index .knownget
  599.       { exch pop exec } { /undefined signalerror } ifelse
  600.     } ifelse
  601.   } {
  602.     PDFfile fileposition exch
  603.     dup /CMapName get exch true resolvestream cvx exec
  604.     /CMap findresource
  605.     exch PDFfile exch setfileposition
  606.   } ifelse        % CMap
  607.   [
  608.     3 index /DescendantFonts oget { exec resourcefont } forall
  609.   ]            % subfonts
  610.   composefont
  611.         % Stack: fontres font
  612.   1 index /FontMatrix knownoget {
  613.     dup aload pop true {0 0 1 0 0 1} {3 -1 roll eq and} forall {
  614.       1 index exch makefont exch /FontName get exch definefont
  615.     } {
  616.       pop
  617.     } ifelse
  618.   } if exch pop
  619. } bdef
  620.  
  621. % ---------------- CIDFontType0/2 fonts ---------------- %
  622.  
  623. % Insert metrics into a CIDFont, by saving the PDF W, W2, DW, and DW2
  624. % arrays and using a (currently very inefficient) CDevProc.
  625. /addCIDmetrics {    % <CIDFont-resource> <CIDFont> addCIDmetrics <fontdict>
  626.   dup length 5 add dict .copydict
  627.   dup /FID undef
  628.   dup /UniqueID undef
  629.   dup /XUID undef
  630.     % Insert the widths into the font.
  631.   {W W2 DW DW2} {
  632.     % Stack: pdfresource newfont key
  633.     2 index 1 index .knownget {
  634.       2 index 3 1 roll put
  635.     } {
  636.       pop
  637.     } ifelse
  638.   } forall
  639.   dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put
  640.   exch pop
  641. } bdef
  642.  
  643. % Apply the [D]W[2] metrics to a character before displaying.
  644. /CIDWProc {        % <w0x> <w0y> <llx> <lly> <urx> <ury>
  645.             %   <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc
  646.             %   <w0x'> ... <vy'>
  647.   begin
  648.     % Look up and apply [D]W
  649.   10 index
  650.   currentdict /DW .knownget { 1000 div exch pop } if
  651.   currentdict /W .knownget {
  652.     % Search the W array for the CID.
  653.     % ****** NOT IMPLEMENTED YET ******
  654.     pop
  655.   } if
  656.   0 13 2 roll 11 -2 roll pop pop
  657.     % Look up and apply [D]W2
  658.     % ****** NOT IMPLEMENTED YET ******
  659.   pop end
  660. } bdef
  661.  
  662. /buildCIDType0 {    % <CIDFontType0-font-resource> buildCIDType0 <font>
  663.   dup /BaseFont get /CIDFont findresource
  664.   addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource
  665. } bdef
  666.  
  667. /buildCIDType2 {    % <CIDFontType2-font-resource> buildCIDType2 <font>
  668.   dup /BaseFont get /CIDFont findresource
  669.   addCIDmetrics dup /BaseFont get exch /CIDFont defineresource
  670. } bdef
  671.  
  672. % ---------------- Other embedded fonts ---------------- %
  673.  
  674. /fontloadprocs mark
  675.   /Type1C /readType1C cvx
  676.   /CIDFontType0C /readCIDFontType0C cvx
  677. .dicttomark readonly def
  678.  
  679. % Read an embedded compressed font.
  680. /readType1C {        % <font-resource> <stream-dict> readType1C <font>
  681.   1 index exch
  682.   PDFfile fileposition 3 1 roll
  683.   dup true resolvestream dup readfontfilter
  684.         % Stack: pos resource streamdict stream filter
  685.   3 index /FontDescriptor oget /FontName oget
  686.   1 index FRD
  687.   closefile closefile pop
  688.   PDFfile 3 -1 roll setfileposition
  689.   /FontDescriptor oget /FontName oget findfont
  690.   adjustfont
  691. } bdef
  692.  
  693. % Read an embedded CFF CIDFont.
  694. /readCIDFontType0C {  % <font-resource> <stream-dict> readCIDFontType0C <font>
  695.   PDFfile fileposition 3 1 roll
  696.   dup true resolvestream dup readfontfilter
  697.         % Stack: pos resource streamdict stream filter
  698.   3 index /FontDescriptor oget /FontName oget
  699.   1 index FRD
  700.   closefile closefile pop
  701.   PDFfile 3 -1 roll setfileposition
  702.         % Some broken Adobe software produces PDF files in which
  703.         % the FontName of the CFF font and the FontName in the
  704.         % FontDescriptor don't match the BaseFont in the font.
  705.         % Use the FontName, rather than the BaseFont, here.
  706.   dup /FontDescriptor oget /FontName oget /CIDFont findresource
  707.   addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource
  708. } bdef
  709.  
  710. % ---------------- Font lookup ---------------- %
  711.  
  712. /fonttypeprocs mark        % <font-resource> -proc- <font>
  713.   /Type0 /buildType0 cvx
  714.   /Type1 /buildType1 cvx
  715.   /MMType1 1 index
  716.   /Type3 /buildType3 cvx
  717.   /TrueType /buildTrueType cvx
  718.   /CIDFontType0 /buildCIDType0 cvx
  719.   /CIDFontType2 /buildCIDType2 cvx
  720. .dicttomark readonly def
  721.  
  722. /resourcefont            % <font-resource> resourcefont <font>
  723.  { dup /PSFont .knownget
  724.     { /FID .knownget { type /fonttype eq } { false } ifelse }
  725.     { false }
  726.    ifelse
  727.     { /PSFont get
  728.     }
  729.     { dup dup /FontDescriptor knownoget
  730.        {    % Stack: font-res font-res font-desc
  731.      dup /FontFile knownoget
  732.       { exch pop readtype1 true }
  733.       { dup /FontFile2 knownoget
  734.          { exch pop readtruetype true }
  735.          { /FontFile3 knownoget
  736.         { dup /Subtype get fontloadprocs exch get exec true }
  737.         { false }
  738.            ifelse
  739.          }
  740.         ifelse
  741.       }
  742.      ifelse
  743.        }
  744.        { false }
  745.       ifelse
  746.         % Stack: font-res font-res false
  747.         %  -or-: font-res font true
  748.       not
  749.        { dup /Subtype get fonttypeprocs exch get exec }
  750.       if
  751.       2 copy /PSFont exch put
  752.       exch pop
  753.     }
  754.    ifelse
  755.  } bdef
  756.  
  757. drawopdict begin
  758.   /d0 {
  759.     .adjustcharwidth setcharwidth
  760.   } bdef
  761.   /d1 {
  762.     6 -2 roll .adjustcharwidth 6 2 roll setcachedevice
  763.   } bdef
  764.   /Tf {
  765.     1 index Page /Font rget not { 1 index /invalidfont signalerror } if
  766.     resourcefont exch Tf pop
  767.   } bdef
  768. end
  769.  
  770. end            % pdfdict
  771. end            % GS_PDF_ProcSet
  772. .setglobal
  773.