% Copyright (C) 1992 Aladdin Enterprises. All rights reserved.
% Distributed by Free Software Foundation, Inc.
% 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
% 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.
% 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.
% ------ Protection utilities ------ %
% Protection values are represented by a mask:
[ (0) (a_execute) null (a_readonly) null null null (a_all)
[ {noaccess} {executeonly} {} {readonly} {} {} {} {}
% Get the protection of an object.
{ % Check for executeonly or noaccess objects in protected.
% Get the protection appropriate for (all the) values in a dictionary.
dup type dup /stringtype eq exch /arraytype eq or
% Keep track of executeonly and noaccess objects,
% but don't let the protection actually take effect.
{ /protected 1500 dict def }
ifelse % do first so // will work
{ dup //protected exch a_executeonly put readonly
{ dup //protected exch a_noaccess put readonly
{ (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
% ------ Output utilities ------ %
% By convention, the output file is named cfile.
% Define some utilities for writing the output file.
/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 or wcsl must either believe that the string is short,
% or be prepared to use wcca instead.
{ 8#1000 add 8 (0000) cvrs dup 0 (\\) 0 get put ws
/wbx load 31 { dup } repeat
/wb load 94 { dup } repeat
/wbx load 128 { dup } repeat
("\\) { wcst exch { (\\) ws wb } put } forall
{ (") ws { dup wcst exch get exec } forall (") ws
/wcsl % Write C string with length
{ ({) ws dup length wt (,) ws wcs (}) ws
/can_wcs % Test if can use wcs
% Write a C string as an array of character values.
% We only need this because of line and literal length limitations.
exch dup 19 ge { () wl pop 0 } if 1 add
% Write object protection attributes.
{ dup xcheck { (a_executable+) ws } if
getpa prot_names exch get ws
{ getva prot_names exch get ws
% Write a named object. Return true if this was possible.
% Legal types are: boolean, integer, name, real, string,
% array of (integer, integer+real, null+string).
% Dictionaries are handled specially. Other types are ignored.
/isall % array proc -> bool
{ 2 index exec not { pop false exit } if }
/wta % name wproc array ->
dup length 0 eq { pop {0} } if
2 index wt (_array[] = {\n) exch
forall pop pop (\n};\nstatic ref_(ref *) ) ws
dup wt ( = array_v\() ws 1 index length wt (, ) ws
wt (_array, ) ws wpa (\);) wl
{ { type /integertype eq }
{ (static ref_(long) ) ws { (integer_v\() ws wt } exch wta true }
{ { type dup /integertype eq exch /realtype eq or }
{ (static ref_(float) ) ws { (real_v\() ws wt } exch wta true }
/a_name null def % predefine so we can use store, not def
{ { type dup /nulltype eq exch /stringtype eq or }
{ % Write the strings first with wcca
[ 0 1 a_body length 1 sub
{ dup a_body exch get dup null eq
{ exch wtstring cvs (_) concatstrings
a_name wtstring cvs exch concatstrings
(static char ) ws dup ws ([] = ) ws exch wcca (;) wl
% Make the protections match
prot_opers a_body getpa get exec
% Now write the array itself
(static ref_(char *) ) ws
{ (string_v\(sizeof\() ws dup ws (\),) ws ws }
{ aload pop 2 index 2 index isall
{ exch (static const ref_(ushort) ) ws wt ( = boolean_v\() ws
{ (1) } { (0) } ifelse ws (\);) wl true
{ pop alldictdict exch known
{ exch (static const ref_(long) ) ws wt ( = integer_v\() ws
{ exch (static const ref_(const char *) ) ws wt ( = name_v\() ws
wnstring cvs dup length wt (,) ws wcs % OK, names are short
{ exch (static const ref_(float) ) ws wt ( = real_v\() ws
{ exch (static const ref_(const char *) ) ws wt ( = string_v\() ws
dup length wt (,) ws wcs (\);) wl true
{ (static char ) ws 1 index wt (_[] = ) ws wcca (;) wl
dup dup (static const ref_(const char *) ) ws wt
( = string_v\(sizeof\() ws wt (_\),) ws wt (_\);) wl true
{ dup type wott exch known
{ dup type wott exch get exec }
% Write a named dictionary. We assume the ref is already declared.
dup (static const char _ds *str_keys_[] = {) wl
{ wtstring cvs wcs % OK, key names are short
(static const ref _ds *values_[] = {\n) exch
{ exch ws ((const ref _ds *)&) ws wt (,\n)
(\tstatic const cfont_dict_keys keys_ =) wl
(\t { 0, 0, str_keys_, countof\(str_keys_\) - 1, 1, ) ws
dup wpa (, ) ws wva ( };) wl
(\tcode = cfont_ref_dict_create\(&) ws wt
(, &keys_, &values_[0]\);) wl
(\tif (code < 0) return code;) wl
% 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
(static const charindex enc_keys_[] = {) wl
{ 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
(static const char _ds *str_keys_[] = {) wl
{ pop decoding 1 index known
{ (\t) ws wtstring cvs wcs % OK, key names are short
% Values, with those corresponding to stdkeys first.
(static const ) ws 1 index ws
{ exch pop exch ws (\t) ws 1 index exec (,\n) }
{ exch pop exch ws (\t) ws 1 index exec (,\n) }
(static const cfont_dict_keys keys_ = {) wl
(\tenc_keys_, countof\(enc_keys_\) - 1,) wl
(\tstr_keys_, countof\(str_keys_\) - 1, 0, ) ws
dup wpa (, ) ws wva () wl
(\tcode = cfont_) ws ws (_dict_create\(&) ws ws (, &keys_, &values_[0]\);) wl
(\tif ( code < 0 ) return code;) wl
% ------ The main program ------ %
% Construct an inverse dictionary of encodings.
StandardEncoding (StandardEncoding) def
ISOLatin1Encoding (ISOLatin1Encoding) def
SymbolEncoding (SymbolEncoding) def
currentdict end /encodingnames exch def
% Invert the StandardEncoding and ISOLatin1Encoding vector.
0 1 255 { dup ISOLatin1Encoding exch get exch 256 add def } bind for
0 1 255 { dup StandardEncoding exch get exch def } bind for
currentdict end /decoding exch def
/writefont % cfilename -> [writes the current font]
/cfile cfname (w) file def
Font /FontName get wtstring cvs
dup length 1 sub 0 exch 1 exch
{ dup wtstring exch get 45 eq { wtstring exch 95 put } { pop } ifelse
for (font_) exch concatstrings
Font /CharStrings get length dict
% Define all the dictionaries we know about.
% wo uses this when writing out dictionaries.
[ (Font) (FontInfo) (CharStrings) (Private)
encodingnames Font /Encoding get known not
{ % Make a fake entry for Encoding, for later
Font /Metrics known { (Metrics) } if
dup /alldictnames exch def
dup length 1 sub 1 exch getinterval % drop Font
dup length dict begin { dup def } forall
currentdict end /alldictdict exch def
% Write out the boilerplate.
(/* Copyright (C) 1992 Aladdin Enterprises. All rights reserved.) wl
( Distributed by Free Software Foundation, Inc.) wl
(This file is part of Ghostscript.) wl
(Ghostscript is distributed in the hope that it will be useful, but) wl
(WITHOUT ANY WARRANTY. No author or distributor accepts responsibility) wl
(to anyone for the consequences of using it or for whether it serves any) wl
(particular purpose or works at all, unless he says so in writing.) wl
(Refer to the Ghostscript General Public License for full details.) wl
(Everyone is granted permission to copy, modify and redistribute) wl
(Ghostscript, but only under the conditions described in the Ghostscript) wl
(General Public License. A copy of this license is supposed to have been) wl
(given to you along with Ghostscript so you can know your rights and) wl
(responsibilities. It should be in a file named COPYING. Among other) wl
(things, the copyright notice and this notice must be preserved on all) wl
(/* ) ws cfname ws ( */) wl
(/* This file was created by the Ghostscript font2c utility. */) wl
{ (/* Portions of this file are subject to the following notice: */) wl
(/****************************************************************) wl
( ****************************************************************/) wl
% Write the operator prologue.
(#ifdef __PROTOTYPES__) wl
fontproc ws ((os_ptr op)) wl
fontproc ws ((op) os_ptr op;) wl
{ (\tstatic ref ) ws ws (;) wl }
% Write out the FontInfo.
% Write out the CharStrings.
% We write the strings with wcca first, and save the mapping in a dictionary.
charmap 1 index 3 index put
(static const char cs) ws 1 index wt ([] = ) ws wcca (;) wl
(CharStrings) (string) CharStrings (charray)
{ ({sizeof\(cs) ws charmap exch get dup wt
(Metrics) (num) Metrics (float) { wtstring cvs ws } wcd
% Write out the Private dictionary.
% Write out the Encoding vector, if it isn't standard.
encodingnames Encoding known not
{ (\t{ static const char _ds *str_elts_[] = {\n)
{ exch ws wtstring cvs wcs % OK, character names are short
(\tcode = cfont_name_array_create\(&Encoding, str_elts_, countof\(str_elts_\)\);) wl
(\tif (code < 0) return code;) wl
% 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
{ % Force it to be treated like a known dictionary
% Finish the procedural initialization code.
% Write out the operator initialization table.
(\nop_def ) ws fontproc ws (_op_defs[] = {) wl
(\t{"0.font_) ws FontName wt (", ) ws fontproc ws (},) wl
% If the program was invoked from the command line, run it now.
dup FontDirectory exch known { dup FontDirectory exch undef } if
(Usage: font2c fontname cfilename.c\n) print
( e.g.: font2c Courier cour.c\n) print flush