summaryrefslogtreecommitdiff
path: root/Master/xemtex/gslib/pdf_font.ps
diff options
context:
space:
mode:
Diffstat (limited to 'Master/xemtex/gslib/pdf_font.ps')
-rw-r--r--Master/xemtex/gslib/pdf_font.ps1224
1 files changed, 1224 insertions, 0 deletions
diff --git a/Master/xemtex/gslib/pdf_font.ps b/Master/xemtex/gslib/pdf_font.ps
new file mode 100644
index 00000000000..525ae34866e
--- /dev/null
+++ b/Master/xemtex/gslib/pdf_font.ps
@@ -0,0 +1,1224 @@
+% Copyright (C) 1994-2002 artofcode LLC. All rights reserved.
+%
+% This program is free software; you can redistribute it and/or modify it
+% under the terms of the GNU General Public License as published by the
+% Free Software Foundation; either version 2 of the License, or (at your
+% option) any later version.
+%
+% This program is distributed in the hope that it will be useful, but
+% WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+% Public License for more details.
+%
+% You should have received a copy of the GNU General Public License along
+% with this program; if not, write to the Free Software Foundation, Inc.,
+% 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
+
+% $Id: pdf_font.ps,v 1.23.2.6.2.1 2003/04/12 14:02:39 giles Exp $
+% pdf_font.ps
+% PDF font operations.
+
+/.setlanguagelevel where { pop 2 .setlanguagelevel } if
+.currentglobal true .setglobal
+/pdfdict where { pop } { /pdfdict 100 dict def } ifelse
+GS_PDF_ProcSet begin
+pdfdict begin
+
+% We cache the PostScript font in an additional element of the
+% font resource dictionary, called PSFont.
+
+% ---------------- Encodings ---------------- %
+
+% Apply a list of differences to an Encoding.
+% Note that the differences may cause the array to grow.
+/updateencoding { % <encoding> <differences> updateencoding <enc'>
+ % Calculate the length of the result.
+ exch 0 2 index {
+ dup type /nametype ne { exch pop } { pop 1 add } ifelse
+ } forall
+ 1 index length .max array dup 0 4 -1 roll putinterval
+ exch 0 exch {
+ % Stack: enc' code element
+ dup type /nametype ne
+ { exch pop }
+ { 3 copy put pop 1 add }
+ ifelse
+ } forall pop
+} bdef
+
+% Get the Encoding for a font.
+/getencoding % <base-encoding> <font-resource> getencoding <enc>
+ { /Encoding knownoget
+ { dup type /nametype eq
+ {
+ % The published PDF specification says the Encoding name
+ % "must be" one of the 3 predefined Encodings, implying
+ % that an error should occur if it isn't. However, Acrobat
+ % Reader simply ignores unknown names, and since there are
+ % some buggy applications that rely on this, we do the same.
+
+ dup dup dup /MacRomanEncoding eq
+ exch /MacExpertEncoding eq or
+ exch /WinAnsiEncoding eq or
+ { exch pop findencoding
+ }
+ { pop
+ }
+ ifelse
+ }
+ { dup /BaseEncoding knownoget
+ { findencoding 3 -1 roll pop exch
+ }
+ if
+ /Differences knownoget { updateencoding } if
+ }
+ ifelse
+ }
+ if
+ } bdef
+
+% Rename a font with a generated name.
+/renamefont { % <fontdict> renamefont <font'>
+ dup /FontName 2 copy get genfontname dup 5 1 roll put definefont
+} bind def
+
+% Adjust a font according to the Encoding and Widths in the font resource.
+/adjustfont { % <font-resource> <font> adjustfont <font'>
+ getfontencoding
+ getfontmetrics 4 -1 roll pop .updatefont { renamefont } if
+} bind def
+
+% Get the (possibly modified) encoding of a font.
+/getfontencoding { % <font-resource> <font> getfontencoding
+ % <font-resource> <font> <Encoding|null>
+ 1 index /Encoding known {
+ dup /Encoding .knownget { 2 index getencoding } { null } ifelse
+ } {
+ null
+ } ifelse
+} bdef
+
+/find_in_diff % <Differences> <index> find_in_diff <bool>
+{ false exch 0 4 3 roll
+ { dup type /nametype ne { exch pop } { pop 1 add } ifelse
+ 2 copy eq {
+ pop pop pop true 0 0 exit
+ } if
+ } forall
+ pop pop
+} bdef
+
+% Get the metrics of a font, if specified.
+/getfontmetrics { % <font-resource> <font> <Encoding|null> getfontmetrics
+ % <font-resource> <font> <Encoding|null>
+ % <Metrics|null>
+ 2 index /Widths known {
+ dup null eq { pop dup /Encoding get } if
+ 4 dict begin
+ /Encoding exch def
+ /Metrics Encoding length dict def
+ exch
+ dup /Widths oget /Widths exch def
+ % Stack: font font-res
+ % Note that widths are always based on a 1000-unit
+ % character space, but the FontMatrix may specify
+ % some other scale factor. Compensate for this here,
+ % by scaling the Widths if necessary.
+ 0.001 2 index /FontMatrix get 0 get div
+ % Stack: font font-res mscale
+ 1 index /FirstChar oget dup 1 4 index /LastChar oget
+ { % Stack: font font-res mscale first-char index
+ Encoding 1 index get
+ Widths 2 index 4 index sub oget
+ % Stack: font font-res mscale first-char index charname width
+ 4 index mul
+ % The following 'loop' is only context for 'exit'.
+ {
+ % Work around a bug in pdfTeX, which can generate Encoding
+ % vectors containing nulls :
+ 1 index null eq { exit } if
+ % There is a hack here to deal with encodings where the
+ % same character appears more than once, because the Metrics
+ % dictionary works by character name, not by character code.
+ % We prefer to take (1) non-zero width, and (2) width for
+ % the character code which appears in Differences.
+ Metrics 2 index .knownget not { 0 } if 0 ne {
+ 5 index /Encoding knownoget not { exit } if
+ dup type /dicttype ne { pop exit } if
+ /Differences knownoget not { exit } if
+ 3 index //find_in_diff exec not { exit } if
+ } if
+ 2 copy Metrics 3 1 roll put
+ exit
+ } loop
+ pop pop pop
+ }
+ for pop
+ % Now fill in the MissingWidth for any encoded characters
+ % that aren't in Metrics already. Note that built-in
+ % fonts may have Widths/FirstChar/LastChar but no
+ % FontDescriptor, so we must check for this.
+ % Stack: font font-res mscale
+ 1 index /FontDescriptor knownoget {
+ Metrics exch
+ /MissingWidth knownoget { 2 index mul } { 0 } ifelse exch
+ Encoding {
+ % Stack: font font-res mscale missing-width metrics charname
+ % Work around the abovementioned pdfTeX bug.
+ dup null ne {
+ 2 copy known not { 2 copy 4 index put } if pop
+ } {
+ pop
+ } ifelse
+ } forall pop pop pop
+ } {
+ pop
+ } ifelse
+ exch Encoding Metrics end
+ } {
+ null
+ } ifelse
+} bdef
+
+currentdict /find_in_diff undef
+
+% ---------------- Descriptors ---------------- %
+
+% Partial descriptors for the 14 built-in fonts. Note that
+% from PDF 1.1 to PDF 1.2, the meaning of the Flag 6 in the FontDescriptor
+% object has undergone a subtle change in its meaning which has serious
+% consequences for searching with Acrobat:
+% In PDF 1.1, the flag meant: Font has StandardEncoding
+% In PDF 1.2, the flag means: Font has (subset of) StandardRomanCharacterSet
+/standardfontdescriptors mark
+ /Courier mark /Flags 16#23 .dicttomark
+ /Courier-Oblique 1 index
+ /Courier-Bold 1 index
+ /Courier-BoldOblique 1 index
+ /Helvetica mark /Flags 16#20 .dicttomark
+ /Helvetica-Oblique 1 index
+ /Helvetica-Bold 1 index
+ /Helvetica-BoldOblique 1 index
+ /Times-Roman mark /Flags 16#22 .dicttomark
+ /Times-Bold 1 index
+ /Times-Italic mark /Flags 16#62 .dicttomark
+ /Times-BoldItalic 1 index
+ /Symbol mark /Flags 16#4 .dicttomark
+ /ZapfDingbats 1 index
+.dicttomark readonly def
+
+% ---------------- Utilities ---------------- %
+
+/.glyphpath { % <glyphname> <boolean> .glyphpath -
+ % another glyphpath written in addxchar.ps does not work here...
+ currentfont 3 1 roll exch
+ currentfont dup length dict begin
+ { 1 index /Encoding eq { pop [ 3 -1 roll ] def } { def } ifelse } forall
+ currentdict end /.glyphpathfont exch definefont
+ setfont <00> exch charpath setfont
+} bdef
+
+/makeboldfont { % <basefont> <strokewidth> makeboldfont <boldfont>
+ 10 dict begin
+ /strokewidth exch def
+ /basefont exch def
+ /FontMatrix matrix def
+ %/FontName basefont /FontName get def
+ /FontName /.boldfont def
+ /FontType 3 def
+ /Encoding basefont /Encoding get def
+ /FontBBox [ basefont /FontBBox get cvx exec
+ 4 2 roll basefont /FontMatrix get transform
+ 4 2 roll basefont /FontMatrix get transform
+ ] def
+ /BuildGlyph {
+ gsave
+ exch begin
+ basefont setfont
+ strokewidth setlinewidth
+ 1 setlinejoin
+ newpath
+ 0 0 moveto dup false .glyphpath stroke
+ 0 0 moveto glyphshow
+ currentpoint setcharwidth
+ end
+ grestore
+ } bind def
+ currentdict
+ end
+ dup /FontName get exch definefont
+} bind def
+
+% Fabricate a font name by adding ?'s on the end.
+/genfontname % <name> genfontname <name>
+ { dup length string cvs
+ { (?) concatstrings
+ dup cvn FontDirectory exch known not { cvn exit } if
+ }
+ loop
+ } bdef
+
+% Find a font, and adjust its encoding if necessary.
+/.pdfdfndict mark
+ /defaultfontname /Helvetica
+.dicttomark readonly def
+/pdffindfont { % <font-resource> <fontname> pdffindfont <font>
+ % If the font isn't available, synthesize one based on
+ % its descriptor.
+ dup /Font resourcestatus {
+ pop pop findfont
+ } {
+ 1 index /FontDescriptor knownoget {
+ % Stack: font-res fontname fontdesc
+ dup /Flags oget
+ dup 16#40 and -6 bitshift % 1, oblique/italic
+ 1 index 16#40000 and -17 bitshift add % 2, bold
+ exch 16#2 and 2 bitshift add % 8, serif
+ % We should look at the fixed flag, too.
+ % Stack: font-res fontname fontdesc properties
+ 1 index /FontName oget exch
+ % Analyzes font name and extract "Narrow" property
+ % which is not described by the FontDescriptor Flags.
+ 0 2 index .fontnameproperties 4 and or
+ % Rebind the default font name to Helvetica so that
+ % fonts with no properties are handled correctly.
+ //.pdfdfndict begin .substitutefontname end
+ % Stack: font-res fontname fontdesc substname|null
+ Fontmap 1 index known not {
+ % No available good substitution, use the standard one.
+ pop 1 index .substitutefont
+ } if
+ QUIET not {
+ (Substituting font ) print dup =only
+ ( for ) print 2 index =only (.) = flush
+ } if
+ 3 -1 roll pop findfont
+ % Stack: font-res fontdesc font
+ % If this is a small-caps font, replace the CharString
+ % entries for a..z.
+ exch /Flags oget 16#20000 and 0 ne {
+ true .copyfontdict
+ dup /CharStrings 2 copy get dup length dict .copydict
+ 4 index /FirstChar get 97 .max
+ 5 index /LastChar get 122 .min 1 exch {
+ % Stack: font-res font' font' /CharStrings charstrings code
+ % Note that this only remaps a-z, not accented characters.
+ 5 index /Widths oget 1 index 7 index /FirstChar get sub oget
+ 1 string dup 0 5 -1 roll put
+ % Stack: font-res font' font' /CharStrings charstrings code
+ % width (x)
+ 2 index exch dup cvn exch
+ dup 0 2 copy get 32 sub put 4 -1 roll {
+ % Stack: operand (X) width
+ 0 setcharwidth exch pop
+ currentfont /FontMatrix get matrix invertmatrix concat
+ 0.7 dup scale 0 0 moveto show
+ } /exec cvx 4 packedarray cvx put
+ } for put
+ renamefont
+ } if
+ } {
+ % No descriptor available, use the default algorithm.
+ findfont
+ } ifelse
+ } ifelse adjustfont
+} bdef
+/findpdffont { % <font-resource> <fontname> findpdffont <font>
+ {} 3 1 roll % proc fnres fnname
+ [
+ [ (,Bold) { .03 makeboldfont } ]
+ [ (,BoldItalic) { .03 makeboldfont [ 1 0 .3 1 0 0 ] makefont } bind ]
+ [ (,Italic) { [ 1 0 .3 1 0 0 ] makefont } bind ]
+ ] {
+ 1 index dup length string cvs
+ 1 index 0 get tailmatch { % proc fnres fnname []
+ 3 -1 roll pop exch 1 get % proc fnres pre-fnname proc
+ 4 -1 roll pop 3 1 roll % proc fnres pre-fnname
+ exit
+ } { pop pop } ifelse % proc fnres fnname
+ } forall
+ pdffindfont exch exec
+} bdef
+
+% ---------------- Type 1 fonts ---------------- %
+
+/buildType1 % <Type1-font-resource> buildType1 <font>
+ { dup /BaseFont get pdffindfont
+ } bdef
+
+% The state dictionary for the embedded Type 1 font reading procedure
+% has the following keys and values:
+% data - stream (filter)
+% buffer, buffer2 - string
+% hexify - procedure to convert buffer to hex if needed
+% leftstr - string containing (non-negative) integer
+% sectionstr - string containing a character 0 .. 3
+% stream - (stream) dictionary
+% proc - procedure of the form {-dict- type1read}
+% pfbhdr - string containing 16#80 if PFB, 0 otherwise
+% When the procedure is executing, this dictionary is current.
+% leftstr and sectionstr are strings so that we can change their values
+% reliably in case the font executes a restore!
+% We also have to do something special about embedded fonts that
+% execute definefont more than once -- that is the function of topFontDict.
+
+% Read an embedded Type 1 font.
+/readfontfilter { % <proc> readfontfilter <filter>
+ 0 () /SubFileDecode filter
+} bdef
+/readtype1dict 5 dict dup begin
+ /definefont {
+ dup topFontDict eq topFontDict null eq or {
+ dup wcheck not { dup length dict copy } if
+ exch pop savedFontName exch
+ } if
+ //systemdict /definefont get exec
+ } bdef
+ /eexec {
+ % Assume the font dictionary is directly below the file on the stack
+ count 0 gt { /topFontDict 2 index cvlit store } if
+ 55665 /eexecDecode filter
+ //systemdict begin readtype1dictcopy begin cvx stopped
+ currentdict readtype1dictcopy eq { end } if
+ currentdict //systemdict eq { end } if
+ { stop } if
+ } bdef
+end readonly def
+/readtype1 { % <font-resource> <stream-dict> readtype1 <font>
+ % Read the definition, using a procedure-based filter
+ % that turns binary/hex conversion on and off
+ % at the right times.
+ 1 index exch
+ PDFfile fileposition 3 1 roll
+ 11 dict begin
+ /leftstr ( ) 10 string copy def
+ dup /Length1 oget leftstr cvs pop
+ /sectionstr <00> 1 string copy def
+ /pfbhdr <00> 1 string copy def
+ /stream 1 index def
+ true resolvestream /data exch def
+ /buffer 1000 string def % arbitrary
+ /buffer2 buffer length 2.1 div cvi 1 sub string def
+ /hexify /buf2hex load def
+ currentdict end
+ /type1read cvx 2 array astore cvx dup 0 get /proc 2 index put
+ readfontfilter
+ % Some buggy embedded fonts leave extra junk on the stack,
+ % so we have to make a closure that records the stack depth
+ % in a fail-safe way.
+ //systemdict begin
+ % The PDF specification is somewhat muddy about whether
+ % an embedded font's name is supposed to be the BaseFont
+ % from the Font object or the FontName from the descriptor.
+ % Acrobat Distiller requires the former. Save away the
+ % name so we can substitute it at definefont time.
+ //readtype1dict dup length 3 add dict copy begin
+ 1 index /BaseFont oget /savedFontName exch def
+ /topFontDict null def
+ /readtype1dictcopy currentdict def
+ { run } aload pop count 1 sub 2 packedarray cvx exec
+ end end
+ count exch sub { pop } repeat
+ PDFfile 3 -1 roll setfileposition
+ /BaseFont oget findfont
+ adjustfont
+ } bdef
+
+% Execute the appropriate reading procedure.
+/type1read % <dict> type1read <string>
+ { begin leftstr cvi
+ { type1read0 type1read1 type1read2 type1read3 } sectionstr 0 get get exec
+ ( ) leftstr copy cvs pop end
+ } bdef
+
+% Read the next block of data into the buffer.
+/type1readdata % <left> <buffer> type1readdata <substring> <left'>
+ { 0 2 index 2 index length .min getinterval
+ % Adobe requires readstring to signal an error if given
+ % an empty string. Work around this nonsense here.
+ dup length 0 ne { data exch readstring pop } if
+ dup length 3 -1 roll exch sub
+ DEBUG
+ { dup =only ( read ) print
+ 1 index length =only (: ) print
+ 1 index == flush
+ } if
+ } bdef
+
+% Read the initial byte to see if we need to skip a 6 byte PFB header
+/type1read0 { % <left> type1read0 <string> <left'>
+ sectionstr 0 1 put % either way we go to the next stage
+ pfbhdr type1readdata
+ 1 index 0 get 16#80 eq {
+ (\n **** Warning: Embedded Type1 font in PFB format is not valid PDF.)
+ pdfformaterror
+ DEBUG { (skipping PFB header) = flush } if
+ exch pop buffer 0 5 getinterval type1readdata exch
+ dup 4 get 256 mul 1 index 3 get add 256 mul
+ 1 index 2 get add 256 mul 1 index 1 get add
+ DEBUG { (PFB segment length = ) print dup = } if
+ exch pop % discard the string keeping the PFB segment length
+ 2 copy ne {
+ (\n **** Warning: Type 1 PFB segment length and Length 1 value do not match.)
+ pdfformaterror
+ exch % keep the PFB length instead
+ } if
+ pop
+ buffer type1readdata % go ahead and read a block
+ }
+ if % if not PFB, return pfbhdr string (first char of file, usually %).
+} bdef
+
+% Read the next block of the initial text portion.
+/type1read1 { % <left> type1read1 <string> <left'>
+ DEBUG { (read1 ) print } if
+ dup 0 eq {
+ pop sectionstr 0 2 put
+ stream /Length2 oget
+ % Determine whether to hexify data for eexec.
+ dup 8 lt {
+ type1read2 % Hexify.
+ } {
+ DEBUG { (read2 ) print } if
+ pfbhdr 0 get 16#80 eq {
+ % eat 6 more bytes of PFB junk before proceeding
+ DEBUG { (skipping PFB header in segment 2) = flush } if
+ buffer 0 6 getinterval type1readdata exch
+ dup 5 get 256 mul 1 index 4 get add 256 mul
+ 1 index 3 get add 256 mul 1 index 2 get add
+ DEBUG { (PFB segment length = ) print dup = } if
+ exch pop % discard the string keeping the PFB segment length
+ 2 copy ne {
+ (\n **** Warning: Type 1 PFB segment length and Length 2 value do not match.)
+ pdfformaterror
+ dup =
+ exch % keep the PFB length instead
+ } if
+ pop
+ } if
+ buffer2 type1readdata exch
+ % The check doesn't have to be 100% accurate:
+ % hexifying is always OK.
+ dup 0 8 getinterval 0 exch { or } forall
+ 128 ge {
+ /hexify { } store
+ /buffer2 buffer def % We don't need an intermediate buffer.
+ } if hexify exch
+ } ifelse
+ } {
+ buffer type1readdata
+ } ifelse
+} bdef
+
+% Convert a string from binary to hex for eexec.
+% Free variables: buffer.
+/buf2hex { % <string> buf2hex <hexstring>
+ buffer /ASCIIHexEncode filter dup 3 -1 roll writestring closefile
+ buffer (>) search pop exch pop exch pop
+} bdef
+
+% Read the next block of the encrypted portion.
+/type1trailer
+(0000000000000000000000000000000000000000000000000000000000000000\n\
+0000000000000000000000000000000000000000000000000000000000000000\n\
+0000000000000000000000000000000000000000000000000000000000000000\n\
+0000000000000000000000000000000000000000000000000000000000000000\n\
+0000000000000000000000000000000000000000000000000000000000000000\n\
+0000000000000000000000000000000000000000000000000000000000000000\n\
+0000000000000000000000000000000000000000000000000000000000000000\n\
+0000000000000000000000000000000000000000000000000000000000000000\n\
+cleartomark\n)
+readonly def
+/type1read2 { % <left> type1read2 <string> <left'>
+ DEBUG { (read2 ) print } if
+ dup 0 eq
+ { pop sectionstr 0 3 put
+ stream /Length3 oget
+ dup 0 eq
+ { DEBUG { (trailer ) print } if
+ type1trailer exch
+ }
+ {
+ pfbhdr 0 get 16#80 eq {
+ % eat 6 more bytes of PFB junk before proceeding
+ DEBUG { (skipping PFB header in segment 3) = flush } if
+ buffer 0 6 getinterval type1readdata exch
+ dup 5 get 256 mul 1 index 4 get add 256 mul
+ 1 index 3 get add 256 mul 1 index 2 get add
+ DEBUG { (PFB segment length = ) print dup = } if
+ exch pop % discard the string keeping the PFB segment length
+ 2 copy ne {
+ (\n **** Warning: Type 1 PFB segment length and Length 3 value do not match.)
+ pdfformaterror
+ exch % keep the PFB length instead
+ } if
+ pop
+ (\n) pdfformaterror
+ } if
+ type1read3
+ }
+ ifelse
+ }
+ { buffer2 type1readdata exch hexify exch
+ }
+ ifelse
+} bdef
+
+% Read the next block of the final text portion.
+% When finished, this procedure returns an empty string.
+/type1read3 % <left> type1read3 <string> <left'>
+ { DEBUG { (read3 ) print } if
+ buffer type1readdata
+ } bdef
+
+% ---------------- Type 3 fonts ---------------- %
+
+/.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
+
+/buildType3 { % <Type3-font-resource> buildType3 <font>
+ 8 dict begin
+ /FontType 3 def
+ /Resources 1 index /Resources knownoget { oforce } { 0 dict } ifelse def
+ /FontBBox 1 index /FontBBox get cvx def
+ /FontMatrix 1 index /FontMatrix oget def
+ /CharProcs 1 index /CharProcs oget def
+ 1 index /Widths knownoget {
+ /Widths exch def
+ /FirstChar 1 index /FirstChar oget def
+ /LastChar 1 index /LastChar oget def
+ } if
+ /FontName 1 index /Name get genfontname def
+ /Encoding .notdefEncoding 2 index getencoding def
+ % We have to define BuildChar rather than BuildGlyph:
+ % there is no PDF equivalent of glyphshow, and we need
+ % the character code to access the Widths.
+ /BuildChar {
+ % Stack: font charcode
+ 1 index begin 3 dict begin
+ /Font 3 -1 roll def /CharCode 1 index def
+ % Make unknown characters map to /.notdef
+ Encoding exch get dup CharProcs exch known
+ { CharProcs exch oget }
+ { pop CharProcs /.notdef oget }
+ ifelse
+ PDFfile fileposition exch
+ false resolvestream
+ % Stack: filepos stream
+ % Don't let setgcolor set the color inside the BuildGlyph
+ % procedure, because this causes an /undefined error.
+ q null /FillColor gput null /StrokeColor gput
+ Font /Resources get exch pdfopdict .pdfruncontext
+ Q
+ PDFfile exch setfileposition
+ end end
+ } bdef
+ FontName currentdict end definefont exch pop
+} bdef
+/.adjustcharwidth { % <wx> <wy> .adjustcharwidth <wx'> <wy'>
+ /Widths where {
+ begin
+ CharCode FirstChar ge CharCode LastChar le and {
+ exch pop Widths CharCode FirstChar sub get exch
+ } if end
+ } if
+} bdef
+
+% ---------------- TrueType fonts ---------------- %
+
+/TTfonts mark
+ /Arial /Helvetica
+ /Arial,Italic /Helvetica-Oblique
+ /Arial,Bold /Helvetica-Bold
+ /Arial,BoldItalic /Helvetica-BoldOblique
+ /CourierNew /Courier
+ /CourierNew,Bold /Courier-Bold
+ /TimesNewRoman /Times-Roman
+ /TimesNewRoman,Italic /Times-Italic
+ /TimesNewRoman,Bold /Times-Bold
+ /TimesNewRoman,BoldItalic /Times-BoldItalic
+ %
+ /ArialBlack,Italic /Arial-BlackItalic
+ /ArialNarrow,Bold /ArialNarrow-Bold
+ /ArialNarrow,BoldItalic /ArialNarrow-BoldItalic
+ /ArialNarrow,Italic /ArialNarrow-Italic
+ /BookAntiqua,Bold /BookAntiqua-Bold
+ /BookAntiqua,BoldItalic /BookAntiqua-BoldItalic
+ /BookAntiqua,Italic /BookAntiqua-Italic
+ /BookmanOldStyle,Bold /BookmanOldStyle-Bold
+ /BookmanOldStyle,BoldItalic /BookmanOldStyle-BoldItalic
+ /BookmanOldStyle,Italic /BookmanOldStyle-Italic
+ /CenturyGothic,Bold /CenturyGothic-Bold
+ /CenturyGothic,BoldItalic /CenturyGothic-BoldItalic
+ /CenturyGothic,Italic /CenturyGothic-Italic
+ /ComicSansMS,Bold /ComicSansMS-Bold
+ /CourierNew,Bold /CourierNewPS-BoldMT
+ /CourierNew,BoldItalic /CourierNewPS-BoldItalicMT
+ /CourierNew,Italic /CourierNewPS-ItalicMT
+ /FranklinGothicMedium,Italic /FranklinGothic-MediumItalic
+ /Garamond,Bold /Garamond-Bold
+ /Garamond,Italic /Garamond-Italic
+ /Georgia,Bold /Georgia-Bold
+ /Georgia,BoldItalic /Georgia-BoldItalic
+ /Georgia,Italic /Georgia-Italic
+ /Tahoma,Bold /Tahoma-Bold
+ /TrebuchetMS,Bold /TrebuchetMS-Bold
+ /TrebuchetMS,BoldItalic /Trebuchet-BoldItalic
+ /TrebuchetMS,Italic /TrebuchetMS-Italic
+ /Verdana,Bold /Verdana-Bold
+ /Verdana,BoldItalic /Verdana-BoldItalic
+ /Verdana,Italic /Verdana-Italic
+.dicttomark readonly def
+
+/buildTrueType { % <TrueType-font-resource> buildTrueType <font>
+ dup /BaseFont get
+ dup TTfonts exch .knownget {
+ exch pop
+ % Hack required by the PDF specification: if the
+ % font resource has Subtype = /TrueType but the actual
+ % (installed) font is not a TrueType font, ignore the
+ % Encoding in the font resource. However, all current
+ % versions of Acrobat Reader have the 14 base TrueType
+ % fonts built in, so this produces incorrect output for
+ % badly designed PDF files that specify these file names
+ % with /Subtype = /TrueType but no embedded definition.
+ % Compensate for this by removing the /Subtype key when
+ % looking up the font.
+ exch dup length dict copy dup /Subtype null put exch
+ } if
+ pdffindfont % findfont for PDF
+ % disable the auto-bold and auto-italic since it sometimes applies
+ % so an already bold or italic substitute font
+ %findpdffont % findfont and auto-bold and/or auto-italic font for PDF
+} bdef
+
+% Read an embedded TrueType font.
+/readtruetype { % <font-resource> <stream-dict> readtruetype <font>
+ % This is much simpler than readtype1, because we don't
+ % have to deal with the tripartite .PFB format.
+ 1 index exch
+ PDFfile fileposition 3 1 roll
+ true resolvestream readfontfilter
+ % Stack: filepos fontres stream
+ 1 index /Subtype get /CIDFontType2 eq {
+ .loadttcidfont
+ % Stack: filepos fontres cidfont
+ 1 index /CIDToGIDMap knownoget {
+ dup /Identity eq {
+ pop
+ } {
+ true resolvestream
+ % The following doesn't work for CIDToGIDMaps with more
+ % than 32K-1 entries. We'll fix it later if necessary.
+ % Stack: filepos fontres font mapstream
+ dup 2 index /CIDCount oget 2 mul string readstring pop exch closefile
+ exch dup length 5 add dict .copydict
+ dup /FID undef
+ dup /CIDMap 4 -1 roll put
+ dup /CIDFontName get exch /CIDFont defineresource
+ } ifelse
+ } if
+ } {
+ null 2 index getencoding .loadpdfttfont
+ } ifelse
+ exch pop
+ PDFfile 3 -1 roll setfileposition
+ % Ignore both the Encoding and the Widths.
+ exch pop
+} bdef
+
+% ---------------- Type 0 fonts ---------------- %
+
+% Predefine the known CMaps, but only create them on demand.
+/knownCMaps mark
+ /Identity-H { /Identity-H 0 makeIdentityCMap }
+ /Identity-V { /Identity-V 1 makeIdentityCMap }
+.dicttomark def
+
+/makeIdentityCMap { % <cmapname> <wmode> .makeIdentityCMap -
+ .currentglobal true .setglobal 3 1 roll
+ /CIDInit /ProcSet findresource begin
+ 12 dict begin
+ begincmap
+ /WMode exch def
+ /CMapName exch def
+ /CIDSystemInfo 3 dict dup begin
+ /Registry (Adobe) def
+ /Ordering (Identity) def
+ /Supplement 0 def
+ end def
+ %/CMapName (see above)
+ /CMapVersion 1 def
+ /CMapType 1 def
+ %WMode (see above)
+ % The PDF documentation says that these CMaps map CIDs
+ % "1 to 65,536". This is a misprint for 0 to 65,535.
+ 1 begincodespacerange
+ % <0001> <00ff> <0100> <ffff>
+ <0000> <ffff>
+ endcodespacerange
+ 1 begincidrange
+ % <0001> <00ff> 1 <0100> <ffff> 256
+ <0000> <ffff> 0
+ endcidrange
+ endcmap
+ CMapName currentdict /CMap defineresource
+ knownCMaps CMapName 2 index put
+ end % CMap
+ end % CIDInit ProcSet
+ exch .setglobal
+} bdef
+
+/buildType0 { % <Type0-font-resource> buildType0 <font>
+ dup /BaseFont get % FontName
+ 1 index /Encoding oget
+ dup type /nametype eq {
+ dup /CMap resourcestatus {
+ pop pop /CMap findresource
+ } {
+ knownCMaps 1 index .knownget
+ { exch pop exec } { /undefined signalerror } ifelse
+ } ifelse
+ } {
+ PDFfile fileposition exch
+ dup /CMapName get exch true resolvestream cvx exec
+ /CMap findresource
+ exch PDFfile exch setfileposition
+ } ifelse % CMap
+ [
+ 3 index /DescendantFonts oget { exec resourcefont } forall
+ ] % subfonts
+ composefont
+ % Stack: fontres font
+ 1 index /FontMatrix knownoget {
+ dup aload pop true {0 0 1 0 0 1} {3 -1 roll eq and} forall {
+ 1 index exch makefont exch /FontName get exch definefont
+ } {
+ pop
+ } ifelse
+ } if exch pop
+} bdef
+
+% ---------------- CIDFontType0/2 fonts ---------------- %
+
+% Insert metrics into a CIDFont, by saving the PDF W, W2, DW, and DW2
+% arrays and using a (currently very inefficient) CDevProc.
+% For detail, refer "PDF Reference" third edition, p. 337,
+% "5.6.3 CIDFonts" and table "Entries in a CIDFont dictionary".
+
+/.pdfDefaultDW 1000 def
+/.pdfDefaultDW2 [ 880 -1000 ] def
+
+/addCIDmetrics { % <CIDFont-resource> <CIDFont> addCIDmetrics <fontdict>
+ dup length 5 add dict .copydict
+ dup /FID undef
+ dup /UniqueID undef
+ dup /XUID undef
+ % Insert the widths into the font.
+
+ % Stack: pdfresource newfont
+
+ 1 index /DW .knownget {
+ 1 index /DW 3 -1 roll put
+ } {
+ dup /DW .pdfDefaultDW put
+ } ifelse
+
+
+ 1 index /W .knownget {
+ dup 2 index /W 3 -1 roll put
+ .pdfMakeInternalW 1 index /.internalW 3 -1 roll put
+ } if
+
+
+ 1 index /DW2 .knownget {
+ 1 index /DW2 3 -1 roll put
+ } {
+ dup /DW2 .pdfDefaultDW2 put
+ } ifelse
+
+
+ 1 index /W2 .knownget {
+ dup 2 index /W2 3 -1 roll put
+ .pdfMakeInternalW2 1 index /.internalW2 3 -1 roll put
+ } if
+
+
+ dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put
+ exch pop
+} bdef
+
+/.pdfMakeInternalMTXArray { % <mtx_array> <item_size> .pdfConvertInternalW <mtx_array'>
+
+ % convert /W or /W2 to internal expression
+ %
+ % mtx_array: original /W or /W2 array
+ % item_size: number of metrics values per CID
+ %
+ % for detail of the metrics list format in PDF,
+ % refer PDF Ref. p.317 "Glyph Metrics in CIDFonts".
+ %
+ % format of single entry in internal expression
+ %
+ % [
+ % [cid_begin cid_end]
+ % value_is_varied (bool)
+ % [ [values for cid_begin...]
+ % [values for cid_begin + 1]
+ % ... ]
+ % ]
+ %
+
+ 7 dict
+ begin
+ /itemSize exch def
+ /M exch def % original /W or /W2
+ /Msize M length def
+ /Mi { M i get } def % W[i]
+ /Mi1 { M i 1 add get } def % W[i + 1]
+ /putMTXEntry <<
+ /arraytype {
+ [
+ [Mi Mi Mi1 length add 1 sub]
+ true
+ [
+ 0 itemSize Mi1 length 1 sub {
+ [ exch 1 1 index itemSize add 1 sub { Mi1 exch get } for ]
+ } for
+ ]
+ ]
+ /i i 2 add def
+ }
+ /integertype {
+ [
+ [Mi Mi1]
+ false
+ [[ i 2 add 1 i 1 add itemSize add { M exch get } for ]]
+ ]
+ /i i 3 add def
+ }
+ >> def
+
+ /i 0 def
+
+ [ { putMTXEntry Mi1 type get exec i Msize ge { exit } if } loop ]
+ end
+} def
+
+/.pdfMakeInternalW { dup length 0 gt { 1 .pdfMakeInternalMTXArray } if } def
+/.pdfMakeInternalW2 { dup length 0 gt { 3 .pdfMakeInternalMTXArray } if } def
+
+/.pdfGetMTXByCID { % <internalMTXArray> <cid>
+ % .pdfGetMTXByCID
+ % { <MTXEntry> true | false }
+
+ % get values for given CID from internal format of /W or /W2
+
+ exch
+ {
+ {
+ dup 0 get {} forall % Stack: <cid> <entry> <cid_0> <cid_1>
+ 3 index lt { pop pop false exit } if
+ 2 index exch sub dup 0 lt { pop pop false exit } if
+ 1 index 1 get not { pop 0 } if
+ exch 2 get exch get true exit
+ } loop
+ { exit } if
+ } forall
+ dup type /arraytype eq { exch pop true } { pop false } ifelse
+} def
+
+
+% Apply the [D]W[2] metrics to a character before displaying.
+/CIDWProc { % <w0x> <w0y> <llx> <lly> <urx> <ury>
+ % <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc
+ % <w0x'> ... <vy'>
+
+ begin % push <font> to currentdict
+ % <w1x> <w1y> <vx> <vy> won't be used and replaced, discard now
+ 5 1 roll pop pop pop pop
+
+ {
+ currentdict /DW .knownget not { % no DW
+ .pdfDefaultDW exit % replace <w0x> by defaultDW
+ } if
+
+ currentdict /.internalW .knownget not { % no W
+ exit % use already-stacked DW
+ } if
+
+ dup length 0 eq { % W is null array
+ pop % discard unusable W
+ exit % use already-stacked DW
+ } if
+
+ % W is finite array, try to get W_cid
+ 2 index .pdfGetMTXByCID { % got W, discard DW
+ exch pop {} forall
+ exit
+ } if
+
+ exit
+ } loop
+
+ 1000 div % <w0x'> (normalized W)
+ 0 % <w0y'>
+
+ % Stack: <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <w0x'> <w0y'>
+ 9 -2 roll pop pop % discard <w0x> <w0y>
+ 7 2 roll % put <w0x'> <w0y'>
+
+ % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <cid>
+ 0 % <w1x'>
+ exch % put <w1x'>
+
+ % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <cid>
+ {
+ currentdict /DW2 .knownget not { % no DW2, use defaultDW2
+ .pdfDefaultDW2 exit
+ } if
+
+ currentdict /.internalW2 .knownget not { % has DW2, no W2
+ exit % use already-stacked DW2
+ } if
+
+ dup length 0 eq { % W2 is null array
+ pop % discard unusable W2
+ exit % use already-stacked DW2
+ } if
+
+ 2 index .pdfGetMTXByCID { % got W2_cid, discard DW2
+ exch pop
+ exit
+ } if
+
+ % could not get W2_cid
+ exit
+
+ } loop
+
+ exch pop % discard <cid>
+
+
+ % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> { [<vy'> <w1y'>] | [<w1y'> <vx'> <vy'>] }
+ dup length 2 eq { % this is DW2
+ {1000 div} forall exch
+ 4 index 7 index add 2 div % <vx'> = (<urx> + <llx>) / 2
+ exch
+ }{ % assume W2
+ {1000 div} forall
+ } ifelse
+ end % recover currentdict
+
+} def
+
+
+
+%----------------------------------------------------------------
+
+% <string> <match> tailmatch ==> <pre> true
+% ==> <string> false
+/tailmatch {
+ 2 copy length 1 index length .min
+ dup 2 index length exch sub exch getinterval
+ 1 index eq {
+ length 1 index length exch sub
+ 0 exch getinterval true
+ } {
+ pop false
+ } ifelse
+} bind def
+
+/makeboldcidfont {
+ 16 dict begin
+ /strokewidth exch def
+ /basecidfont exch def
+ /FontMatrix [ 1 0 0 1 0 0 ] def
+
+ /CIDFontName /.boldfont def
+ /CIDFontType 1 def
+
+ /basefont-H /.basefont-H /Identity-H [ basecidfont ] composefont def
+ /basefont-V /.basefont-V /Identity-V [ basecidfont ] composefont def
+
+ /CIDSystemInfo dup basecidfont exch get def
+ /FontBBox [ basecidfont /FontBBox get cvx exec
+ 4 2 roll basecidfont /FontMatrix get transform
+ 4 2 roll basecidfont /FontMatrix get transform
+ ] def
+
+ /tmpstr 2 string def
+ /BuildGlyph {
+ gsave
+ exch begin
+ dup 256 idiv tmpstr exch 0 exch put
+ 256 mod tmpstr exch 1 exch put
+ rootfont /WMode known { rootfont /WMode get 1 eq } { false } ifelse
+ { basefont-V } { basefont-H } ifelse setfont
+ strokewidth setlinewidth
+ 1 setlinejoin
+ newpath
+ 0 0 moveto tmpstr false charpath stroke
+ 0 0 moveto tmpstr show
+ currentpoint setcharwidth
+ end
+ grestore
+ } bind def
+
+ currentdict
+ end
+ dup /CIDFontName get exch /CIDFont defineresource
+} bind def
+
+% <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font>
+% CIDFont-resource is not modified.
+/findCIDFont {
+ {
+ dup /CIDFont resourcestatus {
+ pop pop /CIDFont findresource
+ exit
+ } if
+
+ dup dup length string cvs
+ (,Bold) tailmatch {
+ exch pop
+ cvn findCIDFont 0.03 makeboldcidfont
+ exit
+ } if
+ (,Italic) tailmatch {
+ exch pop
+ cvn findCIDFont
+ [ 1 0 0.3 1 0 0 ] makefont
+ exit
+ } if
+ (,BoldItalic) tailmatch {
+ exch pop
+ cvn findCIDFont 0.03 makeboldcidfont
+ [ 1 0 0.3 1 0 0 ] makefont
+ exit
+ } if
+ pop
+
+ 1 index /CIDSystemInfo get begin Registry (-) Ordering end
+ concatstrings concatstrings
+ cvn
+ QUIET not {
+ (Substituting ) print dup ==only
+ ( for ) print 1 index ==only (.\n) print
+ } if
+ exch pop
+ /CIDFont findresource
+ exit
+ } loop
+} bdef
+
+/buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
+ dup /BaseFont get exch 1 index findCIDFont
+ addCIDmetrics /CIDFont defineresource
+} bdef
+
+/buildCIDType2 { % <CIDFontType2-font-resource> buildCIDType2 <font>
+ dup /BaseFont get exch 1 index findCIDFont
+ addCIDmetrics /CIDFont defineresource
+} bdef
+
+% ---------------- Other embedded fonts ---------------- %
+
+/fontloadprocs mark
+ /Type1C /readType1C cvx
+ /CIDFontType0C /readCIDFontType0C cvx
+.dicttomark readonly def
+
+% Read an embedded compressed font.
+/readType1C { % <font-resource> <stream-dict> readType1C <font>
+ 1 index exch
+ PDFfile fileposition 3 1 roll
+ dup true resolvestream dup readfontfilter
+ % Stack: pos resource streamdict stream filter
+ 3 index /FontDescriptor oget /FontName oget
+ 1 index FRD
+ closefile closefile pop
+ PDFfile 3 -1 roll setfileposition
+ /FontDescriptor oget /FontName oget findfont
+ adjustfont
+} bdef
+
+% Read an embedded CFF CIDFont.
+/readCIDFontType0C { % <font-resource> <stream-dict> readCIDFontType0C <font>
+ PDFfile fileposition 3 1 roll
+ dup true resolvestream dup readfontfilter
+ % Stack: pos resource streamdict stream filter
+ 3 index /FontDescriptor oget /FontName oget
+ 1 index FRD
+ closefile closefile pop
+ PDFfile 3 -1 roll setfileposition
+ % Some broken Adobe software produces PDF files in which
+ % the FontName of the CFF font and the FontName in the
+ % FontDescriptor don't match the BaseFont in the font.
+ % Use the FontName, rather than the BaseFont, here.
+ dup /FontDescriptor oget /FontName oget /CIDFont findresource
+ addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource
+} bdef
+
+% ---------------- Font lookup ---------------- %
+
+/fonttypeprocs mark % <font-resource> -proc- <font>
+ /Type0 /buildType0 cvx
+ /Type1 /buildType1 cvx
+ /MMType1 1 index
+ /Type3 /buildType3 cvx
+ /TrueType /buildTrueType cvx
+ /CIDFontType0 /buildCIDType0 cvx
+ /CIDFontType2 /buildCIDType2 cvx
+.dicttomark readonly def
+
+/resourcefont % <font-resource> resourcefont <font>
+ { dup /PSFont .knownget
+ { /FID .knownget { type /fonttype eq } { false } ifelse }
+ { false }
+ ifelse
+ { /PSFont get
+ }
+ { dup dup /FontDescriptor knownoget
+ { % Stack: font-res font-res font-desc
+ dup /FontFile knownoget
+ { exch pop readtype1 true }
+ { dup /FontFile2 knownoget
+ { exch pop readtruetype true }
+ { /FontFile3 knownoget
+ { dup /Subtype get fontloadprocs exch get exec true }
+ { false }
+ ifelse
+ }
+ ifelse
+ }
+ ifelse
+ }
+ { false }
+ ifelse
+ % Stack: font-res font-res false
+ % -or-: font-res font true
+ not
+ { dup /Subtype get fonttypeprocs exch get exec }
+ if
+ 2 copy /PSFont exch put
+ exch pop
+ }
+ ifelse
+ } bdef
+
+drawopdict begin
+ /d0 {
+ .adjustcharwidth setcharwidth
+ } bdef
+ /d1 {
+ 6 -2 roll .adjustcharwidth 6 2 roll setcachedevice
+ } bdef
+ /Tf {
+ 1 index Page /Font rget not { 1 index /invalidfont signalerror } if
+ resourcefont exch Tf pop
+ } bdef
+end
+
+end % pdfdict
+end % GS_PDF_ProcSet
+.setglobal