⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gs_cidfn.ps

📁 GhostScript的源代码
💻 PS
字号:
%    Copyright (C) 1995, 1996, 1997, 1998 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: gs_cidfn.ps $
% ProcSet for implementing CIDFont and CIDMap resources.
% When this is run, systemdict is still writable.

% ---------------- Defining CIDFont resources ---------------- %

% Define a CIDFont resource.  This is the defineresource implementation for
% the CIDFont resource category.

/.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse
.cidfonttypes begin

% The key in .cidfonttypes is the CIDFontType value;
% the value is a procedure that takes a font name and the CIDFont dictionary
% and replaces the latter with a real font.

0 {	% CIDFontType 0 = FontType 9
  currentglobal 3 1 roll dup gcheck setglobal
  dup /FontType 9 put
  dup /FontMatrix known not {
    dup /FontMatrix [0.001 0 0 0.001 0 0] put
    dup /FDArray get {
      /FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop
    } forall
  } if
  dup /FDArray get mark exch {
		% Add pro forma entries
    currentglobal exch dup gcheck setglobal
    dup /FontType 1 put
    dup /CharStrings mark /.notdef () .dicttomark put
    dup /Encoding [] put
		% Create a dummy Subrs array now, if there isn't one here
		% already (which can only happen if we're giving another
		% name to an existing font).
    dup /Private get dup /Subrs known not {
      dup /SubrCount .knownget {
	array 1 index /Subrs 3 -1 roll put
      } if readonly
    } if pop
    exch setglobal
    dup /FontName .knownget not { () } if exch .buildfont1 exch pop
  } forall ] 1 index /FDepVector 3 -1 roll put
  3 -1 roll setglobal
  1 index exch .buildfont9 exch pop
} bind def

1 {	% CIDFontType 1 = FontType 10
  dup /FontType 10 put
  1 index exch .buildfont10 exch pop
} bind def

2 {	% CIDFontType 2 = FontType 11
  dup /FontType 11 put
  1 index exch .buildfont11 exch pop
} bind def

end		% .cidfonttypes

% ---------------- Reading CIDFontType 0 files ---------------- %

30 dict begin

% We add the following entries to the CIDFont dictionary, in addition to
% the ones documented by Adobe:
%	ReadString - procedure for reading a string from the binary data
%	SubrCache - dictionary for caching Subr arrays
% For CIDFonts where we read the data from disk incrementally:
%	DataOffset - starting position of data in file
%	(if data are in hex) OffsetMap - map from logical data positions to
%	  physical positions in file

/StartData		% <(Binary)|(Hex)> <datalength> StartData -
			%   (currentdict is CID font dict)
{		% If we're loading a resource file, we can just save a
		% pointer to the binary data and load it incrementally.
		% Check for this by opening the resource file,
		% positioning it to currentfile's position plus the
		% data length, and checking for %%EndData.
   mark
    { currentfile fileposition
      CIDFontName 100 string ResourceFileName (r) file
       mark
	{		% Stack: (Binary)|(Hex) length -mark- pos resfile
			%   -mark-
	  5 index (Hex) eq
	   { 1 index 3 index setfileposition
	     1 index 5 index .skiphex
			%**************** SKIP > AND WHITESPACE SOMEHOW
	   }
	   { 1 index 3 index 6 index add setfileposition
	   }
	  ifelse
	  1 index 9 string readstring pop (%%EndData) ne { stop } if
	}
       .internalstopped { cleartomark closefile stop } if
       pop		% pop the mark
    }
   .internalstopped
   {		% File is not positionable, load the data now.
     cleartomark exch (Hex) eq
      { { currentfile exch readhexstring pop } }
      { { currentfile exch readstring pop } }
     ifelse /ReadString exch def
     dup 65535 le
      { string ReadString
      }
      { mark exch
	 { dup 0 eq { pop exit } if
	   dup 65535 min dup string ReadString
	   3 1 roll sub
	 }
	loop ]
      }
     ifelse
     /GlyphData exch def
		% If we were reading hex data, skip past the >.
     /ReadString load 2 get { readhexstring } 0 get eq {
       currentfile 0 (>) /SubFileDecode filter dup flushfile closefile
     } if
     /.vmreadstring cvx
   }
   {		% File is positionable, just save a pointer.
		% Stack: (Binary)|(Hex) length -mark- pos file
     4 1 roll
     /DataOffset exch def
     pop /GlyphData exch def
     exch (Hex) eq
      {		% Hex data, build the offset map.
	.buildoffsetmap
	/.hexreadstring
      }
      {		% Binary data, just skip over it.
	currentfile DataOffset GlyphData add setfileposition
	/.binaryreadstring
      }
     ifelse cvx
     2 packedarray cvx
   }
  ifelse /ReadString exch def
  /SubrCache 10 dict def
  CIDFontName currentdict /CIDFont defineresource pop
  end			% CID font dict
  end			% resource category dict
} bind def

% Skip a given distance in an ASCIIHex encoded file.  We use this at
% rendering time as well.
/.skiphex		% <file> <count> .skiphex -
{ exch /ASCIIHexDecode filter dup 3 -1 roll () /SubFileDecode filter
  dup flushfile closefile closefile
} bind def

% Build the map from logical offsets to physical offsets in ASCIIHex
% encoded data.
/.buildoffsetmap
{ /OffsetMap GlyphData 256 idiv 8000 min array def
  2 dict begin
     /block GlyphData OffsetMap length idiv def
     0 1 OffsetMap length 1 sub
      { OffsetMap exch currentfile fileposition put
	currentfile block .skiphex
      }
     for
     GlyphData block mod dup 0 eq
      { pop }
      { currentfile exch .skiphex }
     ifelse
  end			% scratch dict
} bind def

currentdict end

% ---------------- Rendering ---------------- %

% ------ Generic ------ %

% Read a string at a given offset in a "file" (binary file, ASCII hex file,
% or GlyphData in RAM).
/.binaryreadstring	% <pos> <string> <file> .binaryreadstring <string>
 { dup 4 -1 roll DataOffset add setfileposition exch readstring pop
 } bind def
/.hexreadstring		% <pos> <string> <file> .hexreadstring <string>
{		% Use the OffsetMap to get to the block of hex data,
		% then skip to the correct position by reading.
  GlyphData OffsetMap length idiv
		% Stack: pos string file blocklen
  3 index 1 index idiv OffsetMap exch get
  2 index exch setfileposition
		% Skip the next (pos % blocklen) hex bytes.
  4 -1 roll exch mod 1 index exch .skiphex
		% Stack: string file
  exch readhexstring pop  
} bind def
/.vmreadstring		% <pos> <string> .vmreadstring <vmstring>
{ GlyphData .stringsreadstring
} bind def
/.stringsreadstring	% <pos> <string> <strings> .stringsreadstring
			%   <vmstring>
{ dup type /stringtype eq
   { 3 1 roll length getinterval
   }
   {  {		% Stack: pos string glyphdata
	dup 0 get length dup 4 index gt { exit } if
	4 -1 roll exch sub 3 1 roll
	dup length 1 sub 1 exch getinterval
      }
     loop
		% Stack: pos string glyphdata glyphdata[0]length
		% We know no request can span more than 2 strings.
     3 index 3 index length add 1 index le
      {		% Request fits in a single string: just return a substring.
	pop 0 get 3 1 roll length getinterval
      }
      {		% Request spans 2 strings.  Copy the first part.
	1 index 0 get 4 index 3 -1 roll 1 index sub getinterval
	2 index copy
		% Copy the second part.
		% Stack: pos str glyphdata str1
	length exch 1 get 0 3 index length
	3 index sub getinterval 2 index 3 1 roll putinterval
	exch pop
      }
     ifelse
   }
  ifelse
} bind def

% Interpret a byte string as a (big-endian) integer.
/.cvbsi			% <bytes> .cvbsi <int>
{ 0 exch { exch 8 bitshift add } forall
} bind def

% Read an integer from binary data.
/.readint		% <pos> <nbytes> .readint <int>
{ string ReadString .cvbsi
} bind def

% Read the glyph data for a given CID.  The CIDFont is currentdict.
% Note that the data must be read into the same VM as the CharStrings
% dictionary of the selected subfont.
/.readglyphdata {	% <cid> .readglyphdata <subfont> <string|null>
  currentdict /GlyphDirectory .knownget {
    dup type /arraytype eq {
      1 index exch get
    } {
      1 index exch .knownget not { null } if
    } ifelse
    dup null eq {
      FDepVector 0 get exch
    } {
      FDBytes 0 eq {
	FDepVector 0 get exch
      } {
			% Note: FDBytes > 1 is not supported.
	dup 0 get FDepVector exch get
	exch dup length 1 sub 1 exch getinterval
      }	ifelse
    } ifelse
  } {
    FDBytes GDBytes add mul CIDMapOffset add
    dup FDBytes .readint exch
    FDBytes add dup GDBytes .readint
    exch GDBytes add FDBytes add GDBytes .readint
			% Stack: fd pos nextpos
    1 index sub dup 0 eq {
      pop pop pop FDepVector 0 get null
    } {
			% Stack: fd pos len
      FDepVector 4 -1 roll get
      dup /CharStrings get gcheck .currentglobal exch .setglobal
			% Stack: pos len subfont global
      4 2 roll string ReadString exch .setglobal
    } ifelse  
  } ifelse
} bind def

% ------ CIDFontType 0 ------ %

% Read some Subrs for the current Type 1 subfont.
% The subfont's Private dict is currentdict; the CIDFont itself is the
% next dictionary on the stack.
/.readsubrs {		% <Subrs> <start> .readsubrs <Subrs>
  1 SubrCount 1 sub {
    dup SDBytes mul SubrMapOffset add
    dup SDBytes .readint exch SDBytes add SDBytes .readint
    1 index sub string ReadString 2 index 3 1 roll put
  } for
} bind def

% Ensure that all the Subrs for the current Type 1 subfont are loaded.
% The subfont's Private dict is currentdict; the CIDFont itself is the
% next dictionary on the stack.
/.loadsubrs {
  currentdict /SubrMapOffset .knownget {
    Subrs 0 get null ne {
      pop		% We've already loaded the Subrs.
    } {
      currentglobal exch currentdict gcheck setglobal
      SubrCache 1 index .knownget {
			% We've already loaded some Subrs at this offset.
			% Make sure we've got as many as we need.
	dup length SubrCount lt {
			% We need to load more.
	  SubrCount array exch 1 index copy length .readsubrs
	  SubrCache 3 -1 roll 2 index put
	} if
      } {
			% We haven't loaded any Subrs at this offset yet.
	SubrCount array 0 .readsubrs
	SubrCache 3 -1 roll 2 index put
      } ifelse
      Subrs copy pop setglobal
    } ifelse
  } if
} bind def

% BuildGlyph procedure for CIDFontType 0.
% ****** WHY NOT USE .type1execchar FOR THIS? ******
% The name %Type9BuildGlyph is known to the interpreter.
/.cid0buildstring 10 string def
(%Type9BuildGlyph) cvn {	% <cidfont> <cid> %Type9BuildGlyph -
  .currentglobal 3 1 roll 1 index gcheck .setglobal
  1 index begin
  dup .readglyphdata dup null eq
   { %**** HANDLE NOTDEF ****
   }
  if
			% Stack: cidfont cid subfont charstring
dup null eq { pop pop pop pop } {	%**** WRONG ****
  4 -1 roll pop
  exch dup /Private get begin .loadsubrs end
  3 -1 roll //.cid0buildstring cvs cvn 3 1 roll
  dup /CharStrings get 3 index 4 -1 roll put
  setfont
  1000 0 setcharwidth	%**** WRONG ****
  0 0 moveto glyphshow
} ifelse	%**** WRONG ****
  end
  .setglobal
} bind def

% ------ CIDFontType 2 ------ %

% BuildGlyph procedure for CIDFontType 2.
% ****** ADD THE OUTLINE STRING AS AN ARGUMENT TO .type42execchar. ******
% The name %Type11BuildGlyph is known to the interpreter.
(%Type11BuildGlyph) cvn {	% <cidfont> <cid> %Type11BuildGlyph -
  .currentglobal 3 1 roll 1 index gcheck .setglobal
  1 index begin
		% We must be prepared for out-of-range CIDs.
  dup GDBytes mul GDBytes string CIDMap
  mark 4 1 roll { .stringsreadstring } .internalstopped {
		%**** 0 IS WRONG
    cleartomark 0 GDBytes string CIDMap .stringsreadstring
  } {
    exch pop
  } ifelse .cvbsi
			% Stack: cidfont cid glyphindex
%**************** GlyphDirectory is not supported yet.
(
  currentdict /GlyphDirectory .knownget
) pop false
   { dup type /arraytype eq
      { 1 index exch get }
      { 1 index exch .knownget not { null } if }
     ifelse
     dup null eq
      { %**** HANDLE NOTDEF
      }
     if
     1 index exch .type42execchar
   }
   { 1 index exch .type42execchar
   }
  ifelse
  end
  .setglobal
} bind def

% ---------------- Define resources ---------------- %

languagelevel exch 2 .setlanguagelevel

% Define the CIDInit ProcSet resource.
% The ProcSet dictionary is still on the stack.

/CMap /Generic /Category findresource dup length dict .copydict
/Category defineresource pop
	% We might have loaded CMap support already.
/CIDInit /ProcSet 2 copy resourcestatus {
  pop pop findresource dup length 4 index length add dict .copydict
  4 -1 roll exch .copydict
} {
  3 -1 roll
} ifelse exch defineresource pop

% Define the CIDFont resource category.
% We break out .buildcidfont because it appears that at least for
% Type 32 (CIDFontType 4) fonts, the font can be registered in the Font
% category with only a CIDFontType and no FontType.
/.buildcidfont {		% <name> <fontdict> .buildcidfont
				%   <name> <cidfont>
  dup /CIDFontType get //.cidfonttypes exch get exec
} odef

/CIDFont /Generic /Category findresource dup length dict .copydict
dup /InstanceType /dicttype put
dup /DefineResource {
  .buildcidfont
  /Generic /Category findresource /DefineResource get exec
} put
/Category defineresource pop

% Add the new FontType resources.

9 1 11 { dup /FontType defineresource pop } for

% Add the new FMapType resource.

9 dup /FMapType defineresource pop

% Define the CIDMap resource category.
% These aren't documented, but it's clear what they are for:
% to give names to CIDMaps for CIDFontType 2 fonts.

/CIDMap /Generic /Category findresource dup length dict .copydict
dup /.CheckResource {
	% Allow either a string or an array of strings.
  dup type dup /stringtype eq
   { pop true
   }
   { dup /arraytype eq exch /packedarraytype eq or
      { true exch { type /stringtype ne { pop false exit } if } forall
      }
      { false
      }
     ifelse
   }
  ifelse
} bind put
/Category defineresource pop

.setlanguagelevel

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -