home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / GhostScript / !GhostScr / 6_01 / lib / pdf_font.ps < prev    next >
Text File  |  2000-03-29  |  22KB  |  695 lines

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