星火微课系统客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gs_ttf.ps 75KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943
  1. % Copyright (C) 1996-2003 Artifex Software, Inc. All rights reserved.
  2. %
  3. % This software is provided AS-IS with no warranty, either express or
  4. % implied.
  5. %
  6. % This software is distributed under license and may not be copied,
  7. % modified or distributed except as expressly authorized under the terms
  8. % of the license contained in the file LICENSE in this distribution.
  9. %
  10. % For more information about licensing, please refer to
  11. % http://www.ghostscript.com/licensing/. For information on
  12. % commercial licensing, go to http://www.artifex.com/licensing/ or
  13. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  14. % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  15. % $Id: gs_ttf.ps 10577 2010-01-03 01:07:12Z alexcher $
  16. % Support code for direct use of TrueType fonts.
  17. % (Not needed for Type 42 fonts.)
  18. % Note that if you want to use this file without including the ttfont.dev
  19. % option when you built Ghostscript, you will need to load the following
  20. % files before this one:
  21. % lib/gs_mgl_e.ps
  22. % lib/gs_mro_e.ps
  23. % lib/gs_wan_e.ps
  24. % Thanks to B. Jackowski and GUST (the Polish TeX Users' Group) for
  25. % the glyf-splitting code.
  26. % ---------------- Font loading machinery ---------------- %
  27. % Augment the FONTPATH machinery so it recognizes TrueType fonts.
  28. /.scanfontheaders where {
  29. pop /.scanfontheaders [
  30. .scanfontheaders aload pop (\000\001\000\000*) (true*)
  31. ] def
  32. } if
  33. % <file> <key> .findfontvalue <value> true
  34. % <file> <key> .findfontvalue false
  35. % Closes the file in either case.
  36. /.findnonttfontvalue /.findfontvalue load def
  37. /.findfontvalue {
  38. 1 index read {
  39. 2 index 1 index unread
  40. % beginning with binary 0 or 't' (TrueType), or 'O' (OpenType)
  41. dup 0 eq 1 index (O) 0 get eq or exch (t) 0 get eq or {
  42. % If this is a font at all, it's a TrueType font.
  43. dup /FontType eq {
  44. pop closefile 42 true
  45. } {
  46. dup /FontName eq { pop .findttfontname } { pop closefile false } ifelse
  47. } ifelse
  48. } {
  49. % Not a TrueType font.
  50. .findnonttfontvalue
  51. } ifelse
  52. } { pop closefile false } ifelse
  53. } bind def
  54. % <file> .findttfontname <fname> true
  55. % <file> .findttfontname false
  56. % Closes the file in either case.
  57. /.findttfontname {
  58. //true 0 .loadttfonttables
  59. tabdict /name .knownget {
  60. dup 8 getu32 f exch setfileposition
  61. 12 getu32 string f exch readstring pop
  62. dup
  63. 6 findname not {
  64. 4 findname % Try FullName
  65. } {
  66. exch pop true
  67. }
  68. ifelse
  69. } {
  70. false
  71. } ifelse
  72. f closefile end end
  73. } bind def
  74. % Load a font file that might be a TrueType font.
  75. /tt_tag_dict << <00010000> 0 (true) 0 (typ1) 0 (ttcf) 0 >> readonly def
  76. % <file> .loadfontfile -
  77. /.loadnonttfontfile /.loadfontfile load def
  78. /.loadfontfile {
  79. dup (1234) .peekstring { //tt_tag_dict exch known } { //false } ifelse {
  80. % If this is a font at all, it's a TrueType font.
  81. .loadttfont pop
  82. } {
  83. % Not a TrueType font.
  84. .loadnonttfontfile
  85. } ifelse
  86. } bind def
  87. currentdict /tt_tag_dict .undef
  88. % ---------------- Automatic Type 42 generation ---------------- %
  89. % Load a TrueType font from a file as a Type 42 PostScript font.
  90. % The thing that makes this really messy is the handling of encodings.
  91. % There are 2 interacting tables that affect the encoding:
  92. % 'cmap' provides multiple maps from character codes to glyph indices
  93. % 'post' maps glyph indices to glyph names (if present)
  94. % What we need to get out of this is:
  95. % Encoding mapping character codes to glyph names
  96. % (the composition of cmap and post)
  97. % CharStrings mapping glyph names to glyph indices
  98. % (the inverse of post)
  99. % If the post table is missing, we have to take a guess based on the cmap
  100. % table.
  101. /.loadttfontdict 50 dict dup begin
  102. /orgXUID AladdinEnterprisesXUID def
  103. /maxstring 32764 def % half the maximum length of a PostScript string,
  104. % must be a multiple of 4 (for hmtx / loca / vmtx)
  105. /.invert_encoding % <array> invert_encoding <dict>
  106. { dup 256 dict exch
  107. 0 exch 1 exch length 1 sub { % [] <> i
  108. dup 3 index exch get % [] <> i v
  109. dup /.notdef ne {
  110. exch 2 index 2 index .knownget {
  111. dup type /arraytype eq {
  112. [ exch aload pop counttomark 2 add -1 roll ]
  113. } {
  114. exch 2 array astore
  115. } ifelse
  116. } if 2 index 3 1 roll put
  117. } {
  118. pop pop
  119. } ifelse
  120. } for
  121. exch pop
  122. } bind def
  123. % Make /MacRomanEncodingForTrueType including additional
  124. % characters in Mac OS Roman encoding, which is missing
  125. % in /MacRomanEncoding. See PDF spec 1.7, p. 431 or
  126. % "Inside Macintosh: Text" 1-55, Figure 1-36.
  127. % This is useful to exploit the glyphs via Apple Roman
  128. % TrueType cmap subtable, but not appropriate for information
  129. % interchange.
  130. /MacRomanEncodingForTrueType
  131. /MacRomanEncoding .findencoding
  132. dup length array copy
  133. <<
  134. /notequal 173
  135. /infinity 176
  136. /lessequal 178
  137. /greaterequal 179
  138. /partialdiff 182
  139. /summation 183
  140. /product 184
  141. /pi 185
  142. /integral 186
  143. /Omega 189
  144. /radical 195
  145. /approxequal 197
  146. /Delta 198
  147. /lozenge 215
  148. /Euro 219
  149. /apple 240
  150. >> {
  151. TTFDEBUG { (Extend MacRomanEncodingForTrueType for TrueType: ) =only } if
  152. % check /.notdef to avoid overwriting
  153. 2 index 1 index get dup /.notdef eq {
  154. TTFDEBUG { (insert /) =only 2 index =only ( @ ) =only 1 index == } if
  155. pop
  156. exch 2 index 3 1 roll put
  157. } {
  158. TTFDEBUG { (cannot insert /) =only 2 index =only ( @ ) =only 1 index =only ( used for ) =only dup == } if
  159. pop
  160. pop pop
  161. } ifelse
  162. } forall
  163. aload pop
  164. 256 packedarray
  165. 5 1 index .registerencoding
  166. .defineencoding
  167. % Define the Macintosh standard mapping from characters to glyph indices.
  168. /MacRomanEncoding dup .findencoding def
  169. /MacGlyphEncoding dup .findencoding def
  170. /MacRomanEncodingForTrueType dup .findencoding def
  171. % Invert the MacRomanEncoding.
  172. /.romanmacdict MacRomanEncodingForTrueType .invert_encoding def
  173. /.latin1isodict ISOLatin1Encoding .invert_encoding def
  174. % Define remapping for misnamed glyphs in TrueType 'post' tables.
  175. % There are probably a lot more than this!
  176. % Also see /postalias table below.
  177. /postremap mark
  178. /Eoverdot /Edotaccent
  179. /eoverdot /edotaccent
  180. .dicttomark readonly def
  181. % Array used for fast pre-filling of cmap array
  182. /.array1024z [ 1024 { 0 } repeat ] def
  183. % ---- Utilities ---- %
  184. % Define a serial number for creating unique XUIDs for TrueType fonts.
  185. % We used to use the checkSumAdjustment value from the font, but this is
  186. % not reliable, since some fonts don't set it correctly.
  187. % Note that we must do this in a string to make it immune to save/restore.
  188. /xuidstring <80000000> def
  189. /curxuid { % - curxuid <int>
  190. 0 xuidstring { exch 8 bitshift exch add } forall
  191. } bind def
  192. /nextxuid { % - nextxuid -
  193. 3 -1 0 {
  194. xuidstring 1 index 2 copy get dup 255 ne {
  195. 1 add put pop exit
  196. } if pop 0 put pop
  197. } for
  198. } bind def
  199. % <string> <index> getu16 <integer>
  200. /getu16 {
  201. 2 copy get 8 bitshift 3 1 roll 1 add get add
  202. } bind def
  203. % <string> <index> gets16 <integer>
  204. /gets16 {
  205. getu16 16#8000 xor 16#8000 sub
  206. } bind def
  207. % <string> <index> getu32 <integer>
  208. /getu32 {
  209. 2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add
  210. } bind def
  211. % <string> <index> gets32 <integer>
  212. /gets32 {
  213. 2 copy gets16 16 bitshift 3 1 roll 2 add getu16 add
  214. } bind def
  215. % <string|array> <index> getu16 <integer>
  216. /getu16a {
  217. 2 getinterval_from_stringarray 0 getu16
  218. } bind def
  219. % <string|array> <index> gets16 <integer>
  220. /gets16a {
  221. 2 getinterval_from_stringarray 0 gets16
  222. } bind def
  223. % <string|array> <index> getu32a <integer>
  224. /getu32a {
  225. 4 getinterval_from_stringarray 0 getu32
  226. } bind def
  227. % <string|array> <index> gets32a <integer>
  228. /gets32a {
  229. 4 getinterval_from_stringarray 0 gets32
  230. } bind def
  231. 16#ffffffff 0 gt { % 64-bit sign extension
  232. { /curxuid /gets32 /gets32a} {
  233. mark 1 index load aload pop { 16#80000000 xor 16#80000000 sub } aload pop
  234. .packtomark cvx def
  235. } bind forall
  236. } if
  237. % <string> <index> <integer> putu16 -
  238. /putu16 {
  239. 3 copy -8 bitshift put
  240. exch 1 add exch 16#ff and put
  241. } bind def
  242. % <string> <index> <integer> putu32 -
  243. /putu32 {
  244. 3 copy -16 bitshift putu16
  245. exch 2 add exch 16#ffff and putu16
  246. } bind def
  247. % <nametable> <nameid> findname <string> true
  248. % <nametable> <nameid> findname false
  249. /findname {
  250. TTFDEBUG { (findname: ) print dup =only } if
  251. false 3 1 roll
  252. 1 index length 0 gt { % check for zero length name table
  253. 0 1 3 index 2 getu16 1 sub {
  254. % Stack: false table id index
  255. 12 mul 6 add 2 index exch 12 getinterval
  256. dup 6 getu16 2 index eq 1 index 8 getu16 0 ne and {
  257. % We found the name we want.
  258. exch pop
  259. % Stack: false table record
  260. dup 10 getu16 2 index 4 getu16 add
  261. 1 index 8 getu16 4 -1 roll 3 1 roll
  262. 3 copy add 1 index length
  263. le {
  264. pop
  265. getinterval exch
  266. % Stack: false string record
  267. % Check for 8- vs. 16-bit characters.
  268. is2byte { true } { dup is2byte2 } ifelse { string2to1 } if true null 4 -1 roll exit
  269. } {
  270. pop pop pop pop
  271. false
  272. exit
  273. } ifelse
  274. } if pop
  275. } for
  276. } if
  277. pop pop
  278. TTFDEBUG {
  279. dup { ( = ) print 1 index == } { ( not found) = } ifelse
  280. } if
  281. } bind def
  282. % <namerecord> is2byte <bool>
  283. /is2byte {
  284. dup 0 getu16 {
  285. { pop true } % Apple Unicode
  286. { pop false } % Macintosh Script manager
  287. { 1 getu16 1 eq } % ISO
  288. { 1 getu16 1 eq } % Microsoft
  289. } exch get exec
  290. } bind def
  291. % <string> is2byte2 <bool>
  292. /is2byte2 {
  293. dup length
  294. dup 2 mod 0 ne {
  295. pop pop false
  296. } { % s l
  297. true exch % s b l
  298. 1 sub 0 exch 2 exch {
  299. 2 index exch get 0 ne {
  300. pop false exit
  301. } if
  302. } for
  303. exch pop
  304. } ifelse
  305. } bind def
  306. % <string2> string2to1 <string>
  307. /string2to1 {
  308. dup length 2 idiv string dup
  309. 0 1 3 index length 1 sub {
  310. 3 index 1 index 2 mul 1 add get put dup
  311. } for pop exch pop
  312. } bind def
  313. % Each procedure in this dictionary is called as follows:
  314. % <encodingtable> proc <glypharray>
  315. /cmapformats mark
  316. 0 { % Apple standard 1-to-1 mapping.
  317. 6 256 getinterval_from_stringarray
  318. mark 0 3 -1 roll
  319. { 1 index 1 add } forall pop
  320. .dicttomark
  321. } bind
  322. 2 { % Apple 16bit CJK (ShiftJIS etc)
  323. % /sHK_sz subHeaderKey_size % 1 * uint16
  324. % /sH_sz subHeader_size % 4 * uint16
  325. % /sH_len subHeader_length
  326. % /cmapf2_tblen total table length
  327. % /cmapf2_lang language code (not used)
  328. % /sHKs subHeaderKeys
  329. /sHK_sz 2 def
  330. /sH_sz 8 def
  331. dup 2 getu16a /cmapf2_tblen exch def
  332. dup 4 getu16a /cmapf2_lang exch def
  333. dup 6 256 sHK_sz mul getinterval_from_stringarray /sHKs exch def
  334. 0 % initialization value for /sH_len
  335. 0 1 255 {
  336. sHKs exch
  337. 2 mul getu16a
  338. 1 index % get current max
  339. 1 index % get current subHeaderKey
  340. lt {exch} if pop
  341. } for
  342. /sH_len exch def
  343. dup 6 256 sHK_sz mul add
  344. cmapf2_tblen 1 index sub getinterval_from_stringarray
  345. /sH_gIA exch def
  346. /cmapf2_glyph_array 0 dict def
  347. /.cmapf2_putGID {
  348. /cmapf2_ch cmapf2_ch_hi 8 bitshift cmapf2_ch_lo add def
  349. firstCode cmapf2_ch_lo le
  350. cmapf2_ch_lo firstCode entryCount add lt
  351. and { % true: j is inside
  352. sH_offset idRangeOffset add % offset to gI
  353. cmapf2_ch_lo firstCode sub 2 mul % rel. pos. in range
  354. add 6 add % offset in sH_gIA
  355. sH_gIA exch getu16a
  356. dup 0 gt { %
  357. idDelta add
  358. cmapf2_glyph_array exch cmapf2_ch exch put
  359. } {
  360. pop
  361. % cmapf2_glyph_array cmapf2_ch 0 put
  362. } ifelse
  363. } { % false: j is outside
  364. % cmapf2_glyph_array cmapf2_ch 0 put
  365. } ifelse
  366. } def
  367. 16#00 1 16#ff { % hi_byte scan
  368. /cmapf2_ch_hi exch def
  369. sHKs cmapf2_ch_hi sHK_sz mul getu16a
  370. /sH_offset exch def
  371. sH_gIA sH_offset sH_sz getinterval
  372. dup 0 getu16a /firstCode exch def
  373. dup 2 getu16a /entryCount exch def
  374. dup 4 gets16a /idDelta exch def
  375. dup 6 getu16a /idRangeOffset exch def
  376. pop
  377. sH_offset 0 eq {
  378. /cmapf2_ch_lo cmapf2_ch_hi def
  379. /cmapf2_ch_hi 0 def
  380. .cmapf2_putGID
  381. } {
  382. 16#00 1 16#ff { % lo_byte scan
  383. /cmapf2_ch_lo exch def
  384. .cmapf2_putGID
  385. } for
  386. } ifelse
  387. } for
  388. pop
  389. cmapf2_glyph_array
  390. } bind
  391. 4 { % Microsoft/Adobe segmented mapping.
  392. /etab exch def
  393. /nseg2 etab 6 getu16a def
  394. 14 /endc etab 2 index nseg2 getinterval_from_stringarray def
  395. % The Apple TrueType documentation omits the 2-byte
  396. % 'reserved pad' that follows the endCount vector!
  397. 2 add
  398. nseg2 add /startc etab 2 index nseg2 getinterval_from_stringarray def
  399. nseg2 add /iddelta etab 2 index nseg2 getinterval_from_stringarray def
  400. nseg2 add /idroff etab 2 index nseg2 getinterval_from_stringarray def
  401. % The following hack allows us to properly handle
  402. % idiosyncratic fonts that start at 0xf000:
  403. pop
  404. /firstcode startc 0 getu16a 16#ff00 and dup 16#f000 ne { pop 0 } if def
  405. /putglyph {
  406. glyphs code 3 -1 roll put /code code 1 add def
  407. } bind def
  408. % Do a first pass to compute the size of the glyphs array.
  409. /numcodes 0 def
  410. /glyphs 0 dict def
  411. 0 0 2 nseg2 3 sub {
  412. % Stack: /glyphs numglyphs i2
  413. /i2 exch def
  414. /scode startc i2 getu16a def
  415. /ecode endc i2 getu16a def
  416. numcodes scode firstcode sub
  417. % Hack for fonts that have only 0x0000 and 0xf000 ranges
  418. %dup 16#e000 ge { 255 and } if
  419. % the previous line is obstructive to CJK fonts, so it was removed
  420. exch sub 0 .max ecode scode sub 1 add add
  421. exch 1 index add exch
  422. numcodes add /numcodes exch def
  423. } for pop
  424. % Now fill in the array.
  425. /numcodes 0 def /code 0 def
  426. 0 2 nseg2 3 sub {
  427. /i2 exch def
  428. /scode startc i2 getu16a def
  429. /ecode endc i2 getu16a def
  430. numcodes scode firstcode sub
  431. % Hack for fonts that have only 0x0000 and 0xf000 ranges
  432. %dup 16#e000 ge { 255 and } if
  433. % the previous line is obstructive to CJK fonts, so it was removed
  434. exch sub 0 .max dup /code exch code exch add def
  435. ecode scode sub 1 add add numcodes add /numcodes exch def
  436. /delta iddelta i2 gets16a def
  437. TTFDEBUG {
  438. (scode=) print scode =only
  439. ( ecode=) print ecode =only
  440. ( delta=) print delta =only
  441. ( droff=) print idroff i2 getu16 =
  442. } if
  443. idroff i2 getu16a dup 0 eq {
  444. pop scode delta add 65535 and 1 ecode delta add 65535 and
  445. { putglyph } for
  446. } { % The +2 is for the 'reserved pad'.
  447. /gloff exch 14 nseg2 3 mul add 2 add i2 add add def
  448. 0 1 ecode scode sub {
  449. 2 mul gloff add etab exch getu16a
  450. dup 0 ne { delta add 65535 and } if putglyph
  451. } for
  452. } ifelse
  453. } for glyphs /glyphs null def % for GC
  454. } bind
  455. 6 { % Single interval lookup.
  456. dup 6 getu16a /firstcode exch def
  457. dup 8 getu16a /ng exch def
  458. firstcode ng add dict
  459. % Stack: tab array
  460. % Fill elements 0 .. firstcode-1 with 0
  461. 0 1 firstcode 1 sub { 2 copy 0 put pop } for
  462. dup
  463. % Stack: tab dict dict
  464. % Fill elements firstcode .. firstcode+nvalue-1 with glyph values
  465. 0 1 ng 1 sub {
  466. dup firstcode add exch
  467. 2 mul 10 add 4 index exch getu16a 3 copy put pop pop
  468. } for pop exch pop
  469. } bind
  470. .dicttomark readonly def % cmapformats
  471. % <cmaptab> cmaparray <glypharray>
  472. /cmaparray {
  473. dup 0 getu16a cmapformats exch .knownget {
  474. TTFDEBUG {
  475. (cmap: format ) print 1 index 0 getu16a = flush
  476. } if exec
  477. } {
  478. (Can't handle format ) print 0 getu16a = flush
  479. mark 0 1 255 { dup } for .dicttomark
  480. } ifelse
  481. TTFDEBUG {
  482. (cmap: length=) print dup length = dup ===
  483. } if
  484. } bind def
  485. /get_from_stringarray % <array|string> <offset> get_from_stringarray <int>
  486. { 1 index type /stringtype eq {
  487. get
  488. } {
  489. exch { % o ()
  490. 2 copy length ge {
  491. length sub
  492. } {
  493. exch get exit
  494. } ifelse
  495. } forall
  496. } ifelse
  497. } bind def
  498. /getinterval_from_stringarray % <array|string> <offset> <length> getinterval_from_stringarray <string>
  499. { % May allocate a string in VM.
  500. 2 index type /stringtype eq {
  501. getinterval
  502. } {
  503. dup 65535 le {
  504. string exch 0 % [] s o p
  505. 4 3 roll { % s o p Si
  506. dup length % s o p Si lSi
  507. dup 4 index lt {
  508. 3 index exch sub % s o p Si o'
  509. exch pop 3 1 roll exch pop % s o' p
  510. } { % s o p Si lSi
  511. dup 3 1 roll % s o p lSi Si lSi
  512. 4 index sub % s o p lSi Si lSi-o
  513. 5 index length 4 index sub % s o p lSi Si lSi-o ls-p
  514. 2 copy gt { exch } if pop % s o p lSi Si minl
  515. dup 3 1 roll % s o p lSi minl Si minl
  516. 5 index exch getinterval % s o p lSi minl from
  517. 5 index 4 index 3 index % s o p lSi minl from s p minl
  518. getinterval % s o p lSi minl from to
  519. copy pop % s o p lSi minl
  520. exch pop add exch pop 0 exch % s 0 p'
  521. dup 3 index length ge { exit } if
  522. } ifelse
  523. } forall
  524. pop pop % s
  525. } {
  526. [ 4 1 roll
  527. {
  528. dup 0 eq {
  529. pop pop pop exit
  530. } if
  531. 3 copy
  532. dup 65535 ge {
  533. pop 65535
  534. } if
  535. getinterval_from_stringarray 4 1 roll
  536. 3 index length sub
  537. exch
  538. 3 index length add
  539. exch
  540. } loop
  541. ]
  542. } ifelse
  543. } ifelse
  544. } bind def
  545. /string_array_size % <array|string> string_array_size <int>
  546. { dup type /stringtype eq {
  547. length
  548. } {
  549. 0 exch { length add } forall
  550. } ifelse
  551. } bind def
  552. % Each procedure in this dictionary is called as follows:
  553. % posttable <<proc>> glyphencoding
  554. /postformats mark
  555. 16#00010000 { % 258 standard Macintosh glyphs.
  556. pop MacGlyphEncoding
  557. }
  558. 16#00020000 { % Detailed map, required by Microsoft fonts.
  559. dup dup type /arraytype eq { 0 get } if length 36 lt {
  560. TTFDEBUG { (post format 2.0 invalid.) = flush } if
  561. pop [ ]
  562. } {
  563. /postglyphs exch def
  564. /post_first postglyphs dup type /arraytype eq { 0 get } if def
  565. post_first 32 getu16 /numglyphs exch def
  566. /glyphnames numglyphs 2 mul 34 add def
  567. % Build names array in the order they occur in the 'post' table
  568. /postpos glyphnames def
  569. /total_length postglyphs //string_array_size exec def
  570. numglyphs array 0 1 numglyphs 1 sub {
  571. postpos total_length ge {
  572. % Fill the rest with .notdef
  573. 1 numglyphs 1 sub { 1 index exch /.notdef put } for
  574. exit
  575. } if
  576. % No name available, /postnames will be defined as an empty
  577. % array and the glyph won't get a name attached.
  578. postglyphs postpos //get_from_stringarray exec
  579. postglyphs postpos 1 add 2 index
  580. 2 copy add total_length gt {
  581. TTFDEBUG { (post table ends in the middle of the entry.) print flush } if
  582. pop pop pop pop
  583. % Fill the rest with .notdef
  584. 1 numglyphs 1 sub { 1 index exch /.notdef put } for
  585. exit
  586. } if
  587. //getinterval_from_stringarray exec cvn
  588. exch postpos add 1 add /postpos exch def
  589. 2 index 3 1 roll
  590. put
  591. } for
  592. /postnames exch def
  593. % Some TrueType fonts converted by "Windows Type 1 Installer" have
  594. % problematic post table including MacGlyphEncoding entries which
  595. % should be omitted. Such extra entries in the beginning of glyphName
  596. % array make /Encoding broken. If we find populary predefined
  597. % ISOLatin1Encoding glyph name in the post table, empty encoding is
  598. % returned. Some TrueType fonts for Microsoft Windows redefines
  599. % MacGlyphEncoding glyph name out of predefined range). To permit
  600. % such fonts, ISOLatin1Encoding is used to find broken post. Bug 689495.
  601. /.broken_post //false def
  602. tabdict /name .knownget {
  603. (Windows Type 1 Installer V1.0) search {
  604. pop pop pop
  605. .latin1isodict postnames {
  606. dup /.notdef ne {
  607. 2 copy known {
  608. TTFDEBUG { (ignore post table that redefines ISOLatin1Encoding glyph name ) print dup == flush } if
  609. /.broken_post //true def
  610. pop exit
  611. } if
  612. } if
  613. pop
  614. } forall
  615. pop
  616. } {
  617. pop
  618. } ifelse
  619. } if
  620. numglyphs array 0 1 numglyphs 1 sub {
  621. dup 2 mul 34 add postglyphs exch 2 //getinterval_from_stringarray exec
  622. dup 0 get 8 bitshift exch 1 get add dup 258 lt {
  623. MacGlyphEncoding exch get
  624. } {
  625. dup 32768 ge {
  626. % According to the published TrueType spec, such values are
  627. % "reserved for future use", but at least some PDF files
  628. % produced by the Adobe PDF library contain entries with a
  629. % value of 16#ffff.
  630. pop /.notdef
  631. } {
  632. % Get the name for this glyph
  633. 258 sub dup postnames length ge {
  634. TTFDEBUG { ( *** warning: glyph index past end of 'post' table) = flush } if
  635. pop pop
  636. exit
  637. } if
  638. postnames exch get
  639. % At least some of Microsoft's TrueType fonts use incorrect
  640. % (Adobe-incompatible) names for some glyphs.
  641. % Correct for this here.
  642. postremap 1 index .knownget { exch pop } if
  643. } ifelse
  644. } ifelse
  645. 2 index 3 1 roll put
  646. } for
  647. .broken_post {
  648. pop
  649. [ postnames aload length 1 roll ]
  650. } if
  651. }
  652. ifelse
  653. } bind
  654. 16#00030000 { % No map.
  655. pop [ ]
  656. } bind
  657. .dicttomark readonly def % postformats
  658. /call.readtable
  659. { .readtable
  660. } bind def
  661. /call.readbigtable
  662. { .readbigtable
  663. } bind def
  664. % Each procedure in this dictionary is called as follows:
  665. % <file> <length> -proc- <string|array_of_strings>
  666. % Note that each table must have an even length, because of a strange
  667. % Adobe requirement that each sfnts entry have even length.
  668. /readtables mark
  669. % Ordinary tables
  670. (head) //call.readtable
  671. (hhea) 1 index
  672. (maxp) 1 index
  673. (name) 1 index
  674. (OS/2) 1 index
  675. (post) //call.readbigtable
  676. (vhea) //call.readtable
  677. % Big tables
  678. (cmap) //call.readbigtable
  679. (GSUB) //call.readbigtable
  680. (glyf) //call.readbigtable
  681. (loca) 1 index
  682. (hmtx) 1 index
  683. (vmtx) 1 index
  684. % Tables only needed for embedding in PDF files
  685. (cvt ) //call.readtable
  686. (fpgm) 1 index
  687. (prep) 1 index
  688. .dicttomark
  689. % Normally there would be a 'readonly' here, but the ttf2pf utility wants
  690. % to include the 'kern' table as well, so we leave the readtables dictionary
  691. % writable.
  692. def % readtables
  693. /readtables_stripped readtables dup length dict copy
  694. dup (loca) { .skiptable } put
  695. dup (glyf) { .skiptable } put
  696. def
  697. % Read a table as a single string.
  698. % <file> <length> .skiptable <string>
  699. /.skiptable {
  700. pop pop ()
  701. } bind def
  702. % Read a table as a single string.
  703. % <file> <length> .readtable <string>
  704. /.readtable {
  705. dup dup 1 and add string
  706. % Stack: f len str
  707. dup 0 4 -1 roll getinterval
  708. % Stack: f str str1
  709. % Because of the absurd PostScript specification that gives an
  710. % error for reading into an empty string, we have to check for
  711. % this explicitly here.
  712. 3 -1 roll exch
  713. dup () ne { readstring } if pop pop
  714. } bind def
  715. % Read a big table (one that may exceed 64K).
  716. % <file> <length> .readbigtable <string[s]>
  717. /.readbigtable {
  718. dup 65400 lt {
  719. .readtable
  720. } {
  721. currentuserparams /VMReclaim get -2 vmreclaim
  722. [ 4 2 roll {
  723. % Stack: mark ... f left
  724. dup maxstring le { exit } if
  725. 1 index maxstring string readstring pop 3 1 roll maxstring sub
  726. } loop .readtable ]
  727. exch vmreclaim
  728. } ifelse
  729. } bind def
  730. end readonly def % .loadttfontdict
  731. % <tab> .printtab -
  732. /.printtab {
  733. dup 0 4 getinterval print ( ) print
  734. dup 8 getu32 =only ( ) print
  735. 12 getu32 =
  736. } bind def
  737. % <file> <bool> <SubfontID> .loadttfonttables -
  738. % Pushes .loadttfontdict & scratch dict on d-stack.
  739. % Defines f, offsets, tables, tabdict, tabs.
  740. % Skips loca and glyf if <bool> is true.
  741. /.loadttfonttables {
  742. .loadttfontdict begin
  743. 40 dict begin
  744. /SubfontID exch def
  745. /load_stripped exch def
  746. /f exch def
  747. /offsets f 12 string readstring pop def
  748. load_stripped { readtables_stripped } { readtables } ifelse /readtables_ exch def
  749. offsets 0 4 getinterval (ttcf) eq {
  750. % We need to handle TT collections with disk fonts only.
  751. % Therefore the file is a disk file and it can be positioned.
  752. offsets 8 getu32 /num_fonts exch def
  753. SubfontID num_fonts ge {
  754. QUIET not { (True Type collection contains insufficient fonts.) = } if
  755. /.loadttfonttables cvx /invalidfont signalerror
  756. } if
  757. SubfontID 4 mul 12 add f exch setfileposition
  758. f 4 string readstring pop 0
  759. getu32 /ttc_offset exch def
  760. f ttc_offset setfileposition
  761. /offsets f 12 string readstring pop def
  762. } {
  763. SubfontID 0 gt {
  764. QUIET not { (SubfontID > 0 with a True Type file which is not a collection.) = } if
  765. /.loadttfonttables cvx /invalidfont signalerror
  766. } if
  767. /ttc_offset 0 def
  768. } ifelse
  769. % Peek because table counter may be incorrect.
  770. /tables f offsets 4 getu16 16 mul string .peekstring pop def
  771. /tabdict tables length 16 idiv dict def
  772. % tabs = tables we want to keep, sorted by file position.
  773. /tabs [ 0 16 tables length 1 sub {
  774. tables exch 16 getinterval
  775. TTFDEBUG { dup .printtab } if
  776. dup 0 4 getinterval readtables_ 1 index known {
  777. % put all 0 length tables at 0 to avoid overlap
  778. 1 index 12 getu32 0 eq { 1 index 8 0 putu32 } if
  779. tabdict exch 2 index put
  780. } {
  781. pop pop
  782. } ifelse
  783. } for ] {
  784. exch 8 getu32 exch 8 getu32 lt
  785. } .sort def
  786. % In certain malformed TrueType fonts, tables overlap.
  787. % Truncate tables if necessary.
  788. 0 1 tabs length 2 sub {
  789. dup tabs exch get exch 1 add tabs exch get
  790. 1 index 8 getu32 2 index 12 getu32 add
  791. 1 index 8 getu32 gt {
  792. (**** Warning: ) print 1 index 0 4 getinterval print
  793. ( overlaps ) print dup 0 4 getinterval print
  794. (, truncating.) = flush
  795. dup 8 getu32 2 index 8 getu32 sub
  796. 2 index 12 3 -1 roll putu32
  797. } if pop pop
  798. } for
  799. } bind def
  800. /.file_table_pos_names
  801. mark
  802. /glyf 0
  803. /loca 0
  804. .dicttomark readonly def
  805. % - .readttdata -
  806. % Read data. Updates offsets, tabs; stores data in tabdict.
  807. /.readttdata {
  808. /file_table_pos 10 dict def
  809. /fpos offsets length ttc_offset add def
  810. /sfpos offsets length tabs length 16 mul add def
  811. offsets 4 tabs length putu16
  812. tabs {
  813. dup 0 4 getinterval /tname exch def
  814. dup 8 getu32 /tpos exch def
  815. dup 12 getu32 /tlen exch def
  816. load_stripped //.file_table_pos_names tname known and {
  817. pop
  818. file_table_pos tname [tpos tlen] put
  819. tabdict tname () put
  820. } {
  821. 8 sfpos putu32
  822. % Skip data between the end of the previous table and
  823. % the beginning of this one, if any.
  824. tpos fpos gt {
  825. load_stripped {
  826. % 'setfileposition' is faster for skipping a big data.
  827. f tpos setfileposition
  828. } {
  829. f tpos fpos sub () /SubFileDecode filter dup flushfile closefile
  830. /fpos tpos def
  831. } ifelse
  832. } if
  833. f tlen readtables_ tname get exec
  834. tabdict tname 3 -1 roll put
  835. % Round up the table length to an even value.
  836. /sfpos sfpos tlen dup 1 and add add def
  837. } ifelse
  838. /fpos fpos tlen add def
  839. } forall
  840. } bind def
  841. % Find the string in a list of strings that includes a given index.
  842. % <strings> <index> .findseg <string> <index'>
  843. /.findseg {
  844. exch {
  845. dup length 2 index gt { exch exit } if
  846. length sub
  847. } forall
  848. } bind def
  849. % - .makesfnts -
  850. % Defines checksum, getloca, head, locatable, numloca, post, sfnts, upem
  851. % Note that the 'loca' table may be out of order. This is handled when
  852. % needed in .dividesfnts
  853. /.makesfnts {
  854. .readttdata
  855. /head tabdict /head get def
  856. /post tabdict /post .knownget {
  857. dup 0 get /post_first_part exch def
  858. } {
  859. null
  860. } ifelse def
  861. load_stripped not {
  862. /locatable tabdict /loca get def
  863. /numloca
  864. locatable dup type /stringtype eq
  865. { length }
  866. { 0 exch { length add } forall }
  867. ifelse % no def yet
  868. locatable type /stringtype eq {
  869. /.indexloca {} def
  870. } {
  871. /.indexloca /.findseg load def
  872. } ifelse
  873. head 50 getu16 0 ne {
  874. /getloca {
  875. 2 bitshift locatable exch .indexloca getu32
  876. } def
  877. 4 idiv 1 sub
  878. } {
  879. /getloca {
  880. dup add locatable exch .indexloca getu16 dup add
  881. } def
  882. 2 idiv 1 sub
  883. } ifelse def % numloca
  884. % If necessary, re-partition the glyfs.
  885. tabdict /glyf get dup type /stringtype ne {
  886. .dividesfnts tabdict /glyf 3 -1 roll put
  887. } {
  888. pop
  889. } ifelse
  890. } {
  891. % We did not load loca, take the number of glyphs from maxp.
  892. /numloca tabdict /maxp get 4 getu16 def
  893. } ifelse
  894. /sfnts [
  895. offsets tabs { concatstrings } forall
  896. tabs {
  897. 0 4 getinterval tabdict exch get
  898. dup type /stringtype ne { aload pop } if
  899. } forall
  900. ] def
  901. } bind def
  902. % <glyfs> .dividesfnts <glyfs'>
  903. /.dividesfnts {
  904. /glyfs exch def
  905. /len1 0 glyfs { length add } forall def
  906. % Determine where to split the glyfs by scanning the sorted locatable
  907. % The very last entry in loca may be bogus.
  908. % Note that some loca entries may be odd, but we can only
  909. % split at even positions.
  910. %
  911. % Construct splitarray, the array of final lengths of
  912. % the sfnts entries covering the glyfs (i.e., all but
  913. % the first and last sfnts entries).
  914. /prevsplit 0 def
  915. /prevboundary 0 def
  916. % sort the locatable in case it is out of order
  917. % Note the 'loca' table remains unchanged
  918. /needsort false def
  919. numloca array % the array of 'loca' entries (may be out of order)
  920. -1 % initial values for in order check
  921. 0 1 numloca 1 sub {
  922. dup getloca dup
  923. 4 -1 roll lt { /needsort true def } if
  924. 3 copy put exch pop
  925. } for pop % discard inorder check value
  926. needsort {
  927. { lt } bind .sort % stack: locatable_array
  928. } if
  929. /splitarray [
  930. 3 -1 roll 0 1 numloca 1 sub {
  931. % stack: /splitarray -mark- { splitlen splitlen ... } locatable_array index
  932. 1 index exch get dup prevsplit maxstring add gt {
  933. prevboundary prevsplit sub exch
  934. /prevsplit prevboundary def
  935. } if
  936. dup 1 and 0 eq { /prevboundary exch def } { pop } ifelse
  937. dup type /arraytype ne { exch } if % keep locatable_array on top
  938. } for
  939. len1 prevsplit sub
  940. exch pop % discard locatable_array
  941. ] def
  942. currentuserparams /VMReclaim get -2 vmreclaim
  943. [
  944. % Re-split the sfnts glyfs strings according to splitarray.
  945. % We do this by iterating over the final segments defined
  946. % by splitarray, and constructing them from pieces of the
  947. % current glyfs strings. We recycle the current strings
  948. % when possible, to avoid stressing the allocator.
  949. /sfnt_idx 0 def
  950. /strpos 0 def
  951. /avail () def
  952. splitarray {
  953. /seglen exch def
  954. /segpos 0 def
  955. avail length seglen ge
  956. { avail 0 seglen getinterval /avail () def } { seglen string }
  957. ifelse
  958. {
  959. /str glyfs sfnt_idx get def
  960. /strlen str length def
  961. /strleft strlen strpos sub def
  962. seglen segpos sub strleft lt { exit } if
  963. % Copy the (rest of the) string into the new segment.
  964. % We know strleft <= segleft.
  965. dup segpos str strpos strleft getinterval putinterval
  966. /segpos segpos strleft add def
  967. /avail str def
  968. /sfnt_idx sfnt_idx 1 add def
  969. /strpos 0 def
  970. segpos seglen eq { exit } if
  971. } loop
  972. % Fill up the segment with an initial piece of the next
  973. % existing glyfs string. We know strleft > segleft.
  974. /segleft seglen segpos sub def
  975. dup segpos str strpos segleft getinterval putinterval
  976. /strpos strpos segleft add def
  977. } forall
  978. ]
  979. exch vmreclaim
  980. } bind def
  981. /first_post_string % - first_post_string <string>
  982. {
  983. post dup type /arraytype eq { 0 get } if
  984. } bind def
  985. % - .getpost -
  986. % Uses post, defines glyphencoding
  987. /.getpost {
  988. /glyphencoding post null eq {
  989. TTFDEBUG { (post missing) = flush } if [ ]
  990. } {
  991. postformats first_post_string 0 getu32 .knownget {
  992. TTFDEBUG {
  993. (post: format ) print
  994. first_post_string
  995. dup 0 getu16 =only (,) print 2 getu16 = flush
  996. } if
  997. post exch exec
  998. } {
  999. TTFDEBUG { (post: unknown format ) print post 0 getu32 = flush } if [ ]
  1000. } ifelse
  1001. } ifelse
  1002. TTFDEBUG { (post=) print dup == } if
  1003. def
  1004. } bind def
  1005. % - .ttkeys <key> <value> ...
  1006. /.ttkeys {
  1007. count /ttkeycount exch def
  1008. /upem head 18 getu16 def
  1009. /FontMatrix matrix
  1010. /FontBBox [ 36 2 42 { head exch gets16 upem div } for ]
  1011. nextxuid
  1012. tabdict /name .knownget {
  1013. % Find the names from the 'name' table.
  1014. /names exch def
  1015. /FontName names 6 findname not { names 4 findname not { curxuid 16#ffffffff and 16 32 string cvrs } if } if
  1016. /fontname 1 index def
  1017. /FontInfo mark
  1018. names 0 findname { /Notice exch } if
  1019. names 1 findname { /FamilyName exch } if
  1020. names 4 findname { /FullName exch } if
  1021. names 5 findname { /Version exch } if
  1022. } {
  1023. % No name table, fabricate a FontName.
  1024. /FontName curxuid 16#ffffffff and 16 32 string cvrs
  1025. /fontname 1 index def
  1026. /FontInfo mark
  1027. } ifelse
  1028. % Stack: ... /FontInfo mark key1 value1 ...
  1029. post null ne {
  1030. /ItalicAngle first_post_string 4 gets32 65536.0 div
  1031. /isFixedPitch first_post_string 12 getu32 0 ne
  1032. /UnderlinePosition first_post_string 8 gets16 upem div
  1033. /UnderlineThickness first_post_string 10 gets16 upem div
  1034. } if
  1035. counttomark 0 ne { .dicttomark } { pop pop } ifelse
  1036. /XUID [orgXUID 42 curxuid]
  1037. TTFDEBUG {
  1038. tabs { .printtab } forall
  1039. [ sfnts { length } forall ] ==
  1040. count ttkeycount sub array astore dup { == } forall aload pop
  1041. } if
  1042. /sfnts sfnts
  1043. } bind def
  1044. % ---------------- Standard TrueType font loading ---------------- %
  1045. % - .pickcmap_with_no_xlatmap -
  1046. % Defines cmapsub, cmaptab
  1047. /.pickcmap_with_no_xlatmap {
  1048. tabdict /cmap get
  1049. % The Apple cmap format is no help in determining the encoding.
  1050. % Look for a Microsoft table. If we can't find one,
  1051. % just use the first table, whatever it is.
  1052. dup 4 8 getinterval_from_stringarray exch % () [] % the default
  1053. 0 1 2 index 2 getu16a 1 sub { % () [] i
  1054. 8 mul 4 add 1 index exch 8 getinterval_from_stringarray % () [] ()
  1055. TTFDEBUG {
  1056. (cmap: platform ) print dup 0 getu16 =only
  1057. ( encoding ) print dup 2 getu16 = flush
  1058. } if
  1059. dup 0 getu16 3 eq { exch 3 -1 roll pop exit } if pop
  1060. } for
  1061. % Stack: subentry table
  1062. /cmapsub 2 index def % () []
  1063. exch 4 getu32 1 index string_array_size 1 index sub getinterval_from_stringarray
  1064. /cmaptab exch def
  1065. } bind def
  1066. % - .pickcmap_with_xlatmap -
  1067. % Defines cmapsub, cmaptab
  1068. /.pickcmap_with_xlatmap {
  1069. .xlatmap_dict /TrueType known not {
  1070. (Emulating a CID font with a True Type file, ) print
  1071. (the file gs/lib/xlatmap must contain /TrueType key.) =
  1072. /.pickcmap_with_xlatmap cvx /configurationerror signalerror
  1073. } if
  1074. false
  1075. .xlatmap_dict /TrueType get
  1076. dup length 2 sub 0 exch 2 exch { % bool [] i
  1077. 2 copy get % bool [] i ()
  1078. (.) search { % bool [] i post match pre
  1079. cvi exch pop exch cvi % bool [] i PlatID SpecID
  1080. } {
  1081. (gs/lib/xlatmap containg a record with an invalid (PlatformID.SpecificID)) =
  1082. /.pickcmap_with_xlatmap cvx /configurationerror signalerror
  1083. } ifelse
  1084. TTFDEBUG {
  1085. (Seeking a cmap for platform=) print 1 index =only ( encoding=) print dup =
  1086. } if
  1087. tabdict /cmap get % bool [] i PlatID SpecID (cmap)
  1088. dup /cmaptab exch def % temporary
  1089. 0 1 2 index 2 getu16a 1 sub { % bool [] i PlatID SpecID (cmap) j
  1090. 8 mul 4 add 1 index exch 8
  1091. getinterval_from_stringarray % bool [] i PlatID SpecID (cmap) (cmapsub)
  1092. TTFDEBUG {
  1093. (cmap: platform ) print dup 0 getu16 =only
  1094. ( encoding ) print dup 2 getu16 = flush
  1095. } if
  1096. dup 0 getu16 4 index eq {
  1097. dup 2 getu16 3 index eq { % bool [] i PlatID SpecID (cmap) (cmapsub)
  1098. TTFDEBUG {
  1099. (Choosen a cmap for platform=) print 3 index =only
  1100. ( encoding=) print 2 index =
  1101. } if
  1102. /cmapsub 1 index def
  1103. dup 4 getu32 % bool [] i PlatID SpecID (cmap) (cmapsub) p
  1104. cmaptab 1 index getu16a % get cmap format
  1105. 8 lt { % length for traditional 16bit format 0, 2, 4, 6
  1106. cmaptab 1 index 2 add getu16a
  1107. } { % length for advanced 32bit format 8, 10, 12
  1108. cmaptab 1 index 4 add getu32a
  1109. } ifelse % bool [] i PlatID SpecID (cmap) (cmapsub) p l
  1110. cmaptab 3 1 roll getinterval_from_stringarray
  1111. /cmaptab exch def % bool [] i PlatID SpecID (cmap) (cmapsub)
  1112. 5 index 5 index 1 add get % bool [] i PlatID SpecID (cmap) (cmapsub) /Decoding
  1113. /Decoding exch def % bool [] i PlatID SpecID (cmap) (cmapsub)
  1114. 7 -1 roll pop true 7 1 roll % true [] i PlatID SpecID (cmap) (cmapsub)
  1115. } if
  1116. } if
  1117. pop % true [] i PlatID SpecID (cmap)
  1118. 5 index { exit } if
  1119. } for % bool [] i PlatID SpecID (cmap)
  1120. pop pop pop pop % bool []
  1121. 1 index { exit } if
  1122. } for % bool []
  1123. pop % bool
  1124. not {
  1125. QUIET not { (True Type font doesn't contain a charset listed in gs/lib/xlatmap.) = } if
  1126. /.pickcmap_with_xlatmap cvx /invalidfont signalerror
  1127. } if %
  1128. } bind def
  1129. % - .pickcmap -
  1130. % Defines cmapsub, cmaptab
  1131. /.pickcmap {
  1132. % Currently we use xlatmap only for emulation CIDFontType 2 with
  1133. % a disk True Type font files, and use load_stripped
  1134. % to check this regime. We would like to do so
  1135. % while emulating a Type 42, but first the old code
  1136. % about handling them to be changed
  1137. % with adding a handling of a Decoding.
  1138. % fixme : A correct way to fix this is to implenent
  1139. % the Type 42 emulation with gs_fntem.ps .
  1140. % Also note that PDF embedded fonts probably don't need a xlatmap -
  1141. % see PDF spec, "Encodings for True Type fonts".
  1142. load_stripped {
  1143. //.pickcmap_with_xlatmap exec
  1144. } {
  1145. //.pickcmap_with_no_xlatmap exec
  1146. } ifelse
  1147. } bind def
  1148. % <glyph> .nname <_name>
  1149. /.nname {
  1150. =string cvs (_) exch concatstrings cvn
  1151. } bind def
  1152. % Provide alternative backward-compatible names for new TTF glyphs.
  1153. % This list was extracted from Adobe's Glyph List 2.0 and consists of
  1154. % glyph names that map to the same Unicode value.
  1155. % See: http://partners.adobe.com/asn/developer/typeforum/unicodegn.html
  1156. /postalias mark
  1157. /pi1 /pi /plusinus /plusminus
  1158. /Acyrillic /afii10017 /Becyrillic /afii10018
  1159. /Cdot /Cdotaccent /Checyrillic /afii10041
  1160. /Dcroat /Dslash /Decyrillic /afii10021
  1161. /Delta /increment /Djecyrillic /afii10051
  1162. /Dzecyrillic /afii10054 /Dzhecyrillic /afii10145
  1163. /Ecyrillic /afii10053 /Edot /Edotaccent
  1164. /Efcyrillic /afii10038 /Elcyrillic /afii10029
  1165. /Emcyrillic /afii10030 /Encyrillic /afii10031
  1166. /Ercyrillic /afii10034 /Ereversedcyrillic /afii10047
  1167. /Escyrillic /afii10035 /Euro /euro
  1168. /Fitacyrillic /afii10147 /Gcedilla /Gcommaaccent
  1169. /Gdot /Gdotaccent /Gecyrillic /afii10020
  1170. /Gheupturncyrillic /afii10050 /Gjecyrillic /afii10052
  1171. /H18533 /blackcircle /H18543 /blacksmallsquare
  1172. /H18551 /whitesmallsquare /H22073 /whitesquare
  1173. /Hardsigncyrillic /afii10044 /IAcyrillic /afii10049
  1174. /IUcyrillic /afii10048 /Icyrillic /afii10055
  1175. /Idot /Idotaccent /Iecyrillic /afii10022
  1176. /Iicyrillic /afii10026 /Iishortcyrillic /afii10027
  1177. /Iocyrillic /afii10023 /Izhitsacyrillic /afii10148
  1178. /Jecyrillic /afii10057 /Kacyrillic /afii10028
  1179. /Kcedilla /Kcommaaccent /Khacyrillic /afii10039
  1180. /Kjecyrillic /afii10061 /Lcedilla /Lcommaaccent
  1181. /Ldot /Ldotaccent /Ljecyrillic /afii10058
  1182. /Ncedilla /Ncommaaccent /Njecyrillic /afii10059
  1183. /Ocyrillic /afii10032 /Odblacute /Ohungarumlaut
  1184. /Ohm /Omega /Oslashacute /Ostrokeacute
  1185. /Pecyrillic /afii10033 /Rcedilla /Rcommaaccent
  1186. /Shacyrillic /afii10042 /Shchacyrillic /afii10043
  1187. /Softsigncyrillic /afii10046 /Tcedilla /Tcommaaccent
  1188. /Tecyrillic /afii10036 /Tsecyrillic /afii10040
  1189. /Tshecyrillic /afii10060 /Ucyrillic /afii10037
  1190. /Udblacute /Uhungarumlaut /Upsilon1 /Upsilonhooksymbol
  1191. /Ushortcyrillic /afii10062 /Vecyrillic /afii10019
  1192. /Yatcyrillic /afii10146 /Yericyrillic /afii10045
  1193. /Yicyrillic /afii10056 /Zdot /Zdotaccent
  1194. /Zecyrillic /afii10025 /Zhecyrillic /afii10024
  1195. /acutecmb /acutecomb /acyrillic /afii10065
  1196. /afii00208 /horizontalbar /afii08941 /lira
  1197. /afii10066 /becyrillic /afii10067 /vecyrillic
  1198. /afii10068 /gecyrillic /afii10069 /decyrillic
  1199. /afii10070 /iecyrillic /afii10071 /iocyrillic
  1200. /afii10072 /zhecyrillic /afii10073 /zecyrillic
  1201. /afii10074 /iicyrillic /afii10075 /iishortcyrillic
  1202. /afii10076 /kacyrillic /afii10077 /elcyrillic
  1203. /afii10078 /emcyrillic /afii10079 /encyrillic
  1204. /afii10080 /ocyrillic /afii10081 /pecyrillic
  1205. /afii10082 /ercyrillic /afii10083 /escyrillic
  1206. /afii10084 /tecyrillic /afii10085 /ucyrillic
  1207. /afii10086 /efcyrillic /afii10087 /khacyrillic
  1208. /afii10088 /tsecyrillic /afii10089 /checyrillic
  1209. /afii10090 /shacyrillic /afii10091 /shchacyrillic
  1210. /afii10092 /hardsigncyrillic /afii10093 /yericyrillic
  1211. /afii10094 /softsigncyrillic /afii10095 /ereversedcyrillic
  1212. /afii10096 /iucyrillic /afii10097 /iacyrillic
  1213. /afii10098 /gheupturncyrillic /afii10099 /djecyrillic
  1214. /afii10100 /gjecyrillic /afii10101 /ecyrillic
  1215. /afii10102 /dzecyrillic /afii10103 /icyrillic
  1216. /afii10104 /yicyrillic /afii10105 /jecyrillic
  1217. /afii10106 /ljecyrillic /afii10107 /njecyrillic
  1218. /afii10108 /tshecyrillic /afii10109 /kjecyrillic
  1219. /afii10110 /ushortcyrillic /afii10193 /dzhecyrillic
  1220. /afii10194 /yatcyrillic /afii10195 /fitacyrillic
  1221. /afii10196 /izhitsacyrillic /afii10846 /schwacyrillic
  1222. /afii57381 /percentarabic /afii57388 /commaarabic
  1223. /afii57392 /zeroarabic /afii57393 /onearabic
  1224. /afii57394 /twoarabic /afii57395 /threearabic
  1225. /afii57396 /fourarabic /afii57397 /fivearabic
  1226. /afii57398 /sixarabic /afii57399 /sevenarabic
  1227. /afii57400 /eightarabic /afii57401 /ninearabic
  1228. /afii57403 /semicolonarabic /afii57407 /questionarabic
  1229. /afii57409 /hamzaarabic /afii57410 /alefmaddaabovearabic
  1230. /afii57411 /alefhamzaabovearabic /afii57412 /wawhamzaabovearabic
  1231. /afii57413 /alefhamzabelowarabic /afii57414 /yehhamzaabovearabic
  1232. /afii57415 /alefarabic /afii57416 /beharabic
  1233. /afii57417 /tehmarbutaarabic /afii57418 /teharabic
  1234. /afii57419 /theharabic /afii57420 /jeemarabic
  1235. /afii57421 /haharabic /afii57422 /khaharabic
  1236. /afii57423 /dalarabic /afii57424 /thalarabic
  1237. /afii57425 /reharabic /afii57426 /zainarabic
  1238. /afii57427 /seenarabic /afii57428 /sheenarabic
  1239. /afii57429 /sadarabic /afii57430 /dadarabic
  1240. /afii57431 /taharabic /afii57432 /zaharabic
  1241. /afii57433 /ainarabic /afii57434 /ghainarabic
  1242. /afii57440 /tatweelarabic /afii57441 /feharabic
  1243. /afii57442 /qafarabic /afii57443 /kafarabic
  1244. /afii57444 /lamarabic /afii57445 /meemarabic
  1245. /afii57446 /noonarabic /afii57448 /wawarabic
  1246. /afii57449 /alefmaksuraarabic /afii57450 /yeharabic
  1247. /afii57451 /fathatanarabic /afii57452 /dammatanarabic
  1248. /afii57453 /kasratanarabic /afii57454 /fathaarabic
  1249. /afii57455 /dammaarabic /afii57456 /kasraarabic
  1250. /afii57457 /shaddaarabic /afii57458 /sukunarabic
  1251. /afii57470 /heharabic /afii57505 /veharabic
  1252. /afii57506 /peharabic /afii57507 /tcheharabic
  1253. /afii57508 /jeharabic /afii57509 /gafarabic
  1254. /afii57511 /tteharabic /afii57512 /ddalarabic
  1255. /afii57513 /rreharabic /afii57514 /noonghunnaarabic
  1256. /afii57519 /yehbarreearabic /afii57636 /newsheqelsign
  1257. /afii57645 /maqafhebrew /afii57658 /sofpasuqhebrew
  1258. /afii57664 /alef /afii57665 /bet
  1259. /afii57666 /gimel /afii57667 /dalet
  1260. /afii57668 /he /afii57669 /vav
  1261. /afii57670 /zayin /afii57671 /het
  1262. /afii57672 /tet /afii57673 /yod
  1263. /afii57674 /finalkaf /afii57675 /kaf
  1264. /afii57676 /lamed /afii57677 /finalmem
  1265. /afii57678 /mem /afii57679 /finalnun
  1266. /afii57680 /nun /afii57681 /samekh
  1267. /afii57682 /ayin /afii57683 /finalpe
  1268. /afii57684 /pe /afii57685 /finaltsadi
  1269. /afii57686 /tsadi /afii57687 /qof
  1270. /afii57688 /resh /afii57689 /shin
  1271. /afii57690 /tav /afii57694 /shinshindot
  1272. /afii57695 /shinsindot /afii57700 /vavholam
  1273. /afii57705 /doubleyodpatah /afii57716 /vavvavhebrew
  1274. /afii57717 /vavyodhebrew /afii57718 /yodyodhebrew
  1275. /afii57723 /vavdagesh /afii57793 /hiriq
  1276. /afii57794 /tsere /afii57795 /segol
  1277. /afii57796 /qubuts /afii57797 /qamats
  1278. /afii57798 /patah /afii57799 /sheva
  1279. /afii57800 /hatafpatah /afii57801 /hatafsegol
  1280. /afii57802 /hatafqamats /afii57803 /sindothebrew
  1281. /afii57804 /shindothebrew /afii57806 /holam
  1282. /afii57807 /dagesh /afii57839 /siluqhebrew
  1283. /afii57841 /rafe /afii57842 /paseqhebrew
  1284. /afii57929 /apostrophemod /afii61248 /careof
  1285. /afii61289 /lsquare /afii61352 /numero
  1286. /afii61664 /zerowidthnonjoiner /afii63167 /asteriskarabic
  1287. /afii64937 /commareversedmod /alefmaksurainitialarabic /yehinitialarabic
  1288. /alefmaksuramedialarabic /yehmedialarabic /approximatelyequal /congruent
  1289. /arrowdblboth /dblarrowleft /arrowdblleft /arrowleftdbl
  1290. /arrowdblright /dblarrowright /arrowupdnbse /arrowupdownbase
  1291. /bar /verticalbar /betdagesh /betdageshhebrew
  1292. /blackdownpointingtriangle /triagdn /blackleftpointingpointer /triaglf
  1293. /blackrectangle /filledrect /blackrightpointingpointer /triagrt
  1294. /blacksmilingface /invsmileface /blacksquare /filledbox
  1295. /blackuppointingtriangle /triagup /bulletinverse /invbullet
  1296. /cdot /cdotaccent /circle /whitecircle
  1297. /circlemultiply /timescircle /circleplus /pluscircle
  1298. /club /clubsuitblack /colonmonetary /colonsign
  1299. /compass /sun /daletdagesh /daletdageshhebrew
  1300. /dargahebrew /dargalefthebrew /dbllowline /underscoredbl
  1301. /dcroat /dmacron /decimalseparatorarabic /decimalseparatorpersian
  1302. /dialytikatonos /dieresistonos /dkshade /shadedark
  1303. /dotbelowcmb /dotbelowcomb /edot /edotaccent
  1304. /eighthnotebeamed /musicalnotedbl /etnahtafoukhhebrew /etnahtahebrew
  1305. /existential /thereexists /female /venus
  1306. /finalkafdagesh /finalkafdageshhebrew /forall /universal
  1307. /gcedilla /gcommaaccent /gdot /gdotaccent
  1308. /gimeldagesh /gimeldageshhebrew /gradient /nabla
  1309. /gravecmb /gravecomb /haaltonearabic /hehaltonearabic
  1310. /heart /heartsuitblack /hedagesh /hedageshhebrew
  1311. /hehfinalalttwoarabic /hehfinalarabic /hookabovecomb /hookcmb
  1312. /ilde /tilde /integralbottom /integralbt
  1313. /integraltop /integraltp /invcircle /whitecircleinverse
  1314. /kafdagesh /kafdageshhebrew /kcedilla /kcommaaccent
  1315. /lameddagesh /lameddageshhebrew /lcedilla /lcommaaccent
  1316. /ldot /ldotaccent /logicalnotreversed /revlogicalnot
  1317. /longs /slong /ltshade /shadelight
  1318. /macron /overscore /mahapakhhebrew /mahapakhlefthebrew
  1319. /male /mars /memdagesh /memdageshhebrew
  1320. /merkhahebrew /merkhalefthebrew /merkhakefulahebrew /merkhakefulalefthebrew
  1321. /middot /periodcentered /mu /mu1
  1322. /munahhebrew /munahlefthebrew /napostrophe /quoterightn
  1323. /nbspace /nonbreakingspace /ncedilla /ncommaaccent
  1324. /notelement /notelementof /nundagesh /nundageshhebrew
  1325. /odblacute /ohungarumlaut /omega1 /pisymbolgreek
  1326. /openbullet /whitebullet /orthogonal /rightangle
  1327. /oslashacute /ostrokeacute /pedagesh /pedageshhebrew
  1328. /phi1 /phisymbolgreek /propersubset /subset
  1329. /propersuperset /superset /qofdagesh /qofdageshhebrew
  1330. /quoteleftreversed /quotereversed /rcedilla /rcommaaccent
  1331. /reflexsubset /subsetorequal /reflexsuperset /supersetorequal
  1332. /reviahebrew /reviamugrashhebrew /samekhdagesh /samekhdageshhebrew
  1333. /sfthyphen /softhyphen /shade /shademedium
  1334. /sheqel /sheqelhebrew /shindagesh /shindageshhebrew
  1335. /shindageshshindot /shindageshshindothebrew /shindageshsindot /shindageshsindothebrew
  1336. /sigma1 /sigmafinal /similar /tildeoperator
  1337. /smileface /whitesmilingface /space /spacehackarabic
  1338. /spade /spadesuitblack /tavdages /tavdagesh
  1339. /tcedilla /tcommaaccent /tetdagesh /tetdageshhebrew
  1340. /tevirhebrew /tevirlefthebrew /theta1 /thetasymbolgreek
  1341. /thousandsseparatorarabic /thousandsseparatorpersian /tildecmb /tildecomb
  1342. /tipehahebrew /tipehalefthebrew /tsadidagesh /tsadidageshhebrew
  1343. /twodotenleader /twodotleader /udblacute /uhungarumlaut
  1344. /yerahbenyomohebrew /yerahbenyomolefthebrew /yoddagesh /yoddageshhebrew
  1345. /zayindagesh /zayindageshhebrew /zdot /zdotaccent
  1346. .dicttomark readonly def
  1347. % - .charkeys /CharStrings <charstrings> /Encoding <encoding>
  1348. % Resets glyphencoding
  1349. /.charkeys {
  1350. TTFDEBUG {
  1351. (glyphencoding: length=) print glyphencoding dup length = === flush
  1352. } if
  1353. % Hack: if there is no usable post table but the cmap uses
  1354. % the Microsoft Unicode encoding, use ISOLatin1Encoding.
  1355. % if 'post' presents, .charkeys computes (with dropping minor details) :
  1356. % CharStrings = glyphencoding^-1
  1357. % Encoding = cmap*glyphencoding
  1358. % because 'post' maps glyph indices to glyph names.
  1359. % Otherwise .charkeys must compute (with dropping same details) :
  1360. % CharStrings = glyphencoding^-1 * cmap
  1361. % Encoding = glyphencoding
  1362. % because glyphencoding is stubbed with an encoding,
  1363. % which maps char codes to glyph names.
  1364. glyphencoding length 0 eq {
  1365. /have_post false def
  1366. cmapsub 0 4 getinterval <00030001> eq {
  1367. PDFDEBUG { (No post but have cmap 3.1, so use ISOLatin1Encoding) = } if
  1368. /glyphencoding ISOLatin1Encoding dup length array copy def
  1369. } {
  1370. PDFDEBUG { (No encoding info, use .GS_extended_SymbolEncoding) = } if
  1371. /glyphencoding /.GS_extended_SymbolEncoding findencoding dup length array copy def
  1372. } ifelse
  1373. } {
  1374. /have_post true def
  1375. } ifelse
  1376. % If necessary, fabricate additional glyphencoding entries
  1377. % to cover all of loca
  1378. glyphencoding length numloca lt {
  1379. /glyphencoding numloca array
  1380. glyphencoding length dup 1 sub 0 1 3 2 roll {
  1381. dup glyphencoding exch get
  1382. 3 index 3 1 roll put
  1383. } for
  1384. % /glyphencoding <newarray> <glyphencoding length>
  1385. 1 numloca 1 sub {
  1386. 1 index exch dup .nname put
  1387. } for
  1388. def
  1389. } if
  1390. /cmapa cmaptab cmaparray def
  1391. % Some badly designed Chinese fonts have a post table
  1392. % in which all glyphs other than 0 are named .null.
  1393. % Use CharStrings to keep track of the reverse map from
  1394. % names to glyphs, and don't let any name be used for
  1395. % more than one glyph.
  1396. /CharStrings glyphencoding dup length 1 add dict % +1 for .notdef
  1397. 0 1 3 index length 1 sub {
  1398. % Stack: glyphencoding dict index
  1399. 2 index 1 index get
  1400. have_post not {
  1401. exch
  1402. cmapa exch .knownget not {
  1403. 0 % a stub for a while. Must skip the entry.
  1404. } if
  1405. exch
  1406. } if
  1407. 2 index 1 index known
  1408. { % The same name maps to more than one glyph. Change the name.
  1409. % No special treatment for /.notdef glyph. Bug 689408.
  1410. pop dup .nname 3 index 2 index 2 index put
  1411. 2 index exch 3 -1 roll put
  1412. } {
  1413. 2 index exch 3 -1 roll put % unique name
  1414. } ifelse
  1415. } for exch pop
  1416. % If there is no .notdef entry, map it to glyph 0.
  1417. dup /.notdef known not { dup /.notdef 0 put } if
  1418. TTFDEBUG {
  1419. (CharStrings:)= dup { exch =string cvs print ( ) print == } forall
  1420. } if
  1421. //postalias {
  1422. % process pairs of names. If both names are known, do nothing. Otherwise
  1423. % make the name that is not defined an alias for the one that does exist.
  1424. % Stack: CharStrings(dict) /name1 /name2
  1425. 2 index 2 index known 3 index 2 index known 1 index xor not {
  1426. pop pop pop % both names known or neither known
  1427. } {
  1428. % Stack: CharStrings(dict) /name1 /name2 name1_known(bool)
  1429. { exch } if % /name1 known -- we need it on top
  1430. % Stack: CharStrings(dict) /alias_name /known_name
  1431. TTFDEBUG { (setting alias: ) print 1 index ==only ( to be the same as glyph: ) print dup == } if
  1432. 2 index exch get 2 index 3 1 roll put
  1433. } ifelse
  1434. } forall
  1435. readonly
  1436. /Encoding [
  1437. have_post {
  1438. 0 1 255 {
  1439. cmapa exch .knownget not { 0 } if
  1440. glyphencoding dup length
  1441. 2 index le {
  1442. pop pop /.notdef
  1443. } {
  1444. exch get
  1445. } ifelse
  1446. } for
  1447. } {
  1448. glyphencoding dup length 256 gt { 0 256 getinterval } if
  1449. aload pop
  1450. counttomark 256 exch sub { /.notdef } repeat
  1451. } ifelse
  1452. ]
  1453. TTFDEBUG { (Encoding: ) print dup === flush } if
  1454. } bind def
  1455. currentdict /postalias undef
  1456. % <file> .loadttfont <type42font>
  1457. /.loadttfont {
  1458. TTFDEBUG { (.loadttfont) = } if
  1459. //false 0 .loadttfonttables
  1460. .makesfnts
  1461. .getpost
  1462. .pickcmap
  1463. mark
  1464. .charkeys
  1465. .ttkeys
  1466. /FontType 42
  1467. /PaintType 0
  1468. TTFDEBUG {
  1469. (numloca=) print numloca =
  1470. } if
  1471. .dicttomark
  1472. end end dup /FontName get exch definefont
  1473. } bind def
  1474. % ---------------- CIDFontType 2 font loading ---------------- %
  1475. % Fill a string with sequential CIDs starting from the initial value.
  1476. % <string> <value> .fill_identity_cmap <string>
  1477. /.fill_identity_cmap { % () v
  1478. 1 index length 2 sub % () v n-2
  1479. 0 2 3 2 roll { % () v 0 2 n-1
  1480. 3 copy exch % () v i () i v
  1481. -8 bitshift % () v i () i v>>8
  1482. put % () v i
  1483. 3 copy 1 add % () v i () v i+1
  1484. exch 255 and % () v i () i+1 v&255
  1485. put % () v i
  1486. pop 1 add % () v+1
  1487. } for
  1488. pop
  1489. } bind def
  1490. % <dict> .definettcidfont <font>
  1491. /.definettcidfont {
  1492. dup begin
  1493. /CIDFontName fontname def
  1494. /CIDFontType 2 def
  1495. /CIDSystemInfo mark
  1496. /Registry (Adobe)
  1497. /Ordering (Japan1) % adhoc
  1498. /Supplement 0
  1499. .dicttomark def
  1500. /CharStrings mark /.notdef 0 .dicttomark def
  1501. % The cmap isn't of any use even if it is present.
  1502. % Just construct an identity CIDMap covering all the glyphs.
  1503. /CIDCount numloca % Wrong if a CIDFontType2 embedded into PDF with a non-Identity CIDToGIDMap.
  1504. def % processCIDToGIDMap may replace.
  1505. /CIDMap numloca maxstring le {
  1506. % Use a single string.
  1507. numloca 2 mul string 0 .fill_identity_cmap
  1508. } {
  1509. % We must use 2 strings.
  1510. maxstring 2 mul string 0 .fill_identity_cmap
  1511. numloca maxstring sub 2 mul string maxstring .fill_identity_cmap
  1512. 2 array astore
  1513. } ifelse
  1514. def
  1515. /GDBytes 2 def
  1516. end
  1517. end end dup /CIDFontName get exch /CIDFont defineresource
  1518. } bind def
  1519. % <file> <Substite name> .loadttcidfont <cidtype2font>
  1520. /.loadttcidfont {
  1521. exch
  1522. //false 0 .loadttfonttables
  1523. .makesfnts
  1524. % CIDFontType2 fonts don't have a cmap: they are indexed by CID.
  1525. mark
  1526. .ttkeys
  1527. .dicttomark dup % convert keys to dict and copy dict
  1528. 3 -1 roll % Bring PDF substitute name to top of stack
  1529. dup
  1530. /fontname exch def
  1531. /FontName exch put % replace any definition of /FontName
  1532. .definettcidfont
  1533. } bind def
  1534. % <file> <SubfontID> .load_tt_font_stripped <font_data>
  1535. % The font_data includes sfnts, NumGlyphs, TT_cmap, file_table_pos, Decoding.
  1536. % CIDMap to be created later from TT_cmap.
  1537. /.load_tt_font_stripped {
  1538. //true exch .loadttfonttables
  1539. .makesfnts
  1540. .pickcmap
  1541. mark
  1542. .ttkeys
  1543. /NumGlyphs numloca
  1544. /TT_cmap cmaptab cmaparray
  1545. /file_table_pos file_table_pos
  1546. /Decoding Decoding
  1547. .dicttomark
  1548. end end
  1549. } bind def
  1550. % ---------------- PDF TrueType font loading ---------------- %
  1551. % Strictly speaking, this code should be loaded only if we have a PDF
  1552. % interpreter, but it's so closely tied to the rest of the code in this
  1553. % file that we always include it.
  1554. % <plat+enc> .findcmap <subtable> true
  1555. % <plat+enc> .findcmap false
  1556. /.findcmap {
  1557. false exch tabdict /cmap get
  1558. % Some fonts have multiple cmaps with the same platform and
  1559. % encoding. Use the first one we find.
  1560. 0 1 2 index 2 getu16a 1 sub {
  1561. % Stack: false plat+enc cmap index
  1562. 8 mul 4 add 1 index exch 8 getinterval_from_stringarray
  1563. dup 0 4 getinterval 3 index eq {
  1564. 4 getu32 1 index exch 1 index string_array_size 1 index sub getinterval_from_stringarray
  1565. 4 -1 roll not 4 2 roll exit
  1566. } if pop
  1567. } for
  1568. % Stack: false plat+enc cmap || subtable true plat+enc cmap
  1569. pop pop
  1570. } bind def
  1571. % Build .symbol_list for .pdfcharkeys .
  1572. % It is a dictionary containing all SymbolEncoding glyph names
  1573. % and random names for filling gaps in the character code range.
  1574. /.symbol_list 256 dict def
  1575. {
  1576. =string 0 (x) 0 get put
  1577. /SymbolEncoding .findencoding
  1578. 0 1 255 {
  1579. dup 2 index exch get
  1580. dup /.notdef eq {
  1581. pop dup
  1582. =string 1 3 getinterval cvs length 1 add
  1583. =string exch 0 exch getinterval cvn
  1584. } if
  1585. exch //.symbol_list 3 1 roll put
  1586. } for
  1587. pop
  1588. } bind exec
  1589. % Create .GS_extended_SymbolEncoding as inverse of .symbol_list .
  1590. {
  1591. /.GS_extended_SymbolEncoding 256 array
  1592. //.symbol_list {
  1593. exch 2 index 3 1 roll put
  1594. } forall
  1595. .defineencoding
  1596. } bind exec
  1597. /.hexdigits (0123456789ABCDEF) def
  1598. /.is_hex_digit { % <int> .is_hex_digit <bool>
  1599. dup 48 ge exch
  1600. dup 57 le exch
  1601. dup 65 ge exch
  1602. 70 le and
  1603. 3 1 roll
  1604. and or
  1605. } bind def
  1606. /.popfex { pop //false exit } bind def
  1607. /.pop3ex { pop pop pop exit } bind def
  1608. /.addglyph { % <dict> <name> <glyph#> .addglyph -
  1609. 1 index .namestring % d n g s
  1610. dup length 7 eq {
  1611. % Bug688467.ps doesn't work if the uniXXXX mapping is allowed with any cmap.
  1612. % Allow it with cmap 3.1 only.
  1613. currentdict /.allow_uniXXXX_glyph_names .knownget not { //false } if
  1614. } { //false
  1615. } ifelse % d n g s b
  1616. {
  1617. % An undocumented Adobe feature (not sure) :
  1618. % if the name is uniXXXX, obtain Unicode code from it.
  1619. % See bug 688946.
  1620. TTFDEBUG { (Try uniXXXX:) print dup print } if
  1621. { dup 0 get 117 ne //.popfex if % u
  1622. dup 1 get 110 ne //.popfex if % n
  1623. dup 2 get 105 ne //.popfex if % i
  1624. dup 3 get //.is_hex_digit exec not //.popfex if
  1625. dup 4 get //.is_hex_digit exec not //.popfex if
  1626. dup 5 get //.is_hex_digit exec not //.popfex if
  1627. dup 6 get //.is_hex_digit exec not //.popfex if
  1628. dup 3 1 getinterval .hexdigits exch search pop length exch pop exch pop 12 bitshift exch
  1629. dup 4 1 getinterval .hexdigits exch search pop length exch pop exch pop 8 bitshift exch
  1630. dup 5 1 getinterval .hexdigits exch search pop length exch pop exch pop 4 bitshift exch
  1631. dup 6 1 getinterval .hexdigits exch search pop length exch pop exch pop exch pop
  1632. add add add
  1633. cmapencoding exch .knownget not { 0 } if
  1634. dup 0 eq //.popfex if
  1635. TTFDEBUG { ( index=) print dup =string cvs print } if
  1636. exch pop
  1637. put //true exit
  1638. } loop
  1639. TTFDEBUG { ()= } if
  1640. } {
  1641. pop //false
  1642. } ifelse
  1643. not { % d n g
  1644. {
  1645. cmapencoding exch .knownget not { 0 } if
  1646. dup 0 eq //.pop3ex if
  1647. 3 copy pop known //.pop3ex if
  1648. put exit
  1649. } loop
  1650. } if
  1651. } bind def
  1652. % <subcmap> <chartoglyphmap> .pdfmapchars /CharStrings <charstrings>
  1653. /.pdfmapchars {
  1654. exch cmaparray /cmapencoding exch def % c2g
  1655. /CharStrings 0 dict % c2g /CS <<>>
  1656. % Add glyphs of <chartoglyphmap>*<subcmap> :
  1657. 3 2 roll { % /CS <<>> v
  1658. dup type /arraytype eq { % /CS <<>> /name []
  1659. { 3 copy //.addglyph exec
  1660. pop
  1661. } forall
  1662. } {
  1663. 3 copy //.addglyph exec pop
  1664. } ifelse
  1665. pop
  1666. } forall
  1667. % Add glyphs of 'post' with lower priority :
  1668. 0 1 glyphencoding length 1 sub {
  1669. dup glyphencoding exch get exch
  1670. dup 0 ne {
  1671. 3 copy pop known not {
  1672. 3 copy put
  1673. } if
  1674. } if
  1675. pop pop
  1676. } for
  1677. dup /.notdef 0 put
  1678. } bind def
  1679. % <subtable> .pdfmapsymbolic /Encoding [] /CharStrings <<>>
  1680. /.pdfmapsymbolic {
  1681. cmaparray
  1682. dup length 1 add dict begin
  1683. [ 64 { /.notdef /.notdef /.notdef /.notdef } repeat ]
  1684. exch { % char glyph
  1685. exch 255 and % glyph char
  1686. dup 16 (01234567) cvrs cvn % glyph char /char
  1687. 3 1 roll % /char glyph char
  1688. 3 index exch % /char glyph [] char
  1689. 3 index put % /char glyph
  1690. def % -
  1691. } forall
  1692. /.notdef 0 def
  1693. /Encoding exch
  1694. /CharStrings currentdict end
  1695. } bind def
  1696. % - .pdfcharkeys /CharStrings <charstrings> /Encoding <encoding>
  1697. /.pdfcharkeys {
  1698. % The following algorithms are per the PDF 1.7 Reference.
  1699. TTFDEBUG { (.pdfcharkeys beg) = } if
  1700. is_symbolic {
  1701. <00030000> .findcmap { //true } { <00010000> .findcmap } ifelse {
  1702. .pdfmapsymbolic
  1703. } {
  1704. % This is illegal with PDF spec.
  1705. ( **** Warning: Embedded symbolic TT fonts must contain a cmap for Platform=1,3 Encoding=0.\n)
  1706. pdfformaterror
  1707. % Apply the default algorithm. Hopely it has 'post'.
  1708. .charkeys
  1709. % check if the CharStrings dict contains glyphs needed by the
  1710. % prebuilt_encoding otherwise try the 3,0 cmap.
  1711. prebuilt_encoding null ne {
  1712. false prebuilt_encoding { % false means no missing glyphs
  1713. 4 index exch known not { pop true exit } if
  1714. } forall
  1715. {
  1716. ( **** Warning: Encoding derived from 'post' is incomplete.\n) pdfformaterror
  1717. } if
  1718. } if
  1719. } ifelse
  1720. } {
  1721. <00030001> .findcmap {
  1722. prebuilt_encoding null ne {
  1723. TTFDEBUG { (Using cmap 3.1 with prebuilt_encoding for non-symbolic.) = } if
  1724. % The character code in /prebuilt_encoding[] is not guaranteed to be
  1725. % compatible with the Microsoft UCS2 TrueType cmap subtable.
  1726. % If the glyphname is known by AdobeGlyphList, the charcode for the glyph
  1727. % is replaced by UCS2 charcode from AdobeGlyphList. Otherwise it is left
  1728. % as in /prebuilt_encoding[]. /.pdfmapchars should dredge them.
  1729. /.allow_uniXXXX_glyph_names //true def
  1730. AdobeGlyphList prebuilt_encoding .invert_encoding dup { % <<AGL>> <<pbe>> <glyphname> <pbecode>
  1731. pop % <<AGL>> <<pbe>> <glyphname>
  1732. TTFDEBUG { (check glypname /) print dup =only flush } if
  1733. 2 index 1 index .knownget { % <<AGL>> <<pbe>> <glyphname> <AGLcode>
  1734. 2 index 3 1 roll % <<AGL>> <<pbe>> <<pbe>> <glyphname> <AGLcode>
  1735. TTFDEBUG { ( redefine codepoint by AdobeGlyphList, ) print dup == flush } if
  1736. put % <<AGL>> <<pbe>>
  1737. } { % <<AGL>> <<pbe>> <glyphname>
  1738. TTFDEBUG { ( unknown glyphname, leave as it is ) print flush } if
  1739. pop % <<AGL>> <<pbe>>
  1740. } ifelse
  1741. } forall
  1742. exch pop % <<pbe>>
  1743. TTFDEBUG { dup (<<\n) print { exch ( ) print =only (\t) print == } forall (>>\n) print flush } if
  1744. .pdfmapchars
  1745. /Encoding prebuilt_encoding
  1746. } {
  1747. % Likely this branch is now obsolete.
  1748. TTFDEBUG { (Using cmap 3.1 for non-symbolic.) = } if
  1749. AdobeGlyphList .pdfmapchars
  1750. /Encoding /WinAnsiEncoding .findencoding
  1751. % WinAnsiEncoding is just a stub here.
  1752. % It will be replaced with one from font resource,
  1753. % because PDF spec requires it.
  1754. } ifelse
  1755. } {
  1756. <00010000> .findcmap {
  1757. TTFDEBUG { (Using cmap 1.0 for non-symbolic.) = } if
  1758. .romanmacdict .pdfmapchars
  1759. /Encoding
  1760. prebuilt_encoding null ne {
  1761. prebuilt_encoding
  1762. } {
  1763. /MacRomanEncodingForTrueType .findencoding
  1764. } ifelse
  1765. } {
  1766. % Apply the default algorithm for using the 'post'.
  1767. .charkeys
  1768. % But use PDF encoding when available.
  1769. prebuilt_encoding //null ne {
  1770. pop prebuilt_encoding
  1771. } if
  1772. } ifelse
  1773. } ifelse
  1774. } ifelse
  1775. TTFDEBUG { (.pdfcharkeys end) = } if
  1776. } bind def
  1777. % <file> <is_symbolic> <Encoding|null> .loadpdfttfont <type42font>
  1778. /.loadpdfttfont {
  1779. TTFDEBUG { (.loadpdfttfont Encoding=) print dup == } if
  1780. /prebuilt_encoding gput % for .pdfcharkeys
  1781. /is_symbolic gput
  1782. //false 0 .loadttfonttables
  1783. .makesfnts
  1784. tabdict /cmap known not {
  1785. ( **** Warning: Embedded TT font lacks required cmap table. Using identity cmap.\n)
  1786. pdfformaterror
  1787. % Unknown (i.e. not 0 ) language ID brings in post table.
  1788. % Fields: cmap_version, number_of_subtables,
  1789. % plarform_id, encoding_id, offset,
  1790. % format, subtable_length, language,
  1791. % 256 bytes of identity mapping.
  1792. tabdict /cmap
  1793. < 0000 0001
  1794. 0001 D00D 0000000c
  1795. 0000 0106 0000
  1796. 00 01 02 03 04 05 06 07 08 09 0a 0d 0c 0d 0e 0f
  1797. 10 11 12 13 14 15 16 17 18 19 1a 1d 1c 1d 1e 1f
  1798. 20 21 22 23 24 25 26 27 28 29 2a 2d 2c 2d 2e 2f
  1799. 30 31 32 33 34 35 36 37 38 39 3a 3d 3c 3d 3e 3f
  1800. 40 41 42 43 44 45 46 47 48 49 4a 4d 4c 4d 4e 4f
  1801. 50 51 52 53 54 55 56 57 58 59 5a 5d 5c 5d 5e 5f
  1802. 60 61 62 63 64 65 66 67 68 69 6a 6d 6c 6d 6e 6f
  1803. 70 71 72 73 74 75 76 77 78 79 7a 7d 7c 7d 7e 7f
  1804. 80 81 82 83 84 85 86 87 88 89 8a 8d 8c 8d 8e 8f
  1805. 90 91 92 93 94 95 96 97 98 99 9a 9d 9c 9d 9e 9f
  1806. a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ad ac ad ae af
  1807. b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bd bc bd be bf
  1808. c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cd cc cd ce cf
  1809. d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da dd dc dd de df
  1810. e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea ed ec ed ee ef
  1811. f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fd fc fd fe ff
  1812. > readonly put
  1813. } if
  1814. .getpost
  1815. .pickcmap
  1816. mark
  1817. .pdfcharkeys
  1818. .ttkeys
  1819. /FontType 42
  1820. /PaintType 0
  1821. TTFDEBUG {
  1822. (numloca=) print numloca =
  1823. } if
  1824. .dicttomark
  1825. end end
  1826. .completefont
  1827. } bind def