% Copyright (C) 1997 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. % writecff.ps % Write out a Type 2 font as CFF. % **************** THIS FILE DOES NOT WORK. **************** % **************** DON'T TRY TO USE IT. **************** currentglobal true setglobal (gs_cff.ps) runlibfile setglobal 50 dict begin % ---------------- Standard strings/names ---------------- % /FontSetInit /ProcSet findresource begin mark /StandardSIDs StandardStrings length 1.5 mul cvi dict dup 0 1 StandardStrings length 1 sub { % Stack: mark /StdSIDs dict dict index dup StandardStrings exch get exch put dup } for pop end counttomark 2 idiv { def } repeat pop % ---------------- Standard encodings ---------------- % % ---------------- Standard Charsets ---------------- % % ---------------- Output utilities ---------------- % % Free variables: f (output file), fpos (position in f). /advance { % advance - fpos add /fpos exch store } def /next { % next - f exch write 1 advance } def /nextstring { % nextstring - dup type /nametype eq { .namestring } if f 1 index writestring length advance } def /card8 % card8 - /next load def /card16 { % card16 - dup -8 bitshift next 255 and next } def /offset { % offset - 1 sub -1 0 { -8 mul 2 copy bitshift 255 and next pop } for pop } def /sid % sid - /card16 load def /lenoffsize { % lenoffsize dup 255 le { pop 1 } { -8 bitshift lenoffsize 1 add } ifelse } def /Index { % [ ...] Index - % Calculate the maximum offset we need to be able to represent. 1 1 index { dup null eq { pop } { length add } ifelse } forall lenoffsize % stack: items offsize 1 index length card16 dup next 1 2 index { % stack: items offsize pos item 1 index 3 index offset dup null eq { pop } { length add } ifelse } forall exch offset { nextstring } forall } def /idIndex { % idIndex - 1 index length array 3 -1 roll { 3 index sub 2 index exch 3 -1 roll put } forall exch pop Index } def /stringid { % stringid StandardSIDs 1 index .knownget { exch pop } { sids 1 index .knownget { exch pop } { StandardSIDs length sids length add sids 3 -1 roll 2 index put } ifelse } ifelse } def /.valuetypedict mark /booleantype { { 1 } { 0 } ifelse intvalue } /arraytype { { value } forall } /packedarraytype 1 index /stringtype { stringid intvalue } /nametype 1 index /realtype { realvalue } /integertype { intvalue } .dicttomark readonly def /value { % value - dup type .valuetypedict exch get exec } def /.realchardict mark 48 1 57 { dup 48 sub } for % digits 46 10 69 11 101 11 % . E e 45 { % - -- handle E- specially dup 15 and 11 eq { 15 or 12 } { dup 16#bf eq { pop 255 12 } { 14 } ifelse } ifelse } .dicttomark readonly def /realvalue { % realvalue - =string cvs 255 exch { .realchardict exch get exec 1 index 15 and 15 ne { exch next 255 exch } if 1 index 240 and 240 eq { 4 bitshift 240 } { 15 } ifelse sub add } forall next } def /intvalue { % intvalue - dup dup -107 ge exch 107 le and { 139 add next } { dup dup -1131 ge exch 0 lt and { neg 16#fa94 add card16 } { dup dup 1131 le exch 0 ge and { 16#f694 add card16 } { dup dup -32768 ge exch 32767 le and { 28 next 65535 and card16 } { 29 next dup -16 bitshift 2 { 65535 and card16 } repeat } ifelse } ifelse } ifelse } ifelse } def /op { % op - dup 32 ge { 12 next 32 sub } if next } def /vdef { % vdef - exch value op } def /nedef { % nedef - exch 2 index eq { pop pop } { vdef } ifelse } def /Dict { % Dict - exch { % stack: opsdict key value 2 index 3 -1 roll .knownget { dup type /integertype eq { vdef } { exec } ifelse } { pop } ifelse } forall pop } def /collect { % collect 10 dict begin /str 500 string def /spos 0 def /fpos 0 def /f { pop length spos add /spos exch store spos str length eq { /str str str concatstrings def } if str spos str length spos sub getinterval } /NullEncode filter def exec f closefile str 0 spos getinterval end } def % Write a forward reference in a Dict, and save its position. /forward { % forward - {null null <1c 00 00> <1d 00 00 00 00>} exch get nextstring exch fpos store op } def % ------ Top (font) dictionary ------ % /topkeyops mark /version 0 /Notice 1 /Copyright 32 /FullName 2 /FamilyName 3 /Weight 4 /isFixedPatch { false 33 nedef } /ItalicAngle { 0 34 nedef } /UnderlinePosition { -100 35 nedef } /UnderlineThickness { 50 36 nedef } /PaintType { 0 37 nedef } /CharstringType { 2 38 nedef } /FontMatrix { true 0 1 5 { 2 index 1 index get {0.001 0 0 0.001 0 0} 3 -1 roll get eq and } for { pop } { 39 vdef } ifelse } /UniqueID 13 /FontBBox 5 /StrokeWidth { 0 40 nedef } /XUID 14 /FontInfo { topkeyops Dict } %**** charset, Encoding /CharStrings { pop /charstringsoffset 17 offsetsize forward } /Private { pop /privateoffset 18 offsetsize forward } .dicttomark readonly def % ------ Private dictionary ------ % /deltarray { % [ ...] deltarray - exch 0 exch { 1 index sub dup value add } forall pop op } def /privatekeyops mark /BlueValues { 6 deltarray } /OtherBlues { 7 deltarray } /FamilyBlues { 8 deltarray } /FamilyOtherBlues { 9 deltarray } /BlueScale { 0.039625 41 nedef } /BlueShift { 7 42 nedef } /BlueFuzz { 1 43 nedef } /StdHW 10 /StdVW 11 /StemSnapH { 44 deltarray } /StemSnapV { 45 deltarray } /ForceBold { false 46 nedef } /ForceBoldThreshold { 0 47 nedef } % Skip lenIV, it's always -1 /LanguageGroup { 0 49 nedef } /ExpansionFactor { 0.06 50 nedef } /initialRandomSeed { 0 51 nedef } /Subrs { pop /subrsoffset 19 2 forward } /defaultWidthX { 0 20 nedef } /nominalWidthX { 0 21 nedef } .dicttomark readonly def % ------ Main program ------ % /putoffset { % putoffset - % The saved index points just beyond the end of the number, % and we wrote a zero as the placeholder. % Consequently, we don't need the offset size. pop { dup 0 eq { exit } if exch 1 sub exch 3 copy 255 and put -8 bitshift } loop pop pop pop } def /writecff { % [ ...] writecff - 30 dict begin % The dictionary for each font contains: % font - the original Type 2 font % subrs - the Local Subrs Index % chars - the CharStrings Index % private - the Private Dict % top - the Top Dict % charspos - the offset of the CharStrings Dict relative to % the start of all CharStrings % privatepos - the offset of the Private Dict relative to % the start of all Private Dicts % subrsoffset - the offset of the Local Subrs offset % reference in the Private Dict % charstringsoffset - the offset of the CharStrings offset % reference in the Top dict % privateoffset - the offset of the Private Dict offset % reference in the Top dict [ exch { 12 dict begin /font exch cvlit def currentdict end } forall ] /fonts exch def /cff exch cvlit def /f cff def /fpos 0 def % We need to pre-construct all the strings so that we know % the offsets to fill in. /names { [ fonts { /font get /FontName get } forall ] Index } collect def /sids 20 dict def /subrslength 0 def % only for estimating size /charslength 0 def /privatelength 0 def fonts { begin font /Private get /Subrs .knownget { { Index } collect } { <00 00> } ifelse /subrs exch def /subrslength subrslength subrs length add def %****** FOLLOWING IS WRONG, WRONG, WRONG ******% font /CharStrings get [ exch { exch pop } forall ] { Index } collect /chars exch def /charspos charslength def /charslength charslength chars length add def /subrsoffset null def font /Private get { privatekeyops Dict } collect /private exch def subrsoffset null ne { private subrsoffset private length 2 putoffset } if /privatepos privatelength def /privatelength privatelength private length add subrs length add def } forall % Estimate the size of a 0-based offset for the Top Dicts. /offsetsize subrslength charslength add privatelength add 60000 ge { 3 } { 2 } ifelse def fonts { begin /charstringsoffset null def /privateoffset null def /top { font topkeyops Dict } collect def end } forall /strings { sids StandardSIDs length idIndex } collect def % Now we can write the real file. % Header DEBUG { (header ) print fpos == } if <01 00 04 02> nextstring % Name Index DEBUG { (names ) print fpos == } if names nextstring % Top Dicts DEBUG { (tops ) print fpos == } if /charsbase fpos fonts { /top get length add } forall strings length add def /privatebase charsbase charslength add def fonts { begin top charstringsoffset charspos charsbase add offsetsize putoffset top privateoffset privatepos privatebase add offsetsize putoffset top nextstring end } forall % String Index DEBUG { (strings ) print fpos == } if strings nextstring % Charstrings Indexes DEBUG { (charstrings) print } if /charsbase fpos def fonts { DEBUG { ( ) print fpos =only } if /chars get nextstring } forall DEBUG { () = } if % Private Dicts & Local Subr Indexes DEBUG { (privates/subrs) print } if fonts { DEBUG { ( ) print fpos =only } if dup /private get nextstring DEBUG { ( ) print fpos =only } if /subrs get nextstring } forall DEBUG { () = } if DEBUG { (end ) print fpos = flush } if end } def % ---------------- Wrap up ---------------- % currentdict readonly end /writecffdict exch def /writecff { writecffdict begin writecff end } def .