home *** CD-ROM | disk | FTP | other *** search
- % Copyright (C) 1992, 1993 Aladdin Enterprises. All rights reserved.
- %
- % This file is part of Ghostscript.
- %
- % Ghostscript is distributed in the hope that it will be useful, but
- % WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- % to anyone for the consequences of using it or for whether it serves any
- % particular purpose or works at all, unless he says so in writing. Refer
- % to the Ghostscript General Public License for full details.
- %
- % Everyone is granted permission to copy, modify and redistribute
- % Ghostscript, but only under the conditions described in the Ghostscript
- % General Public License. A copy of this license is supposed to have been
- % given to you along with Ghostscript so you can know your rights and
- % responsibilities. It should be in a file named COPYING. Among other
- % things, the copyright notice and this notice must be preserved on all
- % copies.
-
- % font2c.ps
- % Write out a Type 1 font as C code that can be linked with Ghostscript.
- % This even works on protected fonts, if you use the -dWRITESYSTEMDICT
- % switch in the command line. The code is reentrant and has no
- % external references, so it can be shared.
-
- % Define the maximum string length that will get by the compiler.
- % This must be approximately
- % min(max line length, max string literal length) / 4 - 5.
-
- /max_wcs 50 def
-
- % ------ Protection utilities ------ %
-
- % Protection values are represented by a mask:
- /a_noaccess 0 def
- /a_executeonly 1 def
- /a_readonly 3 def
- /a_all 7 def
- /prot_names
- [ (0) (a_execute) null (a_readonly) null null null (a_all)
- ] def
- /prot_opers
- [ {noaccess} {executeonly} {} {readonly} {} {} {} {}
- ] def
-
- % Get the protection of an object.
- /getpa
- { dup wcheck
- { pop a_all }
- { % Check for executeonly or noaccess objects in protected.
- dup protected exch known
- { protected exch get }
- { pop a_readonly }
- ifelse
- }
- ifelse
- } bind def
-
- % Get the protection appropriate for (all the) values in a dictionary.
- /getva
- { a_noaccess exch
- { exch pop
- dup type dup /stringtype eq exch /arraytype eq or
- { getpa a_readonly and or }
- { pop pop a_all exit }
- ifelse
- }
- forall
- } bind def
-
- % Keep track of executeonly and noaccess objects,
- % but don't let the protection actually take effect.
- /protected % do first so // will work
- systemdict wcheck { 1500 dict } { 1 dict } ifelse
- def
- systemdict wcheck
- { systemdict begin
- /executeonly
- { dup //protected exch a_executeonly put readonly
- } bind odef
- /noaccess
- { dup //protected exch a_noaccess put readonly
- } bind odef
- end
- }
- { (Warning: you will not be able to convert protected fonts.\n) print
- (If you need to convert a protected font,\n) print
- (please restart Ghostscript with the -dWRITESYSTEMDICT switch.\n) print
- flush
- }
- ifelse
-
- % ------ Output utilities ------ %
-
- % By convention, the output file is named cfile.
-
- % Define some utilities for writing the output file.
- /wtstring 100 string def
- /wb {cfile exch write} bind def
- /ws {cfile exch writestring} bind def
- /wl {ws (\n) ws} bind def
- /wt {wtstring cvs ws} bind def
-
- % Write a C string. Some compilers have unreasonably small limits on
- % the length of a string literal or the length of a line, so every place
- % that uses wcs must either know that the string is short,
- % or be prepared to use wcca instead.
- /wbx
- { 8#1000 add 8 (0000) cvrs dup 0 (\\) 0 get put ws
- } bind def
- /wcst
- [
- 32 { /wbx load } repeat
- 95 { /wb load } repeat
- 129 { /wbx load } repeat
- ] def
- ("\\) { wcst exch { (\\) ws wb } put } forall
- /wcs
- { (") ws { dup wcst exch get exec } forall (") ws
- } bind def
- /can_wcs % Test if can use wcs
- { length max_wcs le
- } bind def
- /wncs % name -> C string
- { wtstring cvs wcs
- } bind def
- % Write a C string as an array of character values.
- % We only need this because of line and literal length limitations.
- /wca % string prefix suffix ->
- { 0 4 -2 roll exch
- { exch ws
- exch dup 19 ge { () wl pop 0 } if 1 add
- exch wt (,)
- } forall
- pop pop ws
- } bind def
- /wcca
- { ({\n) (}) wca
- } bind def
-
- % Write object protection attributes. Note that dictionaries are
- % the only objects that can be writable.
- /wpa
- { dup xcheck { (a_executable+) ws } if
- dup type /dicttype eq { getpa } { getpa a_readonly and } ifelse
- prot_names exch get ws
- } bind def
- /wva
- { getva prot_names exch get ws
- } bind def
-
- % ------ Object writing ------ %
-
- /wnstring 128 string def
-
- % Write a string/name or null as an element of a string/name/null array. */
- /wsn
- { dup null eq
- { pop (\t255,255,) wl
- }
- { dup type /nametype eq { wnstring cvs } if
- dup length 256 idiv wt (,) ws
- dup length 256 mod wt
- (,) (,\n) wca
- }
- ifelse
- } bind def
- % Write a packed string/name/null array.
- /wsna % name (string/name/null)* ->
- { (\tstatic const char ) ws exch wt ([] = {) wl
- { wsn } forall
- (\t0\n};) wl
- } bind def
-
-
- % Write a named object. Return true if this was possible.
- % Legal types are: boolean, integer, name, real, string,
- % array of (integer, integer+real, name, null+string).
- % Dictionaries are handled specially. Other types are ignored.
- /isall % array proc -> bool
- { true 3 -1 roll
- { 2 index exec not { pop false exit } if }
- forall exch pop
- } bind def
- /wott 7 dict dup begin
- /arraytype
- { woatt
- { aload pop 2 index 2 index isall
- { exch pop exec exit }
- { pop pop }
- ifelse
- }
- forall
- } bind def
- /booleantype
- { { (\tmake_true\(&) } { (\tmake_false\(&) } ifelse ws
- wt (\);) wl true
- } bind def
- /dicttype
- { dup alldicts exch known
- { alldicts exch get (\t) ws exch wt ( = ) ws wt (;) wl true }
- { pop pop false }
- ifelse
- } bind def
- /integertype
- { (\tmake_int\(&) ws exch wt (, ) ws
- wt (\);) wl true
- } bind def
- /nametype
- { (\tcode = (*pprocs->name_create)\(&) ws exch wt
- (, ) ws wnstring cvs wcs % OK, names are short
- (\);) wl
- (\tif ( code < 0 ) return code;) wl
- true
- } bind def
- /realtype
- { (\tmake_real\(&) ws exch wt (, ) ws
- wt (\);) wl true
- } bind def
- /stringtype
- { ({\tstatic const char s_[] = ) ws
- dup dup can_wcs { wcs } { wcca } ifelse
- (;) wl
- (\tmake_const_string\(&) ws exch wt
- (, a_readonly, ) ws length wt (, (const byte *)s_\);) wl
- (}) wl true
- } bind def
- end def
- /wo % name obj -> OK
- { dup type wott exch known
- { dup type wott exch get exec }
- { pop pop false }
- ifelse
- } bind def
-
- % Write an array (called by wo).
- /wnuma % name array C_type type_v ->
- { ({\tstatic const ref_\() ws exch ws
- (\) a_[] = {) wl exch
- dup length 0 eq
- { (\t0) wl
- }
- { dup
- { (\t) ws 2 index ws (\() ws wt (\),) wl
- } forall
- }
- ifelse
- (\t};) wl exch pop
- (\tmake_array\(&) ws exch wt
- (, ) ws dup wpa (, ) ws length wt
- (, (ref *)a_\);) wl (}) wl
- } bind def
- /woatt [
- % Integers
- { { type /integertype eq }
- { (long) (integer_v) wnuma true }
- }
- % Integers + reals
- { { type dup /integertype eq exch /realtype eq or }
- { (float) (real_v) wnuma true }
- }
- % Strings + nulls
- { { type dup /nulltype eq exch /stringtype eq or }
- { ({) ws dup (sa_) exch wsna
- exch (\tcode = (*pprocs->string_array_create)\(&) ws wt
- (, sa_, ) ws dup length wt (, ) ws wpa (\);) wl
- (\tif ( code < 0 ) return code;) wl
- (}) wl true
- }
- }
- % Names
- { { type /nametype eq }
- { ({) ws dup (na_) exch wsna
- exch (\tcode = (*pprocs->name_array_create)\(&) ws wt
- (, na_, ) ws length wt (\);) wl
- (\tif ( code < 0 ) return code;) wl
- (}) wl true
- }
- }
- % Default
- { { pop true }
- { pop pop false }
- }
- ] def
-
- % Write a named dictionary. We assume the ref is already declared.
- /wd % name dict
- { ({) ws
- (\tref v_[) ws dup length wt (];) wl
- dup [ exch
- { counttomark 2 sub wtstring cvs
- (v_[) exch concatstrings (]) concatstrings exch wo not
- { pop }
- if
- } forall
- ]
- % stack: array of keys (names)
- ({) ws dup (str_keys_) exch wsna
- (\tstatic const cfont_dict_keys keys_ =) wl
- (\t { 0, 0, ) ws length wt (, 1, ) ws
- dup wpa (, ) ws dup wva ( };) wl
- (\tcode = \(*pprocs->ref_dict_create\)\(&) ws 1 index wt
- (, &keys_, str_keys_, &v_[0]\);) wl
- (\tif (code < 0) return code;) wl
- pop pop
- (}) wl
- (}) wl
- } bind def
-
- % Write a character dictionary.
- % We save a lot of space by abbreviating keys which appear in
- % StandardEncoding or ISOLatin1Encoding.
- /wcd % namestring createtype dict valuetype writevalueproc ->
- { % Keys present in StandardEncoding or ISOLatin1Encoding
- 2 index
- (static const charindex enc_keys_[] = {) wl
- [ exch 0 exch
- { pop decoding 1 index known
- { decoding exch get ({) ws dup -8 bitshift wt
- (,) ws 255 and wt (}, ) ws
- 1 add dup 5 mod 0 eq { (\n) ws } if
- }
- { exch }
- ifelse
- }
- forall pop
- ]
- ({0,0}\n};) wl
- % Other keys
- (str_keys_) exch wsna
- % Values, with those corresponding to stdkeys first.
- (static const ) ws 1 index ws
- ( values_[] = {) wl
- 2 index
- { decoding 2 index known
- { exch pop 1 index exec }
- { pop pop }
- ifelse
- }
- forall
- 2 index
- { decoding 2 index known
- { pop pop }
- { exch pop 1 index exec }
- ifelse
- }
- forall
- (\t0\n};) wl
- % Actual creation code
- (static const cfont_dict_keys keys_ = {) wl
- (\tenc_keys_, countof\(enc_keys_\) - 1,) wl
- (\t) ws 2 index length wt ( - \(countof\(enc_keys_\) - 1\), 0, ) ws
- pop pop
- dup wpa (, ) ws wva () wl
- (};) wl
- (\tcode = \(*pprocs->) ws ws (_dict_create\)\(&) ws ws
- (, &keys_, str_keys_, &values_[0]\);) wl
- (\tif ( code < 0 ) return code;) wl
- } bind def
-
- % ------ The main program ------ %
-
- % Construct an inverse dictionary of encodings.
- 4 dict begin
- StandardEncoding (StandardEncoding) def
- ISOLatin1Encoding (ISOLatin1Encoding) def
- SymbolEncoding (SymbolEncoding) def
- DingbatsEncoding (DingbatsEncoding) def
- currentdict end /encodingnames exch def
-
- % Invert the StandardEncoding and ISOLatin1Encoding vector.
- 512 dict begin
- 0 1 255 { dup ISOLatin1Encoding exch get exch 256 add def } for
- 0 1 255 { dup StandardEncoding exch get exch def } for
- currentdict end /decoding exch def
-
- /makefontprocname % fontname -> procname
- { wtstring cvs
- dup length 1 sub -1 0
- { dup wtstring exch get 45 eq { wtstring exch 95 put } { pop } ifelse
- }
- for
- } def
-
- /writefont % cfilename procname -> [writes the current font]
- { (gsf_) exch concatstrings
- /fontprocname exch def
- /cfname exch def
- /cfile cfname (w) file def
- /Font currentfont def
- Font /CharStrings get length dict
- /charmap exch def
-
- % Define all the dictionaries we know about.
- % wo uses this when writing out dictionaries.
- /alldicts 10 dict def
- alldicts begin
- Font /Font def
- { /FontInfo /CharStrings /Private }
- { dup Font exch get exch def }
- forall
- Font /Metrics known { Font /Metrics get /Metrics def } if
- end
-
- % Write out the boilerplate.
- Font begin
- (/* Portions of this file are) wl
- systemdict /copyright get ws
- (All rights reserved.) wl
- (*/) wl
- FontInfo /Notice known
- { (/* Portions of this file are also subject to the following notice: */) wl
- (/****************************************************************) wl
- FontInfo /Notice get wl
- ( ****************************************************************/) wl
- } if
- () wl
- (/* ) ws cfname ws ( */) wl
- (/* This file was created by the Ghostscript font2c utility. */) wl
- () wl
- (#include "std.h") wl
- (#include "iref.h") wl
- (#include "store.h") wl
- (#include "ccfont.h") wl
- () wl
-
- % Write the procedure prologue.
- (#ifdef __PROTOTYPES__) wl
- (int huge) wl
- fontprocname ws ((const cfont_procs *pprocs, ref *pfont)) wl
- (#else) wl
- (int huge) wl
- fontprocname ws ((pprocs, pfont) const cfont_procs *pprocs; ref *pfont;) wl
- (#endif) wl
- ({\tint code;) wl
- alldicts
- { exch pop (\tref ) ws wt (;) wl }
- forall
-
- % Write out the FontInfo.
- (FontInfo) FontInfo wd
-
- % Write out the CharStrings.
- ({) wl
- (CharStrings) (string) CharStrings (char) { wsn } wcd
- (}) wl
-
- % Write out the Metrics.
- Font /Metrics known
- { ({) wl
- (Metrics) (num) Metrics (float) { (\t) ws wtstring cvs ws (,) wl } wcd
- (}) wl
- }
- if
-
- % Write out the Private dictionary.
- (Private) Private wd
-
- % Write out the main font dictionary.
- % If possible, substitute the encoding name for the encoding;
- % PostScript code will fix this up.
- Font dup length dict copy
- encodingnames Encoding known
- { dup /Encoding encodingnames Encoding get put
- }
- if
- (Font) exch wd
-
- % Finish the procedural initialization code.
- (\t*pfont = Font;) wl
- (\treturn 0;) wl
- (}) wl
- end
-
- cfile closefile
-
- } bind def
-
- % If the program was invoked from the command line, run it now.
- [ shellarguments
- { counttomark dup 2 eq exch 3 eq or
- { counttomark -1 roll cvn
- (Converting ) print dup =only ( font.\n) print flush
- dup FontDirectory exch known { dup FontDirectory exch undef } if
- findfont setfont
- (FontName is ) print currentfont /FontName get ==only (.\n) print flush
- counttomark 1 eq
- { % Construct the procedure name from the file name.
- currentfont /FontName get makefontprocname
- }
- if
- writefont
- }
- { cleartomark
- (Usage: font2c fontname cfilename.c [shortname]\n) print
- ( e.g.: font2c Courier cour.c\n) print flush
- mark
- }
- ifelse
- }
- if pop
-