[Gs-devel] font map format design problem
mpsuzuki at hiroshima-u.ac.jp
mpsuzuki at hiroshima-u.ac.jp
Fri Nov 16 09:15:28 PST 2001
Dear Mr. Melichev,
As a sample material for discussion, I attached CIDFnmap
patch against HEAD at sourceforge cvs. I didn't remove
support for TTF/TTC, so undefined ".loadcjkvttcidfont"
procedure (which is defined in gs_ttf.ps of jumbo patch)
is included.
>So now there are alternatives for CIDFnmap/HEAD :
>
>1. Use 3 different formats for native fonts, for FAPI fonts,
> and for CID fonts;
>2. Unify native fonts and CID fonts like gs-cjk did.
> Not sure that will not cause problems in future,
> if more attributes appear.
>3. Unify CIDFnmap and FAPI map as shown above;
> This is pretty flexible thing, rather few more typing.
>4. Develop an unified language for all 3 things,
> so as the old fontmap language is a subset of it.
> Perhaps no time for this now.
>
>I would prefer to go with (3) and switch from it to (4)
>when a necessity appears.
>At least this doesn't require a special parser for now,
>and enough flexible for future.
Also I think (3) is best. In fact, using dictionary object
as fontmap for CID-keyed font was discussed in gs-cjk (but,
gs-cjk choosed simularity to Fontmap syntax).
Regards,
mpsuzuki
diff -PNu gs/lib/gs_init.ps gs-cjk/lib/gs_init.ps
--- gs/lib/gs_init.ps Sat Nov 10 20:32:59 2001
+++ gs-cjk/lib/gs_init.ps Sat Nov 17 01:32:06 2001
@@ -116,6 +116,7 @@
currentdict /NOCIE known /NOCIE exch def
currentdict /NODISPLAY known not /DISPLAYING exch def
currentdict /NOFONTMAP known /NOFONTMAP exch def
+currentdict /NOCIDFONTMAP known /NOCIDFONTMAP exch def
currentdict /NOFONTPATH known /NOFONTPATH exch def
currentdict /NOGC known /NOGC exch def
currentdict /NOINTERPOLATE .knownget { /INTERPOLATE exch not def } if
diff -PNu gs/lib/gs_cidcm.ps gs-cjk/lib/gs_cidcm.ps
--- gs/lib/gs_cidcm.ps Sat Nov 10 20:32:58 2001
+++ gs-cjk/lib/gs_cidcm.ps Sat Nov 17 01:32:03 2001
@@ -163,7 +163,21 @@
{ (r) file % CSIs /InstName g [ file
//GetCIDSystemInfoFromFile exec % CSIs /InstName g [ CSI
} stopped {
- cleartomark //.prs_empty
+ % Cannot find file from Resource directory
+ cleartomark
+ % Try to find file from CIDFontmap
+ % Stack: CSIs /InstName g
+ 1 index dup .CIDFontmapKnownget {
+ % Stack: CSIs /InstName g /InstName ValueInCIDFontmap
+ % We do look at CIDFontmap in global space.
+ % (When stopped, the space is set to local.)
+ true setglobal
+ 1 index 3 1 roll
+ .CIDFontmapRunHandler
+ /CIDFont findresource /CIDSystemInfo get
+ } {
+ pop //.prs_empty
+ } ifelse
} {
exch pop
} ifelse % CSIs /InstName g CSI
diff -PNu gs/lib/gs_cidfn.ps gs-cjk/lib/gs_cidfn.ps
--- gs/lib/gs_cidfn.ps Sat Nov 10 20:32:58 2001
+++ gs-cjk/lib/gs_cidfn.ps Sat Nov 17 01:32:03 2001
@@ -337,26 +337,333 @@
dup /CIDFontType get //.cidfonttypes exch get exec
} odef
+/.loadcidfontwithoutpop {
+ dup 4 string .peekstring pop dup (ttcf) eq exch (\000\001\000\000) eq or {
+ .loadcjkvttcidfont
+ } {
+ /CIDFont /Category findresource /.Instances get
+ dup length 2 div cvi dict .copydict exch
+ .loadfont
+ % Stack: <<original-.Instances>>
+ /CIDFont /Category findresource /.Instances get {% forall
+ % <<original-.Instances>> key value
+ 2 index 2 index known {
+ pop pop
+ } {
+ pop exch pop /CIDFont findresource exit
+ } ifelse
+ } forall
+ dup /CIDFontName known not {
+ {Internal Error in .loadcidfontwithoutpop} stop
+ } if
+ } ifelse
+} bind def
+
+/.loadcidfont {
+ .loadcidfontwithoutpop pop
+} bind def
+
+% Define the name of the CID font map file.
+/defaultcidfontmap (CIDFnmap) def
+userdict /CIDFontmap 10 dict put
+
+% <dict> <file> .readCIDFontmap <dict>
+% Code from gs_fonts.ps::.readFontmap
+/.readCIDFontmap {
+ { dup token not { closefile exit } if
+ % This is a hack to get around the absurd habit of MS-DOS editors
+ % of adding an EOF character at the end of the file.
+ dup (\032) eq { pop closefile exit } if
+ 1 index token not
+ { (CIDFontmap entry for ) print dup =only
+ ( has no associated file or alias name! Giving up.) = flush
+ {.readCIDFontmap} 0 get 1 .quit
+ } if
+ dup type dup /stringtype eq exch /nametype eq or not
+ { (CIDFontmap entry for ) print 1 index =only
+ ( has an invalid file or alias name! Giving up.) = flush
+ {.readCIDFontmap} 0 get 1 .quit
+ } if
+ % stack: dict file cidfontname filename|aliasname
+ 1 index type /stringtype eq
+ 1 index type /nametype eq and 1 index xcheck and
+ 1 index /run eq 2 index /.runlibfile eq or and {
+ % This is an inclusion entry.
+ pop findlibfile { exch pop } { file } ifelse
+ 2 index exch .readCIDFontmap pop
+ } {
+ % This is a real entry.
+ % stack: dict file cidfontname filename|aliasname
+
+ % Before staring a game, we need a hack.
+ % Some CJK pdf file contains a cidfontname that cannot
+ % be represented as a nametype literal. Instead, the
+ % cidfontname is represented as a string literal.
+ % If a cidfontname is represented as a stringtype object,
+ % it must be converted to a nametype object.
+ % We handle such a case here.
+ exch dup type /stringtype eq {cvn} if exch
+
+ % stack: dict file cidfontname filename|aliasname
+ % Read and pop tokens until a semicolon.
+ { 2 index token not
+ { (CIDFontmap entry for ) print 1 index =only
+ ( ends prematurely! Giving up.) = flush
+ {.readCIDFontmap} 0 get 1 .quit
+ } if
+ dup /; eq { pop 3 index 3 1 roll .growput exit } if
+ % Format:
+ % /CIDFontname (file) ttc-index ;
+ % /CIDFontname (file) /Code->CID-dict ;
+ % /CIDFontname (file) ttc-index /Code->CID-dict ;
+ %
+ % e.g.
+ % /HG-MinchoL (hgminchol.ttc) 1 /Adobe-Japan1-Unicode ;
+ % /HG-PMinchoL (hgminchol.ttc) 2 /Adobe-Japan1-Unicode ;
+ % /HG-MinchoL-J2 (hgminchol.ttc) 1 /Adobe-Japan2-Unicode ;
+ % /HG-PGothicB (hggothicb.ttc) 2 ;
+ % /HG-GothicB-J2 (hggothicb.ttc) /Adobe-Japan2-Unicode ;
+ %
+ % CID Fontmap entry is stored into CIDFontmap dict as an array.
+ % Array format:
+ % [filename ttc-index]
+ % [filename /Code->CID-dict]
+ % [filename ttc-index /Code->CID-dict]
+ %
+ % Type:
+ % filename: string
+ % ttc-index: integer
+ % /Code->CID-dict: name
+ %
+ % stack: dict file cidfontname filename something
+ 1 index type /nametype eq {
+ (CIDFontmap entry for ) print 2 index =only
+ (defines an alias! Giving up.) = flush
+ {.readCIDFontmap} 0 get 1 .quit
+ } if
+ % stack: dict file cidfontname filename something
+ exch [ exch 3 -1 roll
+ % stack: dict file cidfontname [ filename something
+ dup type /integertype eq {
+ % stack: dict file cidfontname [ filename int
+ % Read next token
+ 4 index token not
+ { (CIDFontmap entry for ) print 3 index =only
+ ( ends prematurely! Giving up.) = flush
+ {.readCIDFontmap} 0 get 1 .quit
+ } if
+ } if
+ % stack: dict file cidfontname [ filename int something
+ % or dict file cidfontname [ filename something
+ dup /; eq not 1 index type /nametype eq and {
+ % stack: dict file cidfontname [ filename /Code->CID
+ % or dict file cidfontname [ filename int /Code->CID
+ % Read next token
+ counttomark 2 eq {4} {5} ifelse index token not
+ { (CIDFontmap entry for ) print
+ counttomark 2 eq {3} {4} ifelse index =only
+ ( ends prematurely! Giving up.) = flush
+ {.readCIDFontmap} 0 get 1 .quit
+ } if
+ } if
+ % stack: dict file cidfontname [ filename int /Code->CID something
+ % or dict file cidfontname [ filename /Code->CID something
+ dup /; eq {
+ pop ]
+ 3 index 3 1 roll .growput exit
+ } if
+ pop
+ } loop
+ } ifelse
+ } loop
+} bind def
+
+% <file> .loadCIDFontmap -
+/.loadCIDFontmap {
+ userdict /CIDFontmap get exch
+ .readCIDFontmap pop
+} bind def
+
+% Code from .loadinitialfonts
+/.loadinitialcidfonts
+ { NOCIDFONTMAP not
+ { /CIDFONTMAP where
+ { pop [ CIDFONTMAP .pathlist ]
+ { dup VMDEBUG findlibfile
+ { exch pop .loadCIDFontmap }
+ { /undefinedfilename signalerror }
+ ifelse
+ }
+ }
+ { LIBPATH
+ { defaultcidfontmap 2 copy .filenamedirseparator
+ exch concatstrings concatstrings dup VMDEBUG
+ (r) { file } .internalstopped
+ { pop pop } { .loadCIDFontmap } ifelse
+ }
+ }
+ ifelse forall
+ }
+ if
+ %%% Do nothing
+ } bind def
+.loadinitialcidfonts
+
+/CIDFontmapHandler <<
+ /nametype {
+ /CIDFont findresource
+ /CIDFont defineresource pop
+ } bind
+ /stringtype {
+ findlibfile {
+ exch pop
+ % Define CIDFont with a name defined in the font file
+ .loadcidfontwithoutpop
+ % Define CIDFont with a name define in CIDFontmap
+ dup length 0 ne {
+ dup /CIDFontName get 2 index eq {
+ % Avoid duplicated defineresource for the same CIDFont
+ pop pop
+ } {
+ % Give a name different from the name defined in the file
+ /CIDFont defineresource pop
+ } ifelse
+ } {
+ pop pop
+ } ifelse
+ } {
+ /undefinedresource signalerror
+ } ifelse
+ } bind
+ /arraytype {
+ % Replace filename in the array with file
+ dup 0 get
+ findlibfile {
+ 3 1 roll pop
+ copyarray dup 3 1 roll 0
+ 3 -1 roll put
+ % Expand array
+ aload pop .loadcjkvttcidfont
+ /CIDFont defineresource pop
+ } {
+ /undefinedresource signalerror
+ } ifelse
+ } bind
+>> def
+
+%%% CIDFontmap Public Interface
+% /CIDFontName .CIDFontmapKnown true|false
+/.CIDFontmapKnown {
+ userdict /CIDFontmap get exch known
+} bind def
+
+% /CIDFontName .CIDFontmapKnownget value true
+% /CIDFontName .CIDFontmapKnownget false
+/.CIDFontmapKnownget {
+ userdict /CIDFontmap get exch .knownget
+} bind def
+
+% /CIDFontName value .CIDFontmapRunHandler -
+/.CIDFontmapRunHandler {
+ dup CIDFontmapHandler exch type get .execasresource
+} bind def
+
+% proc .CIDFontmapForAll -
+/.CIDFontmapForAll {
+ CIDFontmap exch forall
+} bind def
+
+% proc .CIDFontmapForAllKey -
+/.CIDFontmapForAllKey {
+ [ /pop cvx 3 -1 roll /exec cvx ] cvx .CIDFontmapForAll
+} bind def
+
/CIDFont /Generic /Category findresource dup length dict .copydict
dup /InstanceType /dicttype put
dup /DefineResource {
.buildcidfont
/Generic /Category findresource /DefineResource get exec
} put
+/.originalresourceforall 1 index /ResourceForAll get def
+dup /ResourceForAll {
+ currentglobal false setglobal
+ % (template) (proc) (scratch) g
+ [ % (template) (proc) (scratch) g [
+ %
+ % 1. Gather CIDFont name in /Resource/CIDFont
+ %
+ 4 index % (template) (proc) (scratch) g [ (template)
+ {cvn} % (template) (proc) (scratch) g [ (template) {cvn}
+ 4 index % (template) (proc) (scratch) g [ (template) {cvn} (scratch)
+ .originalresourceforall
+ % (template) (proc) (scratch) g [ ...
+ %
+ % 2. Gather CIDFont name in CIDFontmap
+ %
+ {
+ dup length string cvs
+ dup % (template) (proc) (scratch) g [ ... (Key) (Key)
+ counttomark 4 add index
+ % (template) (proc) (scratch) g [ ... (Key) (Key) (template)
+ .stringmatch {
+ cvn
+ % (template) (proc) (scratch) g [ ... /Key
+ % 3. Remove duplicated /Key
+ counttomark -1 1 {
+ index 1 index eq {
+ pop exit % Duplicated
+ } if
+ } for
+ } {
+ pop
+ } ifelse
+ } .CIDFontmapForAllKey
+ ]
+ exch setglobal
+ %
+ % 4. Build extended procedure
+ %
+ % (template) (proc) (scratch) [CIDFontmapKeys]
+ 4 -1 roll pop
+ % (proc) (scratch) [CIDFontmapKeys]
+ 3 1 roll
+ % [CIDFontmapKeys] (proc) (scratch)
+ [ exch {cvs} aload pop
+ % [CIDFontmapKeys] (proc) [ (scratch) -cvs-
+ 4 -1 roll aload pop ] cvx
+ % [CIDFontmapKeys] proc++
+ %
+ % 5. Exec
+ %
+ forall
+} put
+
% CIDFonts may be defined in CFF OpenType files.
% Check for this here.
/.loadcidfontresource {
dup .ResourceFile {
- {.loadfont} .execasresource
+ {.loadcidfont} .execasresource
+ } {
+ pop dup
+ .CIDFontmapKnownget {
+ .CIDFontmapRunHandler
} {
dup /undefinedresource signalerror
} ifelse
+ } ifelse
} bind def
dup /.LoadResource {
currentglobal {
.loadcidfontresource
} {
true setglobal {.loadcidfontresource} stopped false setglobal {stop} if
+ } ifelse
+} bind put
+dup /.ResourceFileStatus {
+ dup .CIDFontmapKnown {
+ pop 2 -1 true
+ } {
+ .ResourceFile { closefile 2 -1 true } { pop false } ifelse
} ifelse
} bind put
More information about the gs-devel
mailing list