%! /me (ttcf2cid.ps by suzuki toshiya, Masatake YAMATO and gs-cjk project) def % % Usage: % % $ gs [-q] -dNODISPLAY [-dBATCH] [-sOUTPUTDIR=[dir|-|*]] \ % -sttfont=filename.ttf | -spsfont=fontname |\ % -sTTFONT=filename.ttc | -sPSFONT=cidfontname |\ % -dTTFONT='{(filename.ttf) /Adobe-GB1-Unicode}' |\ % -dTTFONT='{(filename.ttc) 2 /Adobe-CNS1}' |\ % [-dRAWMODE] ttcf2cid.ps % % References: % % [1] Adobe Systems Incorporated, ``PostScript Language Reference, % third edition,'' pp. 321-390, Feb 1999. % [2] Adobe Systems Incorporated, ``The Type 42 Font Format % Specification, Technical Note #5012,'' Jul 1998. % [3] Adobe Systems Incorporated, ``Adobe CMap and CIDFont Files % Specification, Technical Note #5014,'' Oct 1996. % [4] Adobe Systems Incorporated, ``The Compact Font Format % Specification, Technical Note #5176,'' Mar 2000. % [5] Adobe Systems Incorporated, ``Adobe Type1 Font Format,'' % Feb 1993. % /unknowndef { exch dup where { pop pop pop } { exch def } ifelse } bind def /RAWMODE false unknowndef % uses RD procedure in Font|CIDFont file /OUTPUTDIR () unknowndef % default current directory /ttfont null unknowndef % truetype font filename /psfont null unknowndef % visible-to-gs fontname /TTFONT null unknowndef % CJK truetype font filename /PSFONT null unknowndef % visible-to-gs CID-keyed fontname /isprint { % string isprint boolean false exch { false [ (\t) (\n) (\r) ] { 0 get 2 index eq or } forall not 1 index 16#20 lt and exch 16#7F ge or { true or exit } if } forall not } bind def /concats { % [str ...] concats str () exch dup length 1 sub -1 0 { 1 index exch get dup type /stringtype ne { dup length string cvs } if 3 -1 roll exch dup length 2 index length add string dup dup 4 2 roll copy length 4 -1 roll putinterval exch } for pop } bind def /xtypes << /numbertype { type dup /integertype eq exch /realtype eq or } bind /proctype { dup type /arraytype eq exch xcheck and } bind /binstringtype { dup type /stringtype eq { dup length 256 gt { % for such string as /FontInfo/Notice isprint not } { pop false } ifelse } { pop false } ifelse } bind /arrayofnamestype { dup type /arraytype eq 1 index xcheck not and { true exch { type /nametype eq and { true } { false exit } ifelse } forall } { pop false } ifelse } bind /arrayofstringstype { dup type /arraytype eq 1 index xcheck not and { true exch { type dup /stringtype eq exch /nulltype eq or and { true } { false exit } ifelse } forall } { pop false } ifelse } bind >> def /xtype { % any xtype name null exch xtypes { % null any xtypes {} forall 2 index exch exec { 3 -1 roll pop exch exit } { pop } ifelse } forall exch % any null|name dup null eq { pop type } { exch pop } ifelse } bind def % any name|array of names xtypematch name true % any name|array of names xtypematch false /xtypematch { dup type /arraytype ne { dup 3 -1 roll xtype eq { true } { pop false } ifelse } { null 3 1 roll { % null any array {} forall 1 index exch xtypematch { % null any (any name xtypematch)name true|false 3 1 roll exch pop exit % name any } if % null any } forall pop dup null ne { true } { pop false } ifelse } ifelse } bind def % error output /*errorfp (%stderr) (w) file def /*error { % string|name *error - dup type /stringtype ne { dup length string cvs } if *errorfp exch writestring } bind def % output file, default /*echofp (%stdout) (w) file def /*open { % filename|(%stdout) *open (w) file /*echofp exch def } bind def /*close { % *close *echofp closefile } bind def /*outputpath { % filename *outputpath fullpath|(%stdout) OUTPUTDIR (-) ne { OUTPUTDIR (*) ne { % for debug only OUTPUTDIR () ne { [ OUTPUTDIR pssystemparams /GenericResourcePathSep get 4 -1 roll ] concats } if } { pop (/dev/null) } ifelse } { pop (%stdout) } ifelse } bind def /*echo { % string|name *echo - dup type /stringtype ne { dup length string cvs } if *echofp exch writestring } bind def /*echohex { % string *echohex - *echofp exch writehexstring } bind def /*echooct { % string|name *echooct - dup type /stringtype ne { dup length string cvs } if 3 string exch { % ooo str (\\) *echo 8 2 index cvrs % (8 ooo cvrs)'ooo' dup length 3 exch sub { (0) *echo } repeat *echo % 'ooo' 3-l {} repeat } forall pop } bind def /*echostring { % string|name *echostring - dup type /stringtype ne { dup length string cvs } if (\() *echo dup length 1 sub 0 1 3 -1 roll { 1 index exch 1 getinterval % str (str i 1 getinterval)s false [ (\\) (\() (\)) ] { % str s false 2 index eq or % str s (false (S s eq)boolean or)boolean } forall { % str s boolean (\\) *echo *echo } { dup isprint { *echo } { *echooct } ifelse } ifelse } for pop (\) ) *echo } bind def /*echohexstring { % string *echohexstring - (<) *echo dup length 32 lt { *echohex } { (\n) *echo dup length 1 sub 0 32 3 -1 roll { % str 32 0 l-1 {} for % str (str i (i+32 l min)i+n-i i n getinterval)substr dup 32 add 2 index length 2 copy gt { exch } if pop 1 index sub 2 index 3 1 roll getinterval *echohex (\n) *echo } for pop } ifelse (> ) *echo } bind def /*echorawstring { % string *echorawstring - dup length *echoobj (RD ) *echo *echo (\n) *echo } bind def /*echobinstring { % string|name *echobinstring - RAWMODE not { *echohexstring } { *echorawstring } ifelse } bind def /*level 0 def /*xlevel 0 def /*xcvlit true def /*echotypes << /dicttype { dup length *echoobj dup wcheck { () } { (readonly ) } ifelse exch (dict begin\n) *echo { exch *echoobj *echoobj (def\n) *echo } forall (currentdict end ) *echo *echo } bind /arraytype { ([ ) *echo { *echoobj } forall (] ) *echo } bind /arrayofnamestype { ([ ) *echo dup length 1 sub 0 1 3 -1 roll { dup 8 mod 0 eq { (\n) *echo } if 1 index exch get *echoobj } for pop (] ) *echo } bind /arrayofstringstype { ([ ) *echo { *echobinstring } forall (] ) *echo } bind /proctype { ({ ) *echo *xlevel 0 eq { /*xcvlit false def } if /*xlevel *xlevel 1 add def { *echoobj } forall /*xlevel *xlevel 1 sub def *xlevel 0 eq { /*xcvlit true def } if (}\n) *echo } bind /stringtype { *echostring } bind /binstringtype { *echobinstring } bind /operatortype { 64 string cvs cvn *echoobj } bind %/packedarraytype { pop null *echoobj } bind % ! %/marktype { pop null *echoobj } bind % ! %/savetype { pop null *echoobj } bind % ! %/filetype { pop null *echoobj } bind % ! %/fonttype { pop null *echoobj } bind % ! /nametype { *level 2 mul { ( ) *echo } repeat *xcvlit { (/) *echo } if dup length string cvs *echo ( ) *echo } bind /numbertype { 16 string cvs *echo ( ) *echo } bind /integertype { 16 string cvs *echo ( ) *echo } bind /booleantype { 16 string cvs *echo ( ) *echo } bind /nulltype { pop (null ) *echo } bind >> def /*echoobj { % obj *echoobj - dup xtype *echotypes exch 2 copy known { get exec } { pop pop pop null *echoobj } ifelse } bind def % mark /key1 value1 /key2 value2 ... keyarray % mark /key1 value1 /key2 value2 ... /keys [ /key1 /key2 ... ] /keyarray { counttomark 2 idiv array % mark ... a dup length 1 sub -1 0 { % mark ... a size-1 -1 0 {} for dup 2 index length exch sub 1 sub 2 mul 3 add index % mark ... a i key(2*(size-i-1)+3 index) 2 index 3 1 roll put % mark ... a (a i key(2*i+3 index) put) } for /keys exch } bind def /beginformat { << } bind def /endformat { keyarray >> dup 3 1 roll def } bind def /inheritformat { load dup /keys get { 2 copy get 3 -1 roll } forall pop } bind def % % Font spec. % /FontInfoFormat beginformat % key type req. nestformat /FamilyName [ /stringtype false null ] /FullName [ /stringtype false null ] /Notice [ /stringtype false null ] /Weight [ /stringtype false null ] /version [ /stringtype false null ] /ItalicAngle [ /numbertype false null ] /isFixedPitch [ /boolean false null ] /UnderlinePosition [ /numbertype false null ] /UnderlineThickness [ /numbertype false null ] endformat pop /FontFormat beginformat % key type req. nestformat /FontType [ /integertype true null ] /FontMatrix [ /arraytype true null ] /FontName [ /stringtype false null ] /FontInfo [ /dicttype false /FontInfoFormat ] /LanguageLevel [ /integertype false null ] /WMode [ /integertype false null ] endformat pop /FontType!0Format beginformat /FontFormat inheritformat % key type req. nestformat /Encoding [ /arrayofnamestype true null ] /FontBBox [ /arraytype true null ] /UniqueID [ /integertype false null ] /XUID [ /arraytype false null ] endformat pop % Type42 Font /FontType42Format beginformat /FontType!0Format inheritformat % key type req. nestformat /PaintType [ /integertype true null ] /StrokeWidth [ /numbertype false null ] /Metrics [ /dicttype false null ] /Metrics2 [ /dicttype false null ] /CDevProc [ /proctype false null ] /CharStrings [ /dicttype true null ] /sfnts [ /arrayofstringstype true null ] /CIDMap [ [ /arrayofstringstype /binstringtype /integertype /dicttype ] true null ] /GDBytes [ /integertype false null ] % ! /GlyphDirectory [ [ /arrayofstringstype /dicttype ] false null ] /MetricCount [ /integertype false null ] endformat pop % Type2 Font /FontType2Format beginformat /FontType!0Format inheritformat % key type req. nestformat /PaintType [ /integertype true null ] /StrokeWidth [ /numbertype false null ] /CharStrings [ /dicttype true null ] endformat pop % % CIDFont spec. % /CIDSystemInfoFormat beginformat % key type req. nestformat /Registry [ /stringtype true null ] /Ordering [ /stringtype true null ] /Supplement [ /integertype true null ] endformat pop /CIDFontFormat beginformat % key type req. nestformat /CIDFontType [ /integertype true null ] /CIDFontName [ /stringtype true null ] % ! /CIDSystemInfo [ /dicttype true /CIDSystemInfoFormat ] % %/Encoding [ /arrayofnamestype true null ] /FontBBox [ /arraytype true null ] /FontType [ /integertype true null ] /FontMatrix [ /arraytype true null ] /FontName [ /stringtype false null ] % /FontInfo [ /dicttype false /FontInfoFormat ] %/LanguageLevel [ /integertype false null ] /WMode [ /integertype false null ] /UIDBase [ /integertype false null ] /UniqueID [ /integertype false null ] /XUID [ /arraytype false null ] endformat pop % CIDFontType2 - Type11: Type42-like CIDFont /CIDFontType2Format beginformat /CIDFontFormat inheritformat % key type req. nestformat /CIDCount [ /integertype true null ] /GDBytes [ /integertype true null ] % ! /CIDMap [ [ /arrayofstringstype /binstringtype /integertype /dicttype ] true null ] /sfnts [ /arrayofstringstype true null ] /Encoding [ /arrayofnamestype true null ] /CharStrings [ /dicttype true null ] /PaintType [ /integertype false null ] /StrokeWidth [ /numbertype false null ] /Metrics [ /dicttype false null ] /Metrics2 [ /dicttype false null ] /CDevProc [ /proctype false null ] /GlyphDirectory [ [ /arrayofstringstype /dicttype ] false null ] /MetricCount [ /integertype false null ] endformat pop % CIDFontType0 - Type9: Type1-like CIDFont /CIDFontType0Format beginformat /CIDFontFormat inheritformat % key type req. nestformat /CDevproc [ /proctype false null ] /CIDCount [ /integertype true null ] /CIDFontVersion [ /integertype false null ] /CIDFontRevision [ /integertype false null ] /CIDMapOffset [ /integertype true null ] /FDArray [ /arraytype true null ] /FDBytes [ /integertype false null ] /GDBytes [ /integertype true null ] endformat pop /*echodictformat { % dict fmt *echodictformat - load dup /keys get 3 -1 roll % fmt keys dict dup length *level 0 eq RAWMODE and { 3 add } if *echoobj (dict begin\n) *echo RAWMODE *level 0 eq and { (/RD { string currentfile exch readstring pop } executeonly def\n) *echo (/ND { noaccess def } executeonly def\n) *echo (/NP { noaccess put } executeonly def\n) *echo } if 1 index { % fmt keys dict [] {} forall 1 index exch 2 copy known { % fmt keys dict dict key boolean 4 index 1 index get 2 get dup null eq { % fmt keys dict dict key fmt fmt=null pop % fmt keys dict dict key dup *echoobj get *echoobj (def\n) *echo } { 2 index 2 index get type /dicttype ne { % fmt keys dict dict key fmt type!=/dicttype pop % fmt keys dict dict key dup *echoobj get *echoobj (def\n) *echo } { 3 1 roll dup *echoobj get exch % fmt keys dict nfmt (dict key get)ndict /*level *level 1 add def *echodictformat /*level *level 1 sub def (def\n) *echo } ifelse } ifelse } { pop pop } ifelse } forall % fmt keys dict exch pop { % fmt dict {} forall 2 index 2 index known not { % fmt key value (fmt key known not)!boolean dup type /fonttype ne 1 index type /filetype ne and { exch *echoobj *echoobj (def\n) *echo } { pop pop } ifelse } { pop pop } ifelse } forall (currentdict end ) *echo pop } bind def % % FontType-individual output procedures with DSC, ProcSet and so on % % string|name type42fontdict fontformat *echottfont - /*echottfont { (%!PS-TrueTypeFont-65536-65536-1\n) *echo (%%Creator: ) *echo me *echo (\n) *echo 2 index *echoobj (\n) *echo *echodictformat (\ndefinefont pop\n) *echo (%%EOF\n) *echo pop } bind def % string|name type2fontdict fontformat *echocffont - /*echocffont { (%!PS-Adobe-3.0 Resource-Font\n) *echo (%%BeginResource: Font ) *echo 2 index *echo (\n) *echo (%%Title: \() *echo 2 index *echo (\)\n) *echo (%%Creator: ) *echo me *echo (\n) *echo 2 index *echoobj (\n) *echo *echodictformat (\n/Font defineresource pop\n) *echo (%%EndResource\n) *echo (%%EOF\n) *echo pop } bind def % string|name type2cidfontdict fontformat *echottcidfont - /*echottcidfont { (%!PS-Adobe-3.0 Resource-CIDFont\n) *echo (%%DocumentNeedResources: procset CIDInit\n) *echo (%%IncludeResource: procset CIDInit\n) *echo (%%BeginResource: CIDFont ) *echo 2 index *echo (\n) *echo (%%Title: \() *echo 2 index *echo ( ) *echo 1 index /CIDSystemInfo get dup /Registry get *echo ( ) *echo dup /Ordering get *echo ( ) *echo /Supplement get 16 string cvs *echo (\)\n) *echo (%%Creator: ) *echo me *echo (\n) *echo (/CIDInit /ProcSet findresource begin\n) *echo 2 index *echoobj (\n) *echo *echodictformat (\n/CIDFont defineresource pop\n) *echo (end\n) *echo (%%EndResource\n) *echo (%%EOF\n) *echo pop } bind def % string|name type0cidfontdict fontformat *echocidfont - /*echocidfont { *echottcidfont } bind def /*echofonttypes << 2 { /FontType2Format *echocffont } % ! 42 { /FontType42Format *echottfont } 9 { /CIDFontType0Format *echocidfont } % ! 11 { /CIDFontType2Format *echottcidfont } >> def /*echofont { % string|name fontdict *echofont - dup /FontType get *echofonttypes exch 2 copy known { get exec } { % string|name fontdict *echofonttypes FontType exch pop (Error: Unsupported FontType ) *error 16 string cvs *error pop ( for ) *error *error (\n) *error *errorfp flushfile } ifelse } bind def % .openttfont /.openttfont { (r) file .loadttfont } bind def % % FontType42 generation ------------------------------------------------ % [ //ttfont null ne { //ttfont } if %(/usr/local/share/fonts/truetype/solaris8/MonotypeCenturySchoolbook.ttf) ] { dup type /arraytype eq 1 index xcheck and { exec } if .openttfont dup /FontName get dup type /nametype eq { dup length string cvs } if dup *outputpath *open exch *echofont *close } forall % % font resource generation ---------------------------------------- % [ //psfont null ne { //psfont } if %(TimesNewRomanHebrew) %/CourierNewHebrew ] { dup type /nametype eq { dup length string cvs } if dup *outputpath *open dup findfont *echofont *close } forall % % CIDFontType2 generation ---------------------------------------- % [ //TTFONT null ne { //TTFONT } if %{ (/usr/local/share/fonts/truetype/solaris8/msgbl.ttf) /Adobe-GB1 } %(/usr/local/share/fonts/truetype/solaris8/mkgbm.ttf) ] { dup type /arraytype eq 1 index xcheck and { exec } if .openttcidfont dup /CIDFontName get dup type /nametype eq { dup length string cvs } if dup *outputpath *open exch *echofont *close } forall % % CIDFont resource generation ---------------------------------------- % [ //PSFONT null ne { //PSFONT } if %/ZenKai-Medium %(Baekmuk-Batang) ] { dup type /nametype eq { dup length string cvs } if dup *outputpath *open dup /CIDFont findresource *echofont *close } forall