addxchar.ps 9.8 KB

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