home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / GhostScript / !GhostScr / 6_01 / lib / addxchar.ps < prev    next >
Text File  |  2000-03-09  |  10KB  |  360 lines

  1. %    Copyright (C) 1999 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. % $Id: addxchar.ps,v 1.1 2000/03/09 08:40:39 lpd Exp $
  16. % Add the Central European and other Adobe extended Latin characters to a
  17. % Type 1 font.
  18. % Requires -dWRITESYSTEMDICT to disable access protection.
  19.  
  20. (type1ops.ps) runlibfile
  21.  
  22. % ---------------- Utilities ---------------- %
  23.  
  24. /addce_dict 50 dict def
  25. addce_dict begin
  26.  
  27. % Define the added copyright notice.
  28. /addednotice (. Portions Copyright (C) 1999 Aladdin Enterprises.) def 
  29.  
  30. % Open a font for modification by removing the FID and changing the
  31. % FontName.  Removing UniqueID and XUID is not necessary, since we
  32. % will only be adding characters.
  33. /openfont {        % <name> <font> openfont <name> <font'>
  34.   dup length dict copy
  35.   dup /FID undef
  36.   dup /FontName 3 index put
  37. } def
  38.  
  39. % Do the equivalent of false charpath for a glyph.
  40. % This should really be an operator!
  41. /glyphpath {        % <glyph> glyphpath -
  42.   currentfont /Encoding get 0 3 -1 roll put
  43.   <00> false charpath
  44. } def
  45.  
  46. % Do the equivalent of charpath + pathbbox for a glyph.
  47. /glyphbbox {        % <glyph> glyphbbox <llx> <lly> <urx> <ury>
  48.     % We cache this value, because it's expensive to compute.
  49.   BBoxes 1 index .knownget {
  50.     exch pop
  51.   } {
  52.     gsave newpath 0 0 moveto dup glyphpath [pathbbox] grestore
  53.     BBoxes 3 -1 roll 2 index put
  54.   } ifelse aload pop
  55. } def
  56.  
  57. % Get the side bearing and width for a glyph.
  58. /glyphsbw {        % <glyph> glyphsbw <lsbx> <wx>
  59.     % We cache this value, because it's expensive to compute.
  60.   SBW 1 index .knownget {
  61.     exch pop
  62.   } {
  63.     dup glyphcs { dup /hsbw eq { pop exit } if } forall
  64.     2 array astore
  65.     SBW 3 -1 roll 2 index put
  66.   } ifelse aload pop
  67. } def
  68.  
  69. % Get the CharString for a glyph, as an array.
  70. /glyphcs {        % <glyph> glyphcs <array>
  71.   CharStrings exch get
  72.   4330 exch dup length string .type1decrypt exch pop
  73.   dup length lenIV sub lenIV exch getinterval
  74.   0 () /SubFileDecode filter [ exch charstack_read ]
  75. } def
  76.  
  77. % Find an occurrence of a value in an array.
  78. /asearch {        % <array> <value> asearch <index> true
  79.             % <array> <value> asearch false
  80.   false 0 4 2 roll exch {
  81.         % Stack: false index value element
  82.     2 copy eq { pop pop exch not exch dup exit } if
  83.     exch 1 add exch
  84.   } forall pop pop
  85. } def
  86.  
  87. % Convert an array back to a CharString.
  88. /csdef {        % <glyph> <array> csdef -
  89.   charproc_string
  90.   4330 exch dup .type1encrypt exch pop readonly
  91.   CharStrings 3 1 roll put
  92. } def
  93.  
  94. % Split an accented character name.
  95. /splitaccented {    % <Baccent> splitaccented <Baccent> <B> <accent>
  96.     dup =string cvs
  97.     dup 0 1 getinterval cvn
  98.     exch dup length 1 sub 1 exch getinterval cvn
  99. } def
  100.  
  101. % Begin the definition of a 'seac' character.
  102. % Defines accent, base, abox, bbox.
  103. % The initial dx lines up the origins of the base and the accent.
  104. /beginseac {        % <bchar> <achar> beginseac
  105.             %   -mark- <lsbx> <wx> /hsbw <asb> <dx>
  106.   /accent exch def /base exch def
  107.   /abox [accent glyphbbox] def
  108.   /bbox [base glyphbbox] def
  109.   [ base glyphsbw /hsbw accent glyphsbw pop
  110.   dup 4 index sub
  111. } def
  112.  
  113. % Center the accent over the base of a 'seac' character.
  114. /centeraccent {        % <dx> centeraccent <adx>
  115.   bbox 2 get bbox 0 get add 2 div
  116.   abox 2 get abox 0 get add 2 div
  117.   sub add
  118. } def
  119.  
  120. % Finish the definition of a 'seac' character.
  121. /finishseac {        % <charname> -mark- ... <adx> <ady> finishseac -
  122.   exch cvi exch cvi
  123.   charindex base get charindex accent get /seac ] csdef
  124. } def
  125.  
  126. % ---------------- Main program ---------------- %
  127.  
  128. % Define accented characters that can be made with seac,
  129. % with the accent centered over the character.
  130. /seacchars [
  131.   /Abreve /Amacron
  132.   /Cacute /Ccaron /Dcaron
  133.   /Ecaron /Edotaccent /Emacron
  134.   /Gbreve
  135.   /Idotaccent /Imacron
  136.   /Lacute
  137.   /Nacute /Ncaron
  138.   /Ohungarumlaut /Omacron
  139.   /Racute /Rcaron
  140.   /Sacute /Scedilla
  141.   /Tcaron
  142.   /Uhungarumlaut /Umacron /Uogonek /Uring
  143.   /Zacute /Zdotaccent
  144.   /abreve /amacron
  145.   /cacute /ccaron
  146.   /ecaron /edotaccent /emacron
  147.   /gbreve
  148.   /lacute
  149.   /nacute /ncaron
  150.   /ohungarumlaut /omacron
  151.   /racute /rcaron
  152.   /sacute /scedilla
  153.   /uhungarumlaut /umacron /uring
  154.   /zacute /zdotaccent
  155. ] def
  156.  
  157. % Define seac characters where the accent lines up with the right
  158. % edge of the character.
  159. /seacrightchars [
  160.   /Aogonek /Eogonek /Iogonek /aogonek /eogonek /iogonek /uogonek
  161. ] def
  162.  
  163. % Define seac characters where the caron becomes an appended quoteright.
  164. /seaccaronchars [
  165.   /dcaron /lcaron /tcaron
  166. ] def
  167.  
  168. % Define seac characters using commaaccent.
  169. /seaccommachars [
  170.   /Gcommaaccent /Kcommaaccent /Lcommaaccent /Ncommaaccent /Rcommaaccent
  171.   /Scommaaccent /Tcommaaccent
  172.   /gcommaaccent /kcommaaccent /lcommaaccent /ncommaaccent /rcommaaccent
  173.   /scommaaccent /tcommaaccent
  174. ] def
  175.  
  176. % Define the characters copied from the Symbol font.
  177. /symbolchars [
  178.   /Delta /greaterequal /lessequal /lozenge /notequal /partialdiff
  179.   /summation
  180. ] def
  181.  
  182. % Define the procedures for editing the commaaccent character.
  183. % Delete all the hints, since it's too hard to adjust them.
  184. /caedit mark
  185.   /rmoveto { exch commatop sub cvi exch }
  186.   /hstem { pop pop pop }
  187.   /vstem 1 index
  188.   /callothersubr {
  189.     dup 3 eq { 4 { pop } repeat /skip true def } if
  190.   }
  191.   /pop { skip { pop /skip false def } if }
  192. .dicttomark def
  193.  
  194. /addce {        % <name> <font> addce <font'>
  195.   20 dict begin
  196.   /origfont 1 index def
  197.   openfont
  198.   dup /CharStrings 2 copy get dup length dict copy put
  199.   dup /Encoding 2 copy get dup length array copy put
  200.   dup /FontInfo 2 copy get dup length dict copy put
  201.   definefont /font exch def
  202.   currentdict font end begin begin
  203.   font 1000 scalefont setfont
  204.   /symbolfont /Symbol findfont def
  205.   /BBoxes CharStrings length dict def
  206.   /SBW CharStrings length dict def
  207.  
  208.   /italfactor FontInfo /ItalicAngle .knownget {
  209.     neg dup sin exch cos div
  210.   } {
  211.     0
  212.   } ifelse def
  213.  
  214.     % Invert the Encoding (needed for seac).
  215.  
  216.   /charindex 256 dict def
  217.   0 1 255 {
  218.     charindex exch Encoding 1 index get exch put
  219.   } for
  220.  
  221.     % Add the commaaccent character, by moving the comma downward.
  222.  
  223.   /comma glyphbbox /commatop exch def pop pop pop
  224.   /comma glyphcs
  225.     /skip false def
  226.     [ exch { caedit 1 index .knownget { exec } if } forall ]
  227.   /commaaccent exch csdef
  228.  
  229.     % Add the accented characters that can be made with seac.
  230.  
  231.   seacchars {
  232.     splitaccented beginseac
  233.       centeraccent
  234.         % If the accent would collide with the base character,
  235.         % raise it a little.
  236.       abox 1 get bbox 3 get sub dup 0 le {
  237.         % ... but not if the accent is in the low position.
  238.     abox 1 get 0 gt {
  239.       neg 60 add
  240.         % Adjust the X position if italic.
  241.       dup italfactor mul 3 -1 roll add exch
  242.     } {
  243.       pop 0
  244.     } ifelse
  245.       } {
  246.     pop 0
  247.       } ifelse
  248.     finishseac
  249.   } forall
  250.  
  251.   seacrightchars {
  252.     splitaccented beginseac
  253.     bbox 2 get abox 2 get sub add    % line up right edges
  254.     0 finishseac
  255.   } forall
  256.  
  257.   /dcroat /d /hyphen beginseac
  258.     bbox 2 get abox 2 get sub add    % line up right edges
  259.   0 finishseac
  260.  
  261.   /imacron /dotlessi /macron beginseac
  262.     centeraccent
  263.   0 finishseac
  264.  
  265.   /Lcaron /L /quoteright beginseac
  266.     bbox 2 get abox 2 get sub add    % line up right edges
  267.   0 finishseac
  268.  
  269.   seaccaronchars {
  270.     dup =string cvs 0 1 getinterval cvn /quoteright beginseac
  271.         % Move the quote to the right of the character.
  272.     bbox 2 get abox 0 get sub 50 add add
  273.         % Adjust the character width as well.
  274.     4 -1 roll abox 2 get abox 0 get sub 50 add add cvi 4 1 roll
  275.     0 finishseac
  276.   } forall
  277.  
  278.   seaccommachars {
  279.     dup =string cvs 0 1 getinterval cvn /comma beginseac
  280.       centeraccent
  281.       commatop neg
  282.         % Lower the accent if the character extends below
  283.         % the baseline
  284.       bbox 1 get 0 .min add
  285.     finishseac
  286.   } forall
  287.  
  288.     % Add the characters from the Symbol font.
  289.     % We should scale them to match the FontBBox, but we don't.
  290.  
  291.   symbolchars {
  292.     symbolfont /CharStrings get 1 index get
  293.     CharStrings 3 1 roll put
  294.   } forall
  295.  
  296.     % Add the one remaining character.
  297.  
  298.   CharStrings /Dcroat CharStrings /Eth get put
  299.  
  300.     % Recompute the FontBBox, since some of the accented characters
  301.     % may have enlarged it.
  302.  
  303.   /llx 1000 def /lly 1000 def /urx 0 def /ury 0 def
  304.   CharStrings {
  305.     pop glyphbbox
  306.     ury .max /ury exch def urx .max /urx exch def
  307.     lly .min /lly exch def llx .min /llx exch def
  308.   } forall
  309.   /FontBBox llx cvi lly cvi urx ceiling cvi ury ceiling cvi 4 packedarray def
  310.  
  311.     % Restore the Encoding and wrap up.
  312.  
  313.   [/Copyright /Notice] {
  314.     FontInfo 1 index .knownget {
  315.       addednotice concatstrings FontInfo 3 1 roll put
  316.     } {
  317.       pop
  318.     } ifelse
  319.   } forall
  320.   FontName font openfont
  321.   dup /Encoding origfont /Encoding get put
  322.   definefont
  323.  
  324.   end end
  325. } def
  326.  
  327. currentdict end readonly pop    % addce_dict
  328.  
  329. /addce { addce_dict begin addce end } def
  330.  
  331. % ---------------- Integration ---------------- %
  332.  
  333. % We would like to patch the font loader so that it adds the extended
  334. % Latin characters automatically.  We haven't done this yet.
  335.  
  336. % ---------------- Test program ---------------- %
  337.  
  338. /TEST where { pop TEST } { false } ifelse {
  339.   /FONT where { pop } { /FONT /Palatino-Italic def } ifelse
  340.   (unprot.ps) runlibfile
  341.   unprot
  342.   (wrfont.ps) runlibfile
  343.   wrfont_dict begin
  344.     /eexec_encrypt true def
  345.     /binary_CharStrings true def
  346.   end
  347.   save
  348.     FONT findfont
  349.     /Latin-CE exch addce setfont
  350.     (t.ce.pfb) (w) file dup writefont closefile
  351.   restore
  352.   (prfont.ps) runlibfile
  353.   (t.ce.pfb) (r) file .loadfont
  354.   /Latin-CE DoFont
  355.   quit
  356. } if
  357.