henesyinit from p9fd787fda5 years agoHistory
694 lines · 21.2 KB · Text
RawDownload
%    Copyright (C) 1994, 2000 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. % $Id: pdf_font.ps,v 1.2 2000/03/10 03:57:50 lpd Exp $% pdf_font.ps% PDF font operations. /.setlanguagelevel where { pop 2 .setlanguagelevel } if.currentglobal true .setglobal/pdfdict where { pop } { /pdfdict 100 dict def } ifelseGS_PDF_ProcSet beginpdfdict 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       { exch pop findencoding       }       { 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 % 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      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	 } {		% Work around a bug in pdfTeX, which can generate Encoding		% vectors containing nulls.	   1 index null ne {	     Metrics 3 1 roll put	   } {	     pop pop	   } ifelse	 }	 ifelse 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 % ---------------- 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 ---------------- % % 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>		% 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      1 index .fontnameproperties or      .substitutefontname		% 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 % ---------------- 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!% 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 on the top of the stack.    count 0 gt { /topFontDict 1 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  } bdefend 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   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		% 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    { 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    /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      Encoding exch get CharProcs exch oget      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.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.  1 index exch  PDFfile fileposition 3 1 roll  true resolvestream readfontfilter		% Stack: filepos fontres stream  1 index /Subtype get /CIDFontType2 eq {    .loadttcidfont  } {    .loadttfont  } 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

Lines 1–500 of 694.