summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps')
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps447
1 files changed, 447 insertions, 0 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps
new file mode 100644
index 00000000000..d2a767f7625
--- /dev/null
+++ b/Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps
@@ -0,0 +1,447 @@
+% Copyright (C) 2001-2012 Artifex Software, Inc.
+% All Rights Reserved.
+%
+% This software is provided AS-IS with no warranty, either express or
+% implied.
+%
+% This software is distributed under license and may not be copied,
+% modified or distributed except as expressly authorized under the terms
+% of the license contained in the file LICENSE in this distribution.
+%
+% Refer to licensing information at http://www.artifex.com or contact
+% Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
+% CA 94903, U.S.A., +1(415)492-9861, for further information.
+%
+
+% Extending Font resource category with CIDFont-CMap fonts.
+
+languagelevel 2 .setlanguagelevel currentglobal //true setglobal
+
+% In the comments below, 'CSI' is an abbreviation/acronym for CIDSystemInfo.
+% We pre-scan resource files to retrieve the CSI from them.
+% First we define a hidden procset .prs_dict containing
+% necessary variables and procedures.
+% Then we redefine the old /Font category using this procset.
+
+% We maintain internal caches for the CSI values retrieved from
+% resource files. This supposes that document doesn't uninstall
+% resource files. To disable caching, set enable_cache to false.
+
+% We assume that names starting with '.prs' do not appear in resource files.
+% If this causes any problem, this prefix should be systematically changed
+% in this file. ('prs' is an abbreviation for 'prescan'.)
+
+25 dict begin
+
+% Define local variables :
+
+/.prs_dict currentdict def % self-reference (constant)
+/.prs_empty 0 dict readonly def
+/path_buffer 8192 string def
+/name_buffer 1024 string def
+/minus (-) 0 get def % character code constant for '-'
+/period (.) 0 get def % character code constant for '.'
+/CMap 10 dict def % CSI cache for CMaps
+/CIDFont 10 dict def % CSI cache for CIDFonts
+/enable_cache //true def % set false to disable cache
+
+% The folloving variables are just placeholders for ones to be set
+% dynamically :
+/.prsFile 0 def % file to prescan
+/.prsResult 0 def % result of prescan
+/.prsDictCount 0 def % save the dictionary stack depth
+
+% Define a dummy CIDInit procset to use while pre-scanning :
+
+/DummyCIDInit 15 dict
+begin
+
+ /begincmap {} def
+ /usecmap {pop} bind def
+
+ {stop} bind
+ [ /begincodespacerange /endcodespacerange /beginnotdefchar /endnotdefchar
+ /beginnotdefrange /endnotdefrange /begincidchar /endcidchar /begincidrange
+ /endcidrange /endcmap /usefont /StartData
+ ] {
+ 1 index def
+ } bind forall
+ pop
+
+currentdict end def
+
+% Define a local 'findresource' for pre-scanning :
+% (it returns the dummy CIDInit instead of the regular CIDInit ProcSet)
+
+/findresource { % <InstName> <CatName> findresource <inst>
+ 2 copy /ProcSet eq exch % /InstName /CatName bool /InstName
+ /CIDInit eq and {
+ pop pop //DummyCIDInit
+ } {
+ //findresource exec
+ } ifelse
+} bind def
+
+% Define procedures for pre-scanning :
+
+/StopIfCSIDefined { % - StopIfCSIDefined -
+
+ % Check if the dictionary stack contains a dictionary containing /CIDSystemInfo.
+ % The search is limited to the top .prsDictCount dictionaries in the stack.
+ % If so, retrieve the CSI, and execute stop to terminate the pre-scanning of the file.
+ % Otherwise, do nothing, so the pre-scanning continues.
+
+ countdictstack //.prs_dict /.prsDictCount get sub dup {
+ currentdict /CIDSystemInfo .knownget {
+ //.prs_dict exch /.prsResult exch put
+ stop
+ } if
+ currentdict exch end
+ } repeat {
+ begin
+ } repeat
+} bind def
+
+/PrescanFile { % - PrescanFile -
+ { //.prs_dict /.prsFile get token {
+ dup type % token type
+ dup /nametype eq exch /operatortype eq or {
+ dup xcheck {
+ exec
+ //StopIfCSIDefined exec
+ } if
+ } if
+ } {
+ stop
+ } ifelse
+ } loop
+} bind odef
+
+/GetCIDSystemInfoFromFile { % <file> GetCIDSystemInfoFromFile <CSI>
+
+ % This procedure reads resource files with 'token',
+ % executing the tokens untill /CIDSystemInfo appears to be defined.
+ % Normally the resource file creates a new dictionary on
+ % dictionary stack and defines /CIDSystemInfo in it.
+ %
+ % Returns an empty dictionary if no CIDSystemInfo is found.
+
+ RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile beg) = } if
+ //.prs_dict begin
+ /.prsFile exch def
+ /.prsResult //.prs_empty def
+ /.prsDictCount countdictstack def
+ RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile will PrescanFile.) = } if
+ { //PrescanFile } stopped pop
+ //.prs_dict /.prsResult get
+ end
+ RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile end) = } if
+} bind def
+
+/GetCIDSystemInfo { % <InstName> <CatName> GetCIDSystemInfo <CSI>
+
+ % Retrieve CSI, using caches.
+
+ RESMPDEBUG { (cidcm GetCIDSystemInfo beg) = } if
+ /Category findresource begin % /InstName
+ dup ResourceStatus
+ {
+ pop 2 lt {
+ FindResource /CIDSystemInfo .knownget not {
+ //.prs_empty
+ } if % CSI
+ } { % /InstName
+ currentdict /GetCIDSystemInfoFromMap .knownget {
+ exec
+ } if
+ dup type /nametype eq
+ {
+ RESMPDEBUG { (cidcm GetCIDSystemInfo got a name.) = } if
+ //.prs_dict Category get % /InstName CSIs
+ dup 2 index known
+ //enable_cache and {
+ RESMPDEBUG { (cidcm GetCIDSystemInfo from cache.) = } if
+ exch get % CSI
+ } {
+ RESMPDEBUG { (cidcm GetCIDSystemInfo from file.) = } if
+ exch % CSIs /InstName
+ dup //path_buffer ResourceFileName % CSIs /InstName (path)
+ RESMPDEBUG { (cidcm GetCIDSystemInfo from file ) print dup = } if
+ currentglobal exch //true setglobal % CSIs /InstName g (path)
+ mark exch % CSIs /InstName g [ (path)
+ { (r) file } stopped {
+ cleartomark //.prs_empty
+ } {
+ exch 1 index % CSIs /InstName g file [ file
+ //GetCIDSystemInfoFromFile stopped {
+ cleartomark closefile //.prs_empty
+ } {
+ exch pop exch closefile
+ } ifelse
+ } ifelse % CSIs /InstName g CSI
+ exch setglobal % CSIs /InstName CSI
+ dup 4 1 roll % CSI CSIs /InstName CSI
+ put % CSI
+ RESMPDEBUG {
+ (cidcm GetCIDSystemInfo got from file : <<) print
+ dup { exch //=string cvs print ( ) print
+ //=string cvs print ( ) print
+ } forall
+ (>>) =
+ } if
+ } ifelse
+ } if
+ } ifelse
+ } {
+ pop //.prs_empty
+ } ifelse
+ end
+ RESMPDEBUG { (cidcm GetCIDSystemInfo end) = } if
+} bind def
+
+/IsCompatibleCSI { % <CSI-M> <CSI-F> IsCompatibleCSI <bool>
+
+ % The CSI in a CIDFont may be an array, a dict, or null.
+ % If it is an array, it must be of 1 element, which is a dict.
+ % In this case the dict is used for testing the compatibility.
+ % Two dicts are compatible iff they contain same /Ordering and /Registry.
+ % Identity CMap is compatible with any CIDFont.
+
+ exch % CSI-F CSI-M
+ { dup type /arraytype eq {
+ dup length 1 ne {
+ pop pop //false exit
+ } if
+ 0 get
+ } if % CSI-F CSI-M
+ dup type /dicttype ne {
+ pop pop //false exit
+ } if % CSI-F <<CSI-M>>
+ exch % <<CSI-M>> CSI-F
+ dup type /dicttype ne {
+ pop pop //false exit
+ } if % <<CSI-M>> <<CSI-F>>
+ dup /Ordering .knownget {
+ /Identity eq {
+ pop pop //true exit
+ } if
+ } if
+ //true % <<CSI-M>> <<CSI-F>> bEQ
+ [/Registry /Ordering] {
+ 2 index 1 index .knownget not {
+ 1234567
+ } if % <<CSI-M>> <<CSI-F>> bEQ /key vF
+ exch % <<CSI-M>> <<CSI-F>> bEQ vF /key
+ 4 index exch .knownget not {
+ 7654321
+ } if % <<CSI-M>> <<CSI-F>> bEQ vF vM
+ eq and % <<CSI-M>> <<CSI-F>> bEQ
+ } forall
+ exch pop exch pop % bEQ
+ exit
+ } loop
+} bind def
+
+/IsWellComposed { % <CIDFontName> <CMapName> IsWellComposed <bool>
+
+ % Check if the given CIDFont and CMap have compatible CSIs.
+ exch % /CMapName /CIDFontName
+ /CIDFont //GetCIDSystemInfo exec % /CMapName CSI-F
+ dup type /dicttype eq {
+ dup length 0 ne {
+ exch % CSI-F /CMapName
+ /CMap //GetCIDSystemInfo exec % CSI-F CSI-M
+ //IsCompatibleCSI exec % bool
+ } {
+ pop pop //false
+ } ifelse
+ } {
+ pop pop //false
+ } ifelse
+} bind def
+
+/IsComposedFont { % <FontName> IsComposedFont <CIDFontName> <CMapName> true
+ % <FontName> IsComposedFont false
+
+ % Check if the given font name may be decomposed into CIDFont.CMap, CIDFont-CMap
+ % or into CIDFont--CMap, such that CIDFont and CMap have compatible CSIs.
+ % FontName
+ dup type /stringtype ne {
+ //name_buffer cvs
+ } if % (FontName)
+ { dup length 2 sub -1 1 {
+ % (FontName) i
+ 2 copy get dup //minus eq exch //period eq or {
+ 2 copy 2 copy % (FontName) i (FontName) i (FontName) i
+ 2 copy get //minus eq {
+ 2 copy 1 sub get //minus eq {
+ 1 sub
+ } if
+ } if % (FontName) i (FontName) i (FontName) i0
+ 0 exch getinterval cvn % (FontName) i (FontName) i /CIDFontName
+ 3 1 roll % (FontName) i /CIDFontName (FontName) i
+ 1 add dup % (FontName) i /CIDFontName (FontName) i1 i1
+ 5 index length % (FontName) i /CIDFontName (FontName) i1 i1 l
+ exch sub getinterval cvn % (FontName) i /CIDFontName /CMapName
+ 2 copy //IsWellComposed exec { % (FontName) i /CIDFontName /CMapName
+ 4 2 roll pop pop % /CIDFontName /CMapName
+ stop
+ } if
+ pop pop pop
+ } {
+ pop
+ } ifelse % (FontName)
+ } for
+ pop
+ } stopped
+} bind def
+
+/ComposeName { % <CIDFont> <CMap> <scr> ComposeName <CIDFont-CMap>
+ dup dup 5 2 roll % (scr) (scr) /CIDFont /CMap (scr)
+ 3 2 roll exch cvs length dup % (scr) (scr) /CMap l0 l0
+ 4 -1 roll exch //minus put % (scr) /CMap l0
+ 1 add dup % (scr) /CMap l1 l1
+ 3 index dup length % (scr) /CMap l1 l1 (scr) L
+ 2 index sub % (scr) /CMap l1 l1 (scr) LT
+ 3 2 roll % (scr) /CMap l1 (scr) LT l1
+ exch getinterval % (scr) /CMap l1 (scrT)
+ 3 2 roll exch cvs length % (scr) l1 l2
+ add 0 exch getinterval % (CIDFont-CMap)
+} bind def
+
+% Redefine the /Font category with CIDFont-CMap construction :
+
+% The following code supposes that the following names are not
+% defined in the old /Font category dictionary :
+% /IsComposedFont, /IsWellComposed .
+
+/Font /Category findresource dup length dict copy begin
+
+/FindResource { % <InstName> FindResource <inst>
+ dup //ResourceStatus exec {
+ pop pop //FindResource exec
+ } {
+ dup //IsComposedFont exec { % /FontName /CIDFontName /CMapName
+ exch [ exch ] composefont % inst
+ } {
+ //FindResource exec
+ } ifelse
+ } ifelse
+} bind def
+
+/ResourceStatus { % <InstName> ResourceStatus <nStatus> <nSize> true
+ % <InstName> ResourceStatus false
+ dup //ResourceStatus exec {
+ 3 2 roll pop //true % nStatus nSize true
+ } {
+ //IsComposedFont exec { % /CIDFontName /CMapName
+ /CMap resourcestatus { % /CIDFontName nStatusM nSizeM
+ exch pop exch % nSizeM /CIDFontName
+ /CIDFont resourcestatus { % nSizeM nStatusF nSizeF
+ exch pop % nSizeF nSizeM
+ dup 0 ge {
+ exch dup 0 ge {
+ add
+ } {
+ exch pop
+ } ifelse
+ } {
+ pop
+ } ifelse % nSize
+ 2 exch //true % nStatus nSize true
+ } {
+ pop pop pop //false % work around buggy resource file
+ } ifelse
+ } {
+ pop pop pop //false % work around buggy resource file
+ } ifelse
+ } {
+ //false
+ } ifelse
+ } ifelse
+} bind def
+
+/ResourceForAll { % <template> <proc> <scratch> ResourceForAll -
+
+ % We suppose that the resourceforall procedure does not
+ % define or install new fonts, CMaps, and/or CIDFonts.
+
+ % First we create 3 temporary dictionaries to store temporary data
+ % about fonts, CMaps and CIDFonts.
+ % These dictionaries must be created dynamically, to allow for a possible
+ % recursive call to resourceforall from the resourceforall procedure.
+ currentglobal //false setglobal
+ 20 dict 20 dict 20 dict % (templ) proc (scr) g <<CIDFont>> <<CMap>> <<Fonts>>
+
+ % Store resource identifiers into local dictionaries
+ % A resource instance can have a key that is not a name or a string. In this
+ % case, resourceforall passes the key directly to proc instead of copying it
+ % into the scratch string. This case can arise only for a resource instance
+ % defined in virtual memory by a previous defineresource
+
+ % Discard non-string keys of CIDFont and CMap because <CIDFontName>-<CMapName>
+ % is only defined for names.
+
+ { /.DisableResourceOrdering pop % gs_resmp accesses this through execstack - don't remove !
+
+ 6 index [ 2 index {exch //null put} aload pop ] cvx bind 6 index //ResourceForAll exec
+
+ (*) [ 3 index {exch dup type /stringtype eq { cvn dup put } { pop pop } ifelse } aload pop
+ ] cvx bind 6 index /CMap resourceforall
+
+ (*) [ 4 index {exch dup type /stringtype eq { cvn dup put } { pop pop } ifelse } aload pop
+ ] cvx bind 6 index /CIDFont resourceforall
+
+ exit
+ } loop % This loop is a pattern for execstack_lookup - don't remove !
+ 4 -1 roll setglobal % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
+
+ %% Make the list of fonts in the form (/Name status) :
+
+ % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
+ dup {
+ pop dup
+ //ResourceStatus exec {
+ pop 2 index % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>> /Name nStatus <<Font>>
+ 3 1 roll put % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
+ } {
+ pop
+ } ifelse
+ } forall % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>>
+
+ %% Add CIDFont-CMap to it (filtering duplicates) :
+
+ 3 2 roll {
+ 3 index {
+ 3 1 roll % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /CIDFont /CMap
+ 6 index //ComposeName exec % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap (Font)
+ dup 8 index .stringmatch {
+ cvn % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /Font
+ dup 4 index exch known {
+ pop pop
+ } {
+ 2 index % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /Font /CIDFont
+ 4 2 roll % (templ) proc (scr) <<CMap>> <<Font>> /Font /CIDFont /CIDFont /CMap
+ //IsWellComposed exec {
+ exch 2 index exch 2 put % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont
+ } {
+ exch pop
+ } ifelse
+ } ifelse
+ } {
+ pop pop
+ } ifelse
+ dup % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CIDFont
+ } forall
+ pop pop % (templ) proc (scr) <<CMap>> <<Font>>
+ } forall % (templ) proc (scr) <<CMap>> <<Font>>
+ exch pop % (templ) proc (scr) <<Font>>
+ 4 3 roll pop % proc (scr) <<Font>>
+
+ % Make the enumerator and apply it :
+ /MappedCategoryRedefiner /ProcSet findresource /MakeResourceEnumerator get exec exec
+} bind def
+
+currentdict end /Font exch /Category defineresource pop
+end
+setglobal .setlanguagelevel