home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / sharewar / dos / inne / gs300ini / font2c.ps < prev    next >
Encoding:
Text File  |  1994-08-02  |  15.5 KB  |  552 lines

  1. %    Copyright (C) 1992, 1993, 1994 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % font2c.ps
  16. % Write out a PostScript Type 0 or Type 1 font as C code
  17. % that can be linked with the interpreter.
  18. % This even works on protected fonts, if you use the -dWRITESYSTEMDICT
  19. % switch in the command line.  The code is reentrant and has no
  20. % external references, so it can be shared.
  21.  
  22. % Define the maximum string length that all compilers will accept.
  23. % This must be approximately
  24. %    min(max line length, max string literal length) / 4 - 5.
  25.  
  26. /font2cdict 100 dict dup begin
  27.  
  28. /max_wcs 50 def
  29.  
  30. % ------ Protection utilities ------ %
  31.  
  32. % Protection values are represented by a mask:
  33. /a_noaccess 0 def
  34. /a_executeonly 1 def
  35. /a_readonly 3 def
  36. /a_all 7 def
  37. /prot_names
  38.  [ (0) (a_execute) null (a_readonly) null null null (a_all)
  39.  ] def
  40. /prot_opers
  41.  [ {noaccess} {executeonly} {} {readonly} {} {} {} {}
  42.  ] def
  43.  
  44. % Get the protection of an object.
  45.    /getpa
  46.     { dup wcheck
  47.        { pop a_all }
  48.        {    % Check for executeonly or noaccess objects in protected.
  49.          dup protected exch known
  50.       { protected exch get }
  51.       { pop a_readonly }
  52.      ifelse
  53.        }
  54.       ifelse
  55.     } bind def
  56.  
  57. % Get the protection appropriate for (all the) values in a dictionary.
  58.    /getva
  59.     { a_noaccess exch
  60.        { exch pop
  61.          dup type dup /stringtype eq 1 index /arraytype eq or
  62.      exch /packedarraytype eq or
  63.       { getpa a_readonly and or }
  64.       { pop pop a_all exit }
  65.      ifelse
  66.        }
  67.       forall
  68.     } bind def
  69.  
  70. % Keep track of executeonly and noaccess objects,
  71. % but don't let the protection actually take effect.
  72. .currentglobal
  73. false .setglobal    % so protected can reference local objs
  74. /protected        % do first so // will work
  75.   systemdict wcheck { 1500 dict } { 1 dict } ifelse
  76. def
  77. systemdict wcheck not
  78.  { (Warning: you will not be able to convert protected fonts.\n) print
  79.    (If you need to convert a protected font, please\n) print
  80.    (restart the program and specify the -dWRITESYSTEMDICT switch.\n) print
  81.    flush
  82.    (%end) .skipeof
  83.  }
  84. if
  85. userdict begin
  86.   /executeonly
  87.    { dup //protected exch //a_executeonly put readonly
  88.    } bind def
  89.   /noaccess
  90.    { dup //protected exch //a_noaccess put readonly
  91.    } bind def
  92. end
  93. true .setglobal
  94. systemdict begin
  95.   /executeonly
  96.    { userdict /executeonly get exec
  97.    } bind odef
  98.   /noaccess
  99.    { userdict /noaccess get exec
  100.    } bind odef
  101. end
  102. %end
  103. .setglobal
  104.  
  105. % ------ Output utilities ------ %
  106.  
  107. % By convention, the output file is named cfile.
  108.  
  109. % Define some utilities for writing the output file.
  110.    /wtstring 100 string def
  111.    /wb {cfile exch write} bind def
  112.    /ws {cfile exch writestring} bind def
  113.    /wl {ws (\n) ws} bind def
  114.    /wt {wtstring cvs ws} bind def
  115.  
  116. % Write a C string.  Some compilers have unreasonably small limits on
  117. % the length of a string literal or the length of a line, so every place
  118. % that uses wcs must either know that the string is short,
  119. % or be prepared to use wcca instead.
  120.    /wbx
  121.     { 8#1000 add 8 (0000) cvrs dup 0 (\\) 0 get put ws
  122.     } bind def
  123.    /wcst
  124.     [
  125.       32 { /wbx load } repeat
  126.       95 { /wb load } repeat
  127.       129 { /wbx load } repeat
  128.     ] def
  129.    ("\\) { wcst exch { (\\) ws wb } put } forall
  130.    /wcs
  131.     { (") ws { dup wcst exch get exec } forall (") ws
  132.     } bind def
  133.    /can_wcs    % Test if can use wcs
  134.     { length max_wcs le
  135.     } bind def
  136.    /wncs    % name -> C string
  137.     { wtstring cvs wcs
  138.     } bind def
  139. % Write a C string as an array of character values.
  140. % We only need this because of line and literal length limitations.
  141.    /wca        % string prefix suffix ->
  142.     { 0 4 -2 roll exch
  143.        { exch ws
  144.          exch dup 19 ge { () wl pop 0 } if 1 add
  145.      exch wt (,)
  146.        } forall
  147.       pop pop ws
  148.     } bind def
  149.    /wcca
  150.     { ({\n) (}) wca
  151.     } bind def
  152.  
  153. % Write object protection attributes.  Note that dictionaries are
  154. % the only objects that can be writable.
  155.    /wpa
  156.     { dup xcheck { (a_executable|) ws } if
  157.       dup type /dicttype eq { getpa } { getpa a_readonly and } ifelse
  158.       prot_names exch get ws
  159.     } bind def
  160.    /wva
  161.     { getva prot_names exch get ws
  162.     } bind def
  163.  
  164. % ------ Object writing ------ %
  165.  
  166.    /wnstring 128 string def
  167.  
  168. % Write a string/name or null as an element of a string/name/null array. */
  169.    /wsn
  170.     { dup null eq
  171.        { pop (\t255,255,) wl
  172.        }
  173.        { dup type /nametype eq { wnstring cvs } if
  174.          dup length 256 idiv wt (,) ws
  175.      dup length 256 mod wt
  176.      (,) (,\n) wca
  177.        }
  178.       ifelse
  179.     } bind def
  180. % Write a packed string/name/null array.
  181.    /wsna    % <name> <(string|name|null)*> wsna -
  182.     { (\tstatic const char ) ws exch wt ([] = {) wl
  183.       { wsn } forall
  184.       (\t0\n};) wl
  185.     } bind def
  186.  
  187.  
  188. % Write a named object.  Return true if this was possible.
  189. % Legal types are: boolean, integer, name, real, string,
  190. % array of (integer, integer+real, name, null+string).
  191. % All other objects are either handled specially or ignored.
  192.    /isall    % array proc -> bool
  193.     { true 3 -1 roll
  194.        { 2 index exec not { pop false exit } if }
  195.       forall exch pop
  196.     } bind def
  197.    /wott 8 dict dup begin
  198.       /arraytype
  199.        { woatt
  200.           { aload pop 2 index 2 index isall
  201.          { exch pop exec exit }
  202.          { pop pop }
  203.         ifelse
  204.       }
  205.      forall
  206.        } bind def
  207.       /booleantype
  208.        { { (\tmake_true\(&) } { (\tmake_false\(&) } ifelse ws
  209.          wt (\);) wl true
  210.        } bind def
  211.       /integertype
  212.        { (\tmake_int\(&) ws exch wt (, ) ws
  213.          wt (\);) wl true
  214.        } bind def
  215.       /nametype
  216.        { (\tcode = (*pprocs->name_create)\(&) ws exch wt
  217.          (, ) ws wnstring cvs wcs    % OK, names are short
  218.      (\);) wl
  219.      (\tif ( code < 0 ) return code;) wl
  220.      true
  221.        } bind def
  222.       /packedarraytype
  223.     /arraytype load def
  224.       /realtype
  225.        { (\tmake_real\(&) ws exch wt (, ) ws
  226.          wt (\);) wl true
  227.        } bind def
  228.       /stringtype
  229.        { ({\tstatic const char s_[] = ) ws
  230.          dup dup can_wcs { wcs } { wcca } ifelse
  231.      (;) wl
  232.      (\tmake_const_string\(&) ws exch wt
  233.      (, a_readonly, ) ws length wt (, (const byte *)s_\);) wl
  234.      (}) wl true
  235.        } bind def
  236.    end def
  237. % Write some other kind of object, if known.
  238.    /wother
  239.     { dup otherobjs exch known
  240.        { otherobjs exch get (\t) ws exch wt ( = ) ws wt (;) wl true }
  241.        { pop pop false }
  242.       ifelse
  243.     } bind def
  244. % Top-level procedure.
  245.    /wo        % name obj -> OK
  246.     { dup type wott exch .knownget { exec } { wother } ifelse
  247.     } bind def
  248.  
  249. % Write an array (called by wo).
  250.    /wnuma    % name array C_type type_v ->
  251.     { ({\tstatic const ref_\() ws exch ws
  252.       (\) a_[] = {) wl exch
  253.       dup length 0 eq
  254.        { (\t0) wl
  255.        }
  256.        { dup
  257.           { (\t) ws 2 index ws (\() ws wt (\),) wl
  258.       } forall
  259.        }
  260.       ifelse
  261.       (\t};) wl exch pop
  262.       (\tmake_array\(&) ws exch wt
  263.       (, a_foreign|) ws dup wpa (, ) ws length wt
  264.       (, (ref *)a_\);) wl (}) wl
  265.     } bind def
  266.    /woatt [
  267.     % Integers
  268.      { { type /integertype eq }
  269.        { (long) (integer_v) wnuma true }
  270.      }
  271.     % Integers + reals
  272.      { { type dup /integertype eq exch /realtype eq or }
  273.        { (float) (real_v) wnuma true }
  274.      }
  275.     % Strings + nulls
  276.      { { type dup /nulltype eq exch /stringtype eq or }
  277.        { ({) ws dup (sa_) exch wsna
  278.      exch (\tcode = (*pprocs->string_array_create)\(&) ws wt
  279.      (, sa_, ) ws dup length wt (, ) ws wpa (\);) wl
  280.      (\tif ( code < 0 ) return code;) wl
  281.      (}) wl true
  282.        }
  283.      }
  284.     % Names
  285.      { { type /nametype eq }
  286.        { ({) ws dup (na_) exch wsna
  287.      exch (\tcode = (*pprocs->name_array_create)\(&) ws wt
  288.      (, na_, ) ws length wt (\);) wl
  289.      (\tif ( code < 0 ) return code;) wl
  290.      (}) wl true
  291.        }
  292.      }
  293.     % Default
  294.      { { pop true }
  295.        { wother }
  296.      }
  297.    ] def
  298.  
  299. % Write a named dictionary.  We assume the ref is already declared.
  300.    /wd        % <name> <dict> <extra> wd -
  301.     { 3 1 roll
  302.       ({) ws
  303.       (\tref v_[) ws dup length wt (];) wl
  304.       dup [ exch
  305.        { counttomark 2 sub wtstring cvs
  306.          (v_[) exch concatstrings (]) concatstrings exch wo not
  307.           { (Skipping ) print ==only (....\n) print }
  308.      if
  309.        } forall
  310.       ]
  311.         % Stack: array of keys (names)
  312.       ({) ws dup (str_keys_) exch wsna
  313.       (\tstatic const cfont_dict_keys keys_ =) wl
  314.       (\t { 0, 0, ) ws length wt (, ) ws 3 -1 roll wt (, ) ws
  315.       dup wpa (, ) ws dup wva ( };) wl pop
  316.       (\tcode = \(*pprocs->ref_dict_create\)\(&) ws wt
  317.       (, &keys_, str_keys_, &v_[0]\);) wl
  318.       (\tif (code < 0) return code;) wl
  319.       (}) wl
  320.       (}) wl
  321.     } bind def
  322.  
  323. % Write a character dictionary.
  324. % We save a lot of space by abbreviating keys which appear in
  325. % StandardEncoding or ISOLatin1Encoding.
  326.    /wcd        % namestring createtype dict valuetype writevalueproc ->
  327.     {    % Keys present in StandardEncoding or ISOLatin1Encoding:
  328.       2 index
  329.       (static const charindex enc_keys_[] = {) wl
  330.       [ exch 0 exch
  331.        { pop decoding 1 index known
  332.           { decoding exch get ({) ws dup -8 bitshift wt
  333.         (,) ws 255 and wt (}, ) ws
  334.         1 add dup 5 mod 0 eq { (\n) ws } if
  335.       }
  336.       { exch }
  337.      ifelse
  338.        }
  339.       forall pop
  340.       ]
  341.       ({0,0}\n};) wl
  342.     % Other keys:
  343.       (str_keys_) exch wsna
  344.     % Values, with those corresponding to stdkeys first:
  345.       (static const ) ws 1 index ws
  346.       ( values_[] = {) wl
  347.       2 index
  348.        { decoding 2 index known
  349.           { exch pop 1 index exec }
  350.       { pop pop }
  351.      ifelse
  352.        }
  353.       forall
  354.       2 index
  355.        { decoding 2 index known
  356.           { pop pop }
  357.       { exch pop 1 index exec }
  358.      ifelse
  359.        }
  360.       forall
  361.       (\t0\n};) wl
  362.     % Actual creation code:
  363.       (static const cfont_dict_keys keys_ = {) wl
  364.       (\tenc_keys_, countof\(enc_keys_\) - 1,) wl
  365.       (\t) ws 2 index length wt ( - \(countof\(enc_keys_\) - 1\), 0, ) ws
  366.       pop pop
  367.       dup wpa (, ) ws wva () wl
  368.       (};) wl
  369.       (\tcode = \(*pprocs->) ws ws (_dict_create\)\(&) ws ws
  370.       (, &keys_, str_keys_, &values_[0]\);) wl
  371.       (\tif ( code < 0 ) return code;) wl
  372.     } bind def
  373.  
  374. % ------ Writers for special objects ------ %
  375.  
  376. /writespecial 10 dict dup begin
  377.  
  378.    /FontInfo { 0 wd } def
  379.  
  380.    /Private { 0 wd } def
  381.  
  382.    /CharStrings
  383.     { ({) wl
  384.       (CharStrings) (string) 3 -1 roll (char) { wsn } wcd pop
  385.       (}) wl
  386.     } bind def
  387.  
  388.    /Metrics
  389.     { ({) wl
  390.       exch (num) 3 -1 roll (float) { (\t) ws wtstring cvs ws (,) wl } wcd
  391.       (}) wl
  392.     } bind def
  393.  
  394.    /Metrics2 /Metrics load def
  395.  
  396.    /CDevProc pop    % NOT IMPLEMENTED YET
  397.  
  398.    /FDepVector pop    % (converted to a list of font names)
  399.  
  400. end def
  401.  
  402. % ------ The main program ------ %
  403.  
  404. % Construct an inverse dictionary of encodings.
  405. [ /StandardEncoding /ISOLatin1Encoding
  406.   /SymbolEncoding /DingbatsEncoding
  407.   /KanjiSubEncoding
  408. ]
  409. dup length dict begin
  410.  { mark exch dup { .findencoding exch def } stopped cleartomark
  411.  } forall
  412. currentdict end /encodingnames exch def
  413.  
  414. % Invert the StandardEncoding and ISOLatin1Encoding vectors.
  415. 512 dict begin
  416.   0 1 255 { dup ISOLatin1Encoding exch get exch 256 add def } for
  417.   0 1 255 { dup StandardEncoding exch get exch def } for
  418. currentdict end /decoding exch def
  419.  
  420. /writefont        % cfilename procname -> [writes the current font]
  421.  { (gsf_) exch concatstrings
  422.      /fontprocname exch def
  423.    /cfname exch def
  424.    /cfile cfname (w) file def
  425.  
  426. % Remove unwanted keys from the font.
  427.    currentfont dup length dict begin { def } forall
  428.     { /FID /MIDVector /CurMID } { currentdict exch undef } forall
  429.    /Font currentdict end def
  430.  
  431. % Replace the FDepVector with a list of font names.
  432.    Font /FDepVector .knownget
  433.     { [ exch { /FontName get } forall ]
  434.       Font /FDepVector 3 -1 roll put
  435.     }
  436.    if
  437.  
  438. % Find all the special objects we know about.
  439. % wo uses this to write out references to otherwise intractable objects.
  440.    /otherobjs writespecial length dict dup begin
  441.      writespecial
  442.       { pop Font 1 index .knownget { exch def } { pop } ifelse
  443.       }
  444.      forall
  445.    end def
  446.  
  447. % Define a dummy FontInfo, in case the font doesn't have one.
  448.    /FontInfo 0 dict def
  449.  
  450. % Write out the boilerplate.
  451.    Font begin
  452.    (/* Portions of this file are subject to the following notice: */) wl
  453.    (/*) wl
  454.    ( * ) ws systemdict /copyright get ws
  455.    ( * All rights reserved.) wl
  456.    ( */) wl
  457.    FontInfo /Notice known
  458.     { (/* Portions of this file are also subject to the following notice: */) wl
  459.       (/****************************************************************) wl
  460.       FontInfo /Notice get wl
  461.       ( ****************************************************************/) wl
  462.     } if
  463.    () wl
  464.    (/* ) ws cfname ws ( */) wl
  465.    (/* This file was created by the ) ws product ws ( font2c utility. */) wl
  466.    () wl
  467.    (#include "ccfont.h") wl
  468.    () wl
  469.  
  470. % Write the procedure prologue.
  471.    (#ifdef __PROTOTYPES__) wl
  472.    (int huge) wl
  473.    fontprocname ws ((const cfont_procs *pprocs, ref *pfont)) wl
  474.    (#else) wl
  475.    (int huge) wl
  476.    fontprocname ws ((pprocs, pfont) const cfont_procs *pprocs; ref *pfont;) wl
  477.    (#endif) wl
  478.    ({\tint code;) wl
  479.    (\tref Font;) wl
  480.    otherobjs
  481.     { exch pop (\tref ) ws wt (;) wl }
  482.    forall
  483.  
  484. % Write out the special objects.
  485.    otherobjs
  486.     { exch writespecial 2 index get exec
  487.     }
  488.    forall
  489.  
  490. % Write out the main font dictionary.
  491. % If possible, substitute the encoding name for the encoding;
  492. % PostScript code will fix this up.
  493.     { /Encoding /PrefEnc }
  494.     { Font 1 index .knownget
  495.        { encodingnames exch .knownget { def } { pop } ifelse }
  496.        { pop }
  497.       ifelse
  498.     }
  499.    forall
  500.    (Font) Font FontType 0 eq { 5 } { 1 } ifelse wd
  501.  
  502. % Finish the procedural initialization code.
  503.    (\t*pfont = Font;) wl
  504.    (\treturn 0;) wl
  505.    (}) wl
  506.    end                % Font
  507.  
  508.    cfile closefile
  509.  
  510.  } bind def
  511.  
  512. end def            % font2cdict
  513.  
  514. % Compute the procedure name from the font name.
  515. /makefontprocname    % fontname -> procname
  516.  { =string cvs
  517.    dup length 1 sub -1 0
  518.     { dup =string exch get 45 eq { =string exch 95 put } { pop } ifelse
  519.     }
  520.    for 
  521.  } def
  522.  
  523. /writefont { font2cdict begin writefont end } def
  524.  
  525. % If the program was invoked from the command line, run it now.
  526. [ shellarguments
  527.  { counttomark dup 2 eq exch 3 eq or
  528.     { counttomark -1 roll cvn
  529.       (Converting ) print dup =only ( font.\n) print flush
  530.       dup FontDirectory exch known { dup FontDirectory exch undef } if
  531.       findfont setfont
  532.       (FontName is ) print currentfont /FontName get ==only (.\n) print flush
  533.       counttomark 1 eq
  534.        {    % Construct the procedure name from the file name.
  535.          currentfont /FontName get makefontprocname
  536.        }
  537.       if
  538.       writefont
  539.       (Done.\n) print flush
  540.     }
  541.     { cleartomark
  542.       (Usage: font2c fontname cfilename.c [shortname]\n) print
  543.       ( e.g.: font2c Courier cour.c\n) print flush
  544.       mark
  545.     }
  546.    ifelse
  547.  }
  548. if pop
  549.