home *** CD-ROM | disk | FTP | other *** search
- % Copyright (C) 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
- %
- % This file is part of Aladdin Ghostscript.
- %
- % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- % or distributor accepts any responsibility for the consequences of using it,
- % or for whether it serves any particular purpose or works at all, unless he
- % or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- % License (the "License") for full details.
- %
- % Every copy of Aladdin Ghostscript must include a copy of the License,
- % normally in a plain ASCII text file named PUBLIC. The License grants you
- % the right to copy, modify and redistribute Aladdin Ghostscript, but only
- % under certain conditions described in the License. Among other things, the
- % License requires that the copyright notice and this notice be preserved on
- % all copies.
-
- % 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.
- /updateencoding % <encoding> <differences> updateencoding <enc'>
- { exch dup length array copy
- exch dup 0 get exch dup length 1 sub
- 1 exch getinterval
- { 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
- { exch pop findencoding
- }
- { dup /BaseEncoding knownoget
- { findencoding 3 -1 roll pop exch
- }
- if
- /Differences knownoget { updateencoding } if
- }
- ifelse
- }
- if
- } bdef
-
- % Adjust a font according to the Encoding and Widths in the font resource.
- /adjustfont % <font-resource> <font> adjustfont
- % <font'> <changed>
- { getfontencoding getfontmetrics 4 -1 roll pop .updatefont
- { dup /FontName 2 copy get genfontname dup 5 1 roll put definefont }
- if
- } bind def
-
- % Get the (possibly modified) encoding of a font.
- /getfontencoding % <font-resource> <font> getfontencoding
- % <font-resource> <font> <encoding>
- { dup /Encoding get 2 index getencoding
- } bdef
-
- % Get the metrics of a font, if specified.
- /getfontmetrics % <font-resource> <font> <encoding> getfontmetrics
- % <font-resource> <font> <encoding> <Metrics|null>
- { 2 index /Widths known
- { 2 dict begin
- /Encoding exch def
- /Metrics Encoding length dict def
- exch
- % 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
- 4 index /Widths oget 2 index 4 index sub get
- % Stack: font font-res mscale first-char index charname width
- 4 index mul
- % 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.
- % Because of this, we can't deal with Width vectors that
- % specify different widths for the same character name
- % appearing multiple times in the Encoding.
- Metrics 2 index .knownget not { 0 } if 0 ne
- { pop pop }
- { Metrics 3 1 roll put }
- ifelse pop
- }
- for pop
- % Now fill in the MissingWidth for any encoded characters
- % that aren't in Metrics already.
- % Stack: font font-res mscale
- Metrics 2 index /FontDescriptor oget
- /MissingWidth knownoget { 2 index mul } { 0 } ifelse exch
- Encoding
- { % Stack: font font-res mscale missing-width metrics charname
- 2 copy known not { 2 copy 4 index put } if pop
- }
- forall pop pop pop
- exch Encoding Metrics end
- }
- { null
- }
- ifelse
- } bdef
-
- % ---------------- Descriptors ---------------- %
-
- % Partial descriptors for the 14 built-in fonts.
- /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 ---------------- %
-
- % 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.
- /pdffindfont % <font-resource> <fontname> pdffindfont <font>
- { findfont adjustfont
- } 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
- % leftstr - string containing (non-negative) integer
- % sectionstr - string containing a character 0 .. 2
- % stream - (stream) dictionary
- % proc - procedure of the form {-dict- type1read}
- % 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!
-
- % Read an embedded Type 1 font.
- /readfontfilter % <proc> readfontfilter <filter>
- { % We make this a separate procedure so that we can
- % redefine it when we're writing PostScript.
- 0 () /SubFileDecode filter
- } bdef
- /readtype1dict 5 dict dup begin
- /definefont {
- dup wcheck not { dup length dict copy } if
- exch pop savedFontName exch
- //systemdict /definefont get exec
- } bdef
- /eexec {
- 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.
- PDFfile fileposition 3 1 roll
- 7 dict begin
- /leftstr ( ) 10 string copy def
- dup /Length1 oget leftstr cvs pop
- /sectionstr <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
- 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
- % Rebind definefont so we can substitute the FontName
- % from the descriptor.
- //readtype1dict dup length 2 add dict copy begin
- 1 index /FontDescriptor oget /FontName oget /savedFontName exch 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
- /FontDescriptor oget /FontName oget findfont
- } bdef
-
- % Execute the appropriate reading procedure.
- /type1read % <dict> type1read <string>
- { begin leftstr cvi
- { 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 next block of the initial text portion.
- /type1read1 % <left> type1read1 <string> <left'>
- { DEBUG { (read1 ) print } if
- dup 0 eq
- { pop sectionstr 0 1 put
- stream /Length2 oget type1read2
- }
- { buffer type1readdata
- }
- ifelse
- } 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 2 put
- stream /Length3 oget
- dup 0 eq
- { DEBUG { (trailer ) print } if
- type1trailer exch
- }
- { type1read3
- }
- ifelse
- }
- { buffer2 type1readdata exch
- buffer /ASCIIHexEncode filter dup 3 -1 roll writestring closefile
- buffer (>) search pop exch pop exch pop 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
- /FontBBox 1 index /FontBBox get cvx def
- /FontMatrix 1 index /FontMatrix oget def
- /CharProcs 1 index /CharProcs oget def
- /FontName 1 index /Name get genfontname def
- /Encoding .notdefEncoding 2 index getencoding def
- /BuildGlyph
- { exch /CharProcs get exch oget
- PDFfile fileposition exch
- false resolvestream
- % Don't let setgcolor set the color inside the BuildGlyph
- % procedure, because this causes an /undefined error.
- q_ null /FillColor gput null /StrokeColor gput
- pdfopdict .pdfrun
- Q_
- PDFfile exch setfileposition
- } bdef
- FontName currentdict end definefont exch pop
- } bdef
-
- % ---------------- TrueType fonts ---------------- %
-
- /TTfonts mark
- /Arial /Helvetica
- /Arial,Italic /Helvetica-Oblique
- /Arial,Bold /Helvetica-Bold
- /Arial,BoldItalic /Helvetica-BoldOblique
- /TimesNewRoman /Times-Roman
- /TimesNewRoman,Italic /Times-Italic
- /TimesNewRoman,Bold /Times-Bold
- /TimesNewRoman,BoldItalic /Times-BoldItalic
- .dicttomark readonly def
-
- /buildTrueType % <TrueType-font-resource> buildTrueType <font>
- { dup /BaseFont get
- dup TTfonts exch .knownget { exch pop } if pdffindfont
- } 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.
- PDFfile fileposition 3 1 roll
- true resolvestream readfontfilter .loadttfont
- dup /FontName get exch definefont exch pop
- PDFfile 3 -1 roll setfileposition
- } bdef
-
- % ---------------- Type 0 fonts ---------------- %
- %**************** NOT ACTUALLY SUPPORTED YET
-
- /buildType0 % <Type0-font-resource> buildType0 <font>
- { 10 dict begin
- /FontType 0 def
- /FontMatrix 1 index /FontMatrix knownoget not { matrix } if def
- /FontName 1 index /BaseFont get def
- /FMapType 9 def
- /Encoding [ 0 1 4 index /DescendantFonts oget length 1 sub { } for ] def
- /FDepVector [ 2 index /DescendantFonts oget { exec } forall ] def
- /CMap 1 index /Encoding oget
- dup type /nametype eq
- { dup Page /CMap rget
- { exch pop resolvestream } { /undefined signalerror } ifelse
- }
- { resolvestream
- }
- ifelse
- % FontName currentdict end definefont exch pop
- end pop /Times-Roman findfont
- } bdef
-
- % ---------------- Other embedded fonts ---------------- %
-
- /fontloadprocs mark
- /Type1C /readType1C cvx
- .dicttomark readonly def
-
- % Read an embedded compressed font.
- /readType1C % <font-resource> <stream-dict> readType1C <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
- /FontDescriptor oget /FontName oget findfont
- } bdef
-
- % ---------------- Font lookup ---------------- %
-
- /fonttypeprocs mark % <font-resource> -proc- <font>
- /Type0 /buildType0 cvx
- /Type1 /buildType1 cvx
- /MMType1 1 index
- /Type3 /buildType3 cvx
- /TrueType /buildTrueType 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 1 index 3 1 roll readtype1 adjustfont true }
- { dup /FontFile2 knownoget
- { exch pop 1 index 3 1 roll readtruetype adjustfont true }
- { /FontFile3 knownoget
- { 1 index exch dup /Subtype get fontloadprocs exch get exec adjustfont 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 /setcharwidth load def
- /d1 /setcachedevice load def
- /Tf
- { exch Page /Resources oget /Font oget exch oget resourcefont
- exch Tf
- } bdef
- end
-
- end % pdfdict
- end % GS_PDF_ProcSet
- .setglobal
-