t1asm.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. <?php
  2. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  3. * PHP class t1asm (for mPDF) *
  4. * *
  5. * Version: 1.2 *
  6. * Date: 2010-04-12 *
  7. * Author: Ian Back <ianb@bpm1.com> *
  8. * License: LGPL *
  9. * *
  10. * The idea and some of the code has been ported from the t1utils scripts *
  11. * http://www.lcdf.org/type/#t1utils *
  12. * The original copyright notice is reproduced below *
  13. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  14. /* t1utils
  15. *
  16. * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
  17. *
  18. * Permission is hereby granted to use, modify, and distribute this program
  19. * for any purpose provided this copyright notice and the one below remain
  20. * intact.
  21. *
  22. * I. Lee Hetherington (ilh@lcs.mit.edu)
  23. *
  24. * 1.5 and later versions contain changes by, and are maintained by,
  25. * Eddie Kohler <ekohler@gmail.com>.
  26. *
  27. * Ported to Microsoft C/C++ Compiler and MS-DOS operating system by
  28. * Kai-Uwe Herbing (herbing@netmbx.netmbx.de) on June 12, 1992. Code
  29. * specific to the MS-DOS version is encapsulated with #ifdef _MSDOS
  30. * ... #endif, where _MSDOS is an identifier, which is automatically
  31. * defined, if you compile with the Microsoft C/C++ Compiler.
  32. *
  33. */
  34. /*
  35. SAMPLE USE OF tiasm
  36. $asm = new t1asm();
  37. $asm->LoadFontFile('originalfont'); // Loads originalfont.t1a and looks for (optional) originalfont.ufm for glyph name map
  38. // Override fontnames if required
  39. $asm->SetFontName('mPDF__001');
  40. $asm->SetFamilyName('mPDF');
  41. $asm->SetFullName('mPDF__001-Italic');
  42. // Define array of codepoint(decimal) to Unicode(decimal)
  43. $chars = array(
  44. 0=>0
  45. 1=>0
  46. 2=>0
  47. ...
  48. 83=>83
  49. 84=>84
  50. 85=>85
  51. 86=>86
  52. ...
  53. 253=>20156
  54. 254=>19289
  55. 255=>4013
  56. );
  57. $asm->DefineChars($chars);
  58. //Available:
  59. $asm->pdf_diffstr; // String of /Diffs for inclusion in a PDF file
  60. $s = $asm->OutputPFB('', false);
  61. // OR
  62. $asm->OutputPFB('myfontassembled',false); // makes a .pfb if (*,true) or gzcompressed as a .z file if not
  63. //Available:
  64. $asm->of_size1; // size in bytes of 1st (ASCII) block
  65. $asm->of_size2; // size in bytes of 2nd (binary) block
  66. */
  67. //======================================================
  68. class t1asm {
  69. var $PFB_ASCII = 1;
  70. var $PFB_BINARY = 2;
  71. var $PFB_DONE = 3;
  72. var $PFB_MARKER = 0x80;
  73. var $file_op = '';
  74. var $ofp;
  75. var $file_ip = '';
  76. var $tbl_prefix ='';
  77. var $agn;
  78. var $uni2gn;
  79. /* flags */
  80. var $pfb = 1;
  81. var $ever_active = 0;
  82. var $in_eexec = 0;
  83. /* lenIV and charstring start command */
  84. var $lenIV = 4;
  85. var $cs_start = 'RD';
  86. /* decryption stuff */
  87. var $c1 = 52845;
  88. var $c2 = 22719;
  89. var $cr = 4330;
  90. var $er = 55665;
  91. var $cs_commands = array();
  92. var $op_buffer = '';
  93. var $wob = '';
  94. var $blocktyp;
  95. var $dest = '';
  96. var $if_header;
  97. var $if_FullName;
  98. var $if_FontName;
  99. var $if_FamilyName;
  100. var $if_encs;
  101. var $if_eexec_start;
  102. var $if_Subrs;
  103. var $if_CharStrings;
  104. var $if_source;
  105. var $fid;
  106. var $SubroutineStr;
  107. var $pdf_diffstr;
  108. var $pdfa_charset; // mPDF 4.2.018
  109. var $offs;
  110. var $of_encodingstr;
  111. var $of_header;
  112. var $of_size1;
  113. var $of_size2;
  114. var $of_FullName;
  115. var $of_FontName;
  116. var $of_FamilyName;
  117. //+++++++++++++++++++++++++++++++++++++++++++++
  118. function t1asm() {
  119. $this->_initialise();
  120. /* Adobe Glyph Names */
  121. $this->agn = array ( 65 => 'A', 198 => 'AE', 508 => 'AEacute', 193 => 'Aacute', 258 => 'Abreve', 194 => 'Acircumflex', 196 => 'Adieresis',
  122. 192 => 'Agrave', 913 => 'Alpha', 902 => 'Alphatonos', 256 => 'Amacron', 260 => 'Aogonek', 197 => 'Aring', 506 => 'Aringacute', 195 => 'Atilde',
  123. 66 => 'B', 914 => 'Beta', 67 => 'C', 262 => 'Cacute', 268 => 'Ccaron', 199 => 'Ccedilla', 264 => 'Ccircumflex', 266 => 'Cdotaccent', 935 => 'Chi',
  124. 68 => 'D', 270 => 'Dcaron', 272 => 'Dcroat', 916 => 'Delta', 69 => 'E', 201 => 'Eacute', 276 => 'Ebreve', 282 => 'Ecaron', 202 => 'Ecircumflex',
  125. 203 => 'Edieresis', 278 => 'Edotaccent', 200 => 'Egrave', 274 => 'Emacron', 330 => 'Eng', 280 => 'Eogonek', 917 => 'Epsilon', 904 => 'Epsilontonos',
  126. 919 => 'Eta', 905 => 'Etatonos', 208 => 'Eth', 8364 => 'Euro', 70 => 'F', 71 => 'G', 915 => 'Gamma', 286 => 'Gbreve', 486 => 'Gcaron',
  127. 284 => 'Gcircumflex', 290 => 'Gcommaaccent', 288 => 'Gdotaccent', 72 => 'H', 9679 => 'H18533', 9642 => 'H18543', 9643 => 'H18551', 9633 => 'H22073',
  128. 294 => 'Hbar', 292 => 'Hcircumflex', 73 => 'I', 306 => 'IJ', 205 => 'Iacute', 300 => 'Ibreve', 206 => 'Icircumflex', 207 => 'Idieresis',
  129. 304 => 'Idotaccent', 8465 => 'Ifraktur', 204 => 'Igrave', 298 => 'Imacron', 302 => 'Iogonek', 921 => 'Iota', 938 => 'Iotadieresis', 906 => 'Iotatonos',
  130. 296 => 'Itilde', 74 => 'J', 308 => 'Jcircumflex', 75 => 'K', 922 => 'Kappa', 310 => 'Kcommaaccent', 76 => 'L', 313 => 'Lacute', 923 => 'Lambda',
  131. 317 => 'Lcaron', 315 => 'Lcommaaccent', 319 => 'Ldot', 321 => 'Lslash', 77 => 'M', 924 => 'Mu', 78 => 'N', 323 => 'Nacute', 327 => 'Ncaron',
  132. 325 => 'Ncommaaccent', 209 => 'Ntilde', 925 => 'Nu', 79 => 'O', 338 => 'OE', 211 => 'Oacute', 334 => 'Obreve', 212 => 'Ocircumflex', 214 => 'Odieresis',
  133. 210 => 'Ograve', 416 => 'Ohorn', 336 => 'Ohungarumlaut', 332 => 'Omacron', 937 => 'Omega', 911 => 'Omegatonos', 927 => 'Omicron', 908 => 'Omicrontonos',
  134. 216 => 'Oslash', 510 => 'Oslashacute', 213 => 'Otilde', 80 => 'P', 934 => 'Phi', 928 => 'Pi', 936 => 'Psi', 81 => 'Q', 82 => 'R', 340 => 'Racute',
  135. 344 => 'Rcaron', 342 => 'Rcommaaccent', 8476 => 'Rfraktur', 929 => 'Rho', 83 => 'S', 9484 => 'SF010000', 9492 => 'SF020000', 9488 => 'SF030000',
  136. 9496 => 'SF040000', 9532 => 'SF050000', 9516 => 'SF060000', 9524 => 'SF070000', 9500 => 'SF080000', 9508 => 'SF090000', 9472 => 'SF100000',
  137. 9474 => 'SF110000', 9569 => 'SF190000', 9570 => 'SF200000', 9558 => 'SF210000', 9557 => 'SF220000', 9571 => 'SF230000', 9553 => 'SF240000',
  138. 9559 => 'SF250000', 9565 => 'SF260000', 9564 => 'SF270000', 9563 => 'SF280000', 9566 => 'SF360000', 9567 => 'SF370000', 9562 => 'SF380000',
  139. 9556 => 'SF390000', 9577 => 'SF400000', 9574 => 'SF410000', 9568 => 'SF420000', 9552 => 'SF430000', 9580 => 'SF440000', 9575 => 'SF450000',
  140. 9576 => 'SF460000', 9572 => 'SF470000', 9573 => 'SF480000', 9561 => 'SF490000', 9560 => 'SF500000', 9554 => 'SF510000', 9555 => 'SF520000',
  141. 9579 => 'SF530000', 9578 => 'SF540000', 346 => 'Sacute', 352 => 'Scaron', 350 => 'Scedilla', 348 => 'Scircumflex', 536 => 'Scommaaccent',
  142. 931 => 'Sigma', 84 => 'T', 932 => 'Tau', 358 => 'Tbar', 356 => 'Tcaron', 354 => 'Tcommaaccent', 920 => 'Theta', 222 => 'Thorn', 85 => 'U',
  143. 218 => 'Uacute', 364 => 'Ubreve', 219 => 'Ucircumflex', 220 => 'Udieresis', 217 => 'Ugrave', 431 => 'Uhorn', 368 => 'Uhungarumlaut', 362 => 'Umacron',
  144. 370 => 'Uogonek', 933 => 'Upsilon', 978 => 'Upsilon1', 939 => 'Upsilondieresis', 910 => 'Upsilontonos', 366 => 'Uring', 360 => 'Utilde', 86 => 'V',
  145. 87 => 'W', 7810 => 'Wacute', 372 => 'Wcircumflex', 7812 => 'Wdieresis', 7808 => 'Wgrave', 88 => 'X', 926 => 'Xi', 89 => 'Y', 221 => 'Yacute',
  146. 374 => 'Ycircumflex', 376 => 'Ydieresis', 7922 => 'Ygrave', 90 => 'Z', 377 => 'Zacute', 381 => 'Zcaron', 379 => 'Zdotaccent', 918 => 'Zeta',
  147. 97 => 'a', 225 => 'aacute', 259 => 'abreve', 226 => 'acircumflex', 180 => 'acute', 769 => 'acutecomb', 228 => 'adieresis', 230 => 'ae',
  148. 509 => 'aeacute', 8213 => 'afii00208', 1040 => 'afii10017', 1041 => 'afii10018', 1042 => 'afii10019', 1043 => 'afii10020', 1044 => 'afii10021',
  149. 1045 => 'afii10022', 1025 => 'afii10023', 1046 => 'afii10024', 1047 => 'afii10025', 1048 => 'afii10026', 1049 => 'afii10027', 1050 => 'afii10028',
  150. 1051 => 'afii10029', 1052 => 'afii10030', 1053 => 'afii10031', 1054 => 'afii10032', 1055 => 'afii10033', 1056 => 'afii10034', 1057 => 'afii10035',
  151. 1058 => 'afii10036', 1059 => 'afii10037', 1060 => 'afii10038', 1061 => 'afii10039', 1062 => 'afii10040', 1063 => 'afii10041', 1064 => 'afii10042',
  152. 1065 => 'afii10043', 1066 => 'afii10044', 1067 => 'afii10045', 1068 => 'afii10046', 1069 => 'afii10047', 1070 => 'afii10048', 1071 => 'afii10049',
  153. 1168 => 'afii10050', 1026 => 'afii10051', 1027 => 'afii10052', 1028 => 'afii10053', 1029 => 'afii10054', 1030 => 'afii10055', 1031 => 'afii10056',
  154. 1032 => 'afii10057', 1033 => 'afii10058', 1034 => 'afii10059', 1035 => 'afii10060', 1036 => 'afii10061', 1038 => 'afii10062', 1072 => 'afii10065',
  155. 1073 => 'afii10066', 1074 => 'afii10067', 1075 => 'afii10068', 1076 => 'afii10069', 1077 => 'afii10070', 1105 => 'afii10071', 1078 => 'afii10072',
  156. 1079 => 'afii10073', 1080 => 'afii10074', 1081 => 'afii10075', 1082 => 'afii10076', 1083 => 'afii10077', 1084 => 'afii10078', 1085 => 'afii10079',
  157. 1086 => 'afii10080', 1087 => 'afii10081', 1088 => 'afii10082', 1089 => 'afii10083', 1090 => 'afii10084', 1091 => 'afii10085', 1092 => 'afii10086',
  158. 1093 => 'afii10087', 1094 => 'afii10088', 1095 => 'afii10089', 1096 => 'afii10090', 1097 => 'afii10091', 1098 => 'afii10092', 1099 => 'afii10093',
  159. 1100 => 'afii10094', 1101 => 'afii10095', 1102 => 'afii10096', 1103 => 'afii10097', 1169 => 'afii10098', 1106 => 'afii10099', 1107 => 'afii10100',
  160. 1108 => 'afii10101', 1109 => 'afii10102', 1110 => 'afii10103', 1111 => 'afii10104', 1112 => 'afii10105', 1113 => 'afii10106', 1114 => 'afii10107',
  161. 1115 => 'afii10108', 1116 => 'afii10109', 1118 => 'afii10110', 1039 => 'afii10145', 1122 => 'afii10146', 1138 => 'afii10147', 1140 => 'afii10148',
  162. 1119 => 'afii10193', 1123 => 'afii10194', 1139 => 'afii10195', 1141 => 'afii10196', 1241 => 'afii10846', 8206 => 'afii299', 8207 => 'afii300',
  163. 8205 => 'afii301', 1642 => 'afii57381', 1548 => 'afii57388', 1632 => 'afii57392', 1633 => 'afii57393', 1634 => 'afii57394', 1635 => 'afii57395',
  164. 1636 => 'afii57396', 1637 => 'afii57397', 1638 => 'afii57398', 1639 => 'afii57399', 1640 => 'afii57400', 1641 => 'afii57401', 1563 => 'afii57403',
  165. 1567 => 'afii57407', 1569 => 'afii57409', 1570 => 'afii57410', 1571 => 'afii57411', 1572 => 'afii57412', 1573 => 'afii57413', 1574 => 'afii57414',
  166. 1575 => 'afii57415', 1576 => 'afii57416', 1577 => 'afii57417', 1578 => 'afii57418', 1579 => 'afii57419', 1580 => 'afii57420', 1581 => 'afii57421',
  167. 1582 => 'afii57422', 1583 => 'afii57423', 1584 => 'afii57424', 1585 => 'afii57425', 1586 => 'afii57426', 1587 => 'afii57427', 1588 => 'afii57428',
  168. 1589 => 'afii57429', 1590 => 'afii57430', 1591 => 'afii57431', 1592 => 'afii57432', 1593 => 'afii57433', 1594 => 'afii57434', 1600 => 'afii57440',
  169. 1601 => 'afii57441', 1602 => 'afii57442', 1603 => 'afii57443', 1604 => 'afii57444', 1605 => 'afii57445', 1606 => 'afii57446', 1608 => 'afii57448',
  170. 1609 => 'afii57449', 1610 => 'afii57450', 1611 => 'afii57451', 1612 => 'afii57452', 1613 => 'afii57453', 1614 => 'afii57454', 1615 => 'afii57455',
  171. 1616 => 'afii57456', 1617 => 'afii57457', 1618 => 'afii57458', 1607 => 'afii57470', 1700 => 'afii57505', 1662 => 'afii57506', 1670 => 'afii57507',
  172. 1688 => 'afii57508', 1711 => 'afii57509', 1657 => 'afii57511', 1672 => 'afii57512', 1681 => 'afii57513', 1722 => 'afii57514', 1746 => 'afii57519',
  173. 1749 => 'afii57534', 8362 => 'afii57636', 1470 => 'afii57645', 1475 => 'afii57658', 1488 => 'afii57664', 1489 => 'afii57665', 1490 => 'afii57666',
  174. 1491 => 'afii57667', 1492 => 'afii57668', 1493 => 'afii57669', 1494 => 'afii57670', 1495 => 'afii57671', 1496 => 'afii57672', 1497 => 'afii57673',
  175. 1498 => 'afii57674', 1499 => 'afii57675', 1500 => 'afii57676', 1501 => 'afii57677', 1502 => 'afii57678', 1503 => 'afii57679', 1504 => 'afii57680',
  176. 1505 => 'afii57681', 1506 => 'afii57682', 1507 => 'afii57683', 1508 => 'afii57684', 1509 => 'afii57685', 1510 => 'afii57686', 1511 => 'afii57687',
  177. 1512 => 'afii57688', 1513 => 'afii57689', 1514 => 'afii57690', 1520 => 'afii57716', 1521 => 'afii57717', 1522 => 'afii57718', 1460 => 'afii57793',
  178. 1461 => 'afii57794', 1462 => 'afii57795', 1467 => 'afii57796', 1464 => 'afii57797', 1463 => 'afii57798', 1456 => 'afii57799', 1458 => 'afii57800',
  179. 1457 => 'afii57801', 1459 => 'afii57802', 1474 => 'afii57803', 1473 => 'afii57804', 1465 => 'afii57806', 1468 => 'afii57807', 1469 => 'afii57839',
  180. 1471 => 'afii57841', 1472 => 'afii57842', 700 => 'afii57929', 8453 => 'afii61248', 8467 => 'afii61289', 8470 => 'afii61352', 8236 => 'afii61573',
  181. 8237 => 'afii61574', 8238 => 'afii61575', 8204 => 'afii61664', 1645 => 'afii63167', 701 => 'afii64937', 224 => 'agrave', 8501 => 'aleph',
  182. 945 => 'alpha', 940 => 'alphatonos', 257 => 'amacron', 38 => 'ampersand', 8736 => 'angle', 9001 => 'angleleft', 9002 => 'angleright',
  183. 903 => 'anoteleia', 261 => 'aogonek', 8776 => 'approxequal', 229 => 'aring', 507 => 'aringacute', 8596 => 'arrowboth', 8660 => 'arrowdblboth',
  184. 8659 => 'arrowdbldown', 8656 => 'arrowdblleft', 8658 => 'arrowdblright', 8657 => 'arrowdblup', 8595 => 'arrowdown', 8592 => 'arrowleft',
  185. 8594 => 'arrowright', 8593 => 'arrowup', 8597 => 'arrowupdn', 8616 => 'arrowupdnbse', 94 => 'asciicircum', 126 => 'asciitilde', 42 => 'asterisk',
  186. 8727 => 'asteriskmath', 64 => 'at', 227 => 'atilde', 98 => 'b', 92 => 'backslash', 124 => 'bar', 946 => 'beta', 9608 => 'block', 123 => 'braceleft',
  187. 125 => 'braceright', 91 => 'bracketleft', 93 => 'bracketright', 728 => 'breve', 166 => 'brokenbar', 8226 => 'bullet', 99 => 'c', 263 => 'cacute',
  188. 711 => 'caron', 8629 => 'carriagereturn', 269 => 'ccaron', 231 => 'ccedilla', 265 => 'ccircumflex', 267 => 'cdotaccent', 184 => 'cedilla',
  189. 162 => 'cent', 967 => 'chi', 9675 => 'circle', 8855 => 'circlemultiply', 8853 => 'circleplus', 710 => 'circumflex', 9827 => 'club', 58 => 'colon',
  190. 8353 => 'colonmonetary', 44 => 'comma', 8773 => 'congruent', 169 => 'copyright', 164 => 'currency', 100 => 'd', 8224 => 'dagger', 8225 => 'daggerdbl',
  191. 271 => 'dcaron', 273 => 'dmacron', 176 => 'degree', 948 => 'delta', 9830 => 'diamond', 168 => 'dieresis', 901 => 'dieresistonos', 247 => 'divide',
  192. 9619 => 'dkshade', 9604 => 'dnblock', 36 => 'dollar', 8363 => 'dong', 729 => 'dotaccent', 803 => 'dotbelowcomb', 305 => 'dotlessi', 8901 => 'dotmath',
  193. 101 => 'e', 233 => 'eacute', 277 => 'ebreve', 283 => 'ecaron', 234 => 'ecircumflex', 235 => 'edieresis', 279 => 'edotaccent', 232 => 'egrave',
  194. 56 => 'eight', 8712 => 'element', 8230 => 'ellipsis', 275 => 'emacron', 8212 => 'emdash', 8709 => 'emptyset', 8211 => 'endash', 331 => 'eng',
  195. 281 => 'eogonek', 949 => 'epsilon', 941 => 'epsilontonos', 61 => 'equal', 8801 => 'equivalence', 8494 => 'estimated', 951 => 'eta', 942 => 'etatonos',
  196. 240 => 'eth', 33 => 'exclam', 8252 => 'exclamdbl', 161 => 'exclamdown', 8707 => 'existential', 102 => 'f', 9792 => 'female', 8210 => 'figuredash',
  197. 9632 => 'filledbox', 9644 => 'filledrect', 53 => 'five', 8541 => 'fiveeighths', 402 => 'florin', 52 => 'four', 8260 => 'fraction', 8355 => 'franc',
  198. 103 => 'g', 947 => 'gamma', 287 => 'gbreve', 487 => 'gcaron', 285 => 'gcircumflex', 291 => 'gcommaaccent', 289 => 'gdotaccent', 223 => 'germandbls',
  199. 8711 => 'gradient', 96 => 'grave', 768 => 'gravecomb', 62 => 'greater', 8805 => 'greaterequal', 171 => 'guillemotleft', 187 => 'guillemotright',
  200. 8249 => 'guilsinglleft', 8250 => 'guilsinglright', 104 => 'h', 295 => 'hbar', 293 => 'hcircumflex', 9829 => 'heart', 777 => 'hookabovecomb',
  201. 8962 => 'house', 733 => 'hungarumlaut', 45 => 'hyphen', 105 => 'i', 237 => 'iacute', 301 => 'ibreve', 238 => 'icircumflex', 239 => 'idieresis',
  202. 236 => 'igrave', 307 => 'ij', 299 => 'imacron', 8734 => 'infinity', 8747 => 'integral', 8993 => 'integralbt', 8992 => 'integraltp',
  203. 8745 => 'intersection', 9688 => 'invbullet', 9689 => 'invcircle', 9787 => 'invsmileface', 303 => 'iogonek', 953 => 'iota', 970 => 'iotadieresis',
  204. 912 => 'iotadieresistonos', 943 => 'iotatonos', 297 => 'itilde', 106 => 'j', 309 => 'jcircumflex', 107 => 'k', 954 => 'kappa', 311 => 'kcommaaccent',
  205. 312 => 'kgreenlandic', 108 => 'l', 314 => 'lacute', 955 => 'lambda', 318 => 'lcaron', 316 => 'lcommaaccent', 320 => 'ldot', 60 => 'less',
  206. 8804 => 'lessequal', 9612 => 'lfblock', 8356 => 'lira', 8743 => 'logicaland', 172 => 'logicalnot', 8744 => 'logicalor', 383 => 'longs',
  207. 9674 => 'lozenge', 322 => 'lslash', 9617 => 'ltshade', 109 => 'm', 175 => 'macron', 9794 => 'male', 8722 => 'minus', 8242 => 'minute', 956 => 'mu',
  208. 215 => 'multiply', 9834 => 'musicalnote', 9835 => 'musicalnotedbl', 110 => 'n', 324 => 'nacute', 329 => 'napostrophe', 328 => 'ncaron',
  209. 326 => 'ncommaaccent', 57 => 'nine', 8713 => 'notelement', 8800 => 'notequal', 8836 => 'notsubset', 241 => 'ntilde', 957 => 'nu', 35 => 'numbersign',
  210. 111 => 'o', 243 => 'oacute', 335 => 'obreve', 244 => 'ocircumflex', 246 => 'odieresis', 339 => 'oe', 731 => 'ogonek', 242 => 'ograve',
  211. 417 => 'ohorn', 337 => 'ohungarumlaut', 333 => 'omacron', 969 => 'omega', 982 => 'omega1', 974 => 'omegatonos', 959 => 'omicron',
  212. 972 => 'omicrontonos', 49 => 'one', 8228 => 'onedotenleader', 8539 => 'oneeighth', 189 => 'onehalf', 188 => 'onequarter', 8531 => 'onethird',
  213. 9702 => 'openbullet', 170 => 'ordfeminine', 186 => 'ordmasculine', 8735 => 'orthogonal', 248 => 'oslash', 511 => 'oslashacute', 245 => 'otilde',
  214. 112 => 'p', 182 => 'paragraph', 40 => 'parenleft', 41 => 'parenright', 8706 => 'partialdiff', 37 => 'percent', 46 => 'period', 183 => 'periodcentered',
  215. 8869 => 'perpendicular', 8240 => 'perthousand', 8359 => 'peseta', 966 => 'phi', 981 => 'phi1', 960 => 'pi', 43 => 'plus', 177 => 'plusminus',
  216. 8478 => 'prescription', 8719 => 'product', 8834 => 'propersubset', 8835 => 'propersuperset', 8733 => 'proportional', 968 => 'psi', 113 => 'q',
  217. 63 => 'question', 191 => 'questiondown', 34 => 'quotedbl', 8222 => 'quotedblbase', 8220 => 'quotedblleft', 8221 => 'quotedblright',
  218. 8216 => 'quoteleft', 8219 => 'quotereversed', 8217 => 'quoteright', 8218 => 'quotesinglbase', 39 => 'quotesingle', 114 => 'r', 341 => 'racute',
  219. 8730 => 'radical', 345 => 'rcaron', 343 => 'rcommaaccent', 8838 => 'reflexsubset', 8839 => 'reflexsuperset', 174 => 'registered',
  220. 8976 => 'revlogicalnot', 961 => 'rho', 730 => 'ring', 9616 => 'rtblock', 115 => 's', 347 => 'sacute', 353 => 'scaron', 351 => 'scedilla',
  221. 349 => 'scircumflex', 537 => 'scommaaccent', 8243 => 'second', 167 => 'section', 59 => 'semicolon', 55 => 'seven', 8542 => 'seveneighths',
  222. 9618 => 'shade', 963 => 'sigma', 962 => 'sigma1', 8764 => 'similar', 54 => 'six', 47 => 'slash', 9786 => 'smileface', 32 => 'space',
  223. 9824 => 'spade', 163 => 'sterling', 8715 => 'suchthat', 8721 => 'summation', 9788 => 'sun', 116 => 't', 964 => 'tau', 359 => 'tbar', 357 => 'tcaron',
  224. 355 => 'tcommaaccent', 8756 => 'therefore', 952 => 'theta', 977 => 'theta1', 254 => 'thorn', 51 => 'three', 8540 => 'threeeighths',
  225. 190 => 'threequarters', 732 => 'tilde', 771 => 'tildecomb', 900 => 'tonos', 8482 => 'trademark', 9660 => 'triagdn', 9668 => 'triaglf',
  226. 9658 => 'triagrt', 9650 => 'triagup', 50 => 'two', 8229 => 'twodotenleader', 8532 => 'twothirds', 117 => 'u', 250 => 'uacute', 365 => 'ubreve',
  227. 251 => 'ucircumflex', 252 => 'udieresis', 249 => 'ugrave', 432 => 'uhorn', 369 => 'uhungarumlaut', 363 => 'umacron', 95 => 'underscore',
  228. 8215 => 'underscoredbl', 8746 => 'union', 8704 => 'universal', 371 => 'uogonek', 9600 => 'upblock', 965 => 'upsilon', 971 => 'upsilondieresis',
  229. 944 => 'upsilondieresistonos', 973 => 'upsilontonos', 367 => 'uring', 361 => 'utilde', 118 => 'v', 119 => 'w', 7811 => 'wacute', 373 => 'wcircumflex',
  230. 7813 => 'wdieresis', 8472 => 'weierstrass', 7809 => 'wgrave', 120 => 'x', 958 => 'xi', 121 => 'y', 253 => 'yacute', 375 => 'ycircumflex',
  231. 255 => 'ydieresis', 165 => 'yen', 7923 => 'ygrave', 122 => 'z', 378 => 'zacute', 382 => 'zcaron', 380 => 'zdotaccent', 48 => 'zero', 950 => 'zeta',
  232. );
  233. /* initialise table of charstring commands */
  234. $this->cs_commands = array(
  235. 'abs' => array(12, 9 ),
  236. 'add' => array(12, 10 ),
  237. 'and' => array(12, 3 ),
  238. 'blend' => array(16, -1 ),
  239. 'callgsubr' => array(29, -1 ),
  240. 'callothersubr' => array(12, 16 ),
  241. 'callsubr' => array(10, -1 ),
  242. 'closepath' => array(9, -1 ),
  243. 'cntrmask' => array(20, -1 ),
  244. 'div' => array(12, 12 ),
  245. 'dotsection' => array(12, 0 ),
  246. 'drop' => array(12, 18 ),
  247. 'dup' => array(12, 27 ),
  248. 'endchar' => array(14, -1 ),
  249. 'eq' => array(12, 15 ),
  250. 'error' => array(0, -1 ),
  251. 'escape' => array(12, -1 ),
  252. 'exch' => array(12, 28 ),
  253. 'flex' => array(12, 35 ),
  254. 'flex1' => array(12, 37 ),
  255. 'get' => array(12, 21 ),
  256. 'hflex' => array(12, 34 ),
  257. 'hflex1' => array(12, 36 ),
  258. 'hhcurveto' => array(27, -1 ),
  259. 'hintmask' => array(19, -1 ),
  260. 'hlineto' => array(6, -1 ),
  261. 'hmoveto' => array(22, -1 ),
  262. 'hsbw' => array(13, -1 ),
  263. 'hstem' => array(1, -1 ),
  264. 'hstem3' => array(12, 2 ),
  265. 'hstemhm' => array(18, -1 ),
  266. 'hvcurveto' => array(31, -1 ),
  267. 'ifelse' => array(12, 22 ),
  268. 'index' => array(12, 29 ),
  269. 'load' => array(12, 13 ),
  270. 'mul' => array(12, 24 ),
  271. 'neg' => array(12, 14 ),
  272. 'not' => array(12, 5 ),
  273. 'or' => array(12, 4 ),
  274. 'pop' => array(12, 17 ),
  275. 'put' => array(12, 20 ),
  276. 'random' => array(12, 23 ),
  277. 'rcurveline' => array(24, -1 ),
  278. 'return' => array(11, -1 ),
  279. 'rlinecurve' => array(25, -1 ),
  280. 'rlineto' => array(5, -1 ),
  281. 'rmoveto' => array(21, -1 ),
  282. 'roll' => array(12, 30 ),
  283. 'rrcurveto' => array(8, -1 ),
  284. 'sbw' => array(12, 7 ),
  285. 'seac' => array(12, 6 ),
  286. 'setcurrentpoint' => array(12, 33 ),
  287. 'sqrt' => array(12, 26 ),
  288. 'store' => array(12, 8 ),
  289. 'sub' => array(12, 11 ),
  290. 'vhcurveto' => array(30, -1 ),
  291. 'vlineto' => array(7, -1 ),
  292. 'vmoveto' => array(4, -1 ),
  293. 'vstem' => array(3, -1 ),
  294. 'vstem3' => array(12, 1 ),
  295. 'vstemhm' => array(23, -1 ),
  296. 'vvcurveto' => array(26, -1 )
  297. );
  298. $this->SubroutineStr = "dup 0 15 RD \x0a\xc2\xbf1p|\x0a\x0e\x0a=-\xe2\x80\x9cD\\xc3\xa2R NP\ndup 1 9 RD \x0a\xc2\xbf1py\xc2\xbc\xc3\xb6Uz NP\ndup 2 9 RD \x0a\xc2\xbf1py\xc2\xbd\xc3\x84\xc5\xbei NP\ndup 3 5 RD \x0a\xc2\xbf1p\xc3\xb9 NP\ndup 4 12 RD \x0a\xc2\xbf1p~\xc2\xb6+6\xc3\xa46z NP\n";
  299. }
  300. //+++++++++++++++++++++++++++++++++++++++++++++
  301. //+++++++++++++++++++++++++++++++++++++++++++++
  302. // Public functions
  303. function LoadFontFile($file) {
  304. /* returns:
  305. var $if_header;
  306. var $if_FullName;
  307. var $if_FontName;
  308. var $if_FamilyName;
  309. var $if_encs;
  310. var $if_eexec_start;
  311. var $if_Subrs;
  312. var $if_CharStrings;
  313. var $if_source;
  314. var $fid;
  315. var $SubroutineStr;
  316. */
  317. $this->_initialise();
  318. $mqr=ini_get("magic_quotes_runtime");
  319. if ($mqr) { set_magic_quotes_runtime(0); }
  320. $this->lenIV = 4;
  321. $this->cs_start = 'RD';
  322. $fontname = preg_replace('/.*\//', '', $file);
  323. $this->file_ip = _MPDF_PATH.'unifont/'.$fontname;
  324. $this->lenIV = 4;
  325. $this->cs_start = 'RD';
  326. $this->SubroutineStr = "dup 0 15 RD \x0a\xc2\xbf1p|\x0a\x0e\x0a=-\xe2\x80\x9cD\\xc3\xa2R NP\ndup 1 9 RD \x0a\xc2\xbf1py\xc2\xbc\xc3\xb6Uz NP\ndup 2 9 RD \x0a\xc2\xbf1py\xc2\xbd\xc3\x84\xc5\xbei NP\ndup 3 5 RD \x0a\xc2\xbf1p\xc3\xb9 NP\ndup 4 12 RD \x0a\xc2\xbf1p~\xc2\xb6+6\xc3\xa46z NP\n";
  327. $offs = array();
  328. include($this->file_ip .'.dat.php');
  329. if (!isset($offs)) { die("ERROR - Data file not found to embed font subsets - ".$this->file_ip .'.dat.php'); }
  330. $this->offs = $offs;
  331. $fh = fopen($this->file_ip .'.dat', "rb") or die("ERROR - Data file not found to embed font subsets - ".$this->file_ip .'.dat'); // mPDF 4.5.008
  332. $l = $this->_freadint($fh); // Read 4-byte integer
  333. $this->if_header = fread($fh, $l);
  334. $l = $this->_freadint($fh); // Read 4-byte integer
  335. $this->if_eexec_start = fread($fh, $l);
  336. fclose($fh);
  337. // Read uni2gn [code-point to glyph-name] derived from .ufm file if exists
  338. $this->uni2gn = array();
  339. include($file.'.uni2gn.php');
  340. if (!$this->uni2gn) { die("ERROR - Data file not found to embed font subsets - ".$this->file_ip .'.uni2gn.php'); }
  341. if ($mqr) { set_magic_quotes_runtime($mqr); }
  342. }
  343. function SetFontName($fn) {
  344. $this->of_FontName = $fn;
  345. }
  346. function SetFamilyName($fn) {
  347. $this->of_FamilyName = $fn;
  348. }
  349. function SetFullName($fn) {
  350. $this->of_FullName = $fn;
  351. }
  352. function DefineChars($chars,$pdfa=false) { // mPDF 4.2.018 PDFA
  353. // chars = code point (decimal) => Unicode(decimal)
  354. // convertto [0]=>'exclamationmark', [1]=>'afii080012'
  355. // e.g of code point (decimal) => Adobe glyph name
  356. $last_c1 = -99;
  357. $this->pdf_diffstr = ''; // String of /Diffs for PDF file
  358. $this->pdfa_charset = ''; // mPDF 4.2.018 String of /glyphnames for PDFA file CharSet
  359. $this->of_encodingstr = '';
  360. $this->useChars = array();
  361. foreach ($chars AS $c1=>$c2) { // c1 decimal codepoint => c2 decimal(Unicode)
  362. if (isset($this->uni2gn[$c2]) && isset($this->offs[$this->uni2gn[$c2]])) {
  363. $op = $this->uni2gn[$c2];
  364. }
  365. else {
  366. // debug** print out missing characters - not found in the t1a file
  367. //if ($c2 >31) { echo '&#x'.dechex($c2).'; '.$c2.'; Ux'.dechex($c2).' <br />'; }
  368. $op = '.notdef';
  369. }
  370. if ($c1 != ($last_c1+1)) { $this->pdf_diffstr .= $c1 . " "; }
  371. $this->pdf_diffstr .= "/" . $op . " ";
  372. $this->of_encodingstr .= "dup ". $c1 . " /" . $op . " put\n";
  373. if ($pdfa && $op != '.notdef') { $this->pdfa_charset .= "/" . $op; } // mPDF 4.2.018 (don't include .notdef)
  374. $this->useChars[] = $op;
  375. $last_c1 = $c1;
  376. }
  377. }
  378. function OutputPFB($file='', $compress=true, $subr=true) {
  379. // $subr - also get list of subroutines
  380. // takes longer but will make more compact output file
  381. // mPDF 4.5.002
  382. $mqr=ini_get("magic_quotes_runtime");
  383. if ($mqr) { set_magic_quotes_runtime(0); }
  384. if (empty($this->useChars) || empty($this->of_encodingstr)) {
  385. $this->pfb_error('Error [OutputPDF]: No characters have been defined.');
  386. }
  387. if ($file) {
  388. $this->dest = 'F';
  389. }
  390. else {
  391. $this->dest = 'R';
  392. }
  393. $this->of_size1 = 0;
  394. $this->of_size2 = 0;
  395. $this->op_buffer = '';
  396. $this->wob = '';
  397. $this->in_eexec = 0;
  398. $this->blocktyp = $this->PFB_ASCII;
  399. $this->pfb = 1;
  400. $this->ever_active = 0;
  401. $this->lenIV = 4;
  402. $this->cs_start = 'RD';
  403. $this->c1 = 52845;
  404. $this->c2 = 22719;
  405. $this->cr = 4330;
  406. $this->er = 55665;
  407. // Replace Header items
  408. $this->of_header = $this->if_header;
  409. if ($this->of_FullName)
  410. $this->of_header = preg_replace('/(\/FullName\s+\().*?(\) readonly)/', '\\1'.$this->of_FullName.'\\2' , $this->of_header);
  411. if ($this->of_FamilyName)
  412. $this->of_header = preg_replace('/(\/FamilyName\s+\().*?(\) readonly)/', '\\1'.$this->of_FamilyName.'\\2' , $this->of_header);
  413. if ($this->of_FontName)
  414. $this->of_header = preg_replace('/(\/FontName\s+\/)\S*( def)/', '\\1'.$this->of_FontName.'\\2' , $this->of_header);
  415. // Add Header to write output buffer
  416. $this->wob .= $this->of_header;
  417. // Add Encodings
  418. $this->wob .= "/Encoding ".count($this->useChars)." array\n";
  419. $this->wob .= $this->of_encodingstr;
  420. $this->wob .= "readonly def\n";
  421. $this->wob .= "currentdict end\n";
  422. $this->wob .= "currentfile eexec\n";
  423. // Write ASCII block to main output buffer
  424. $this->pfb_writer_output_block();
  425. /************ BINARY *****************/
  426. $this->in_eexec = 1;
  427. $this->blocktyp = $this->PFB_BINARY;
  428. $buffer = '';
  429. for ($i = 0; $i < $this->lenIV; $i++) {
  430. $buffer .= chr(0);
  431. }
  432. $this->eexec_string($buffer);
  433. // Add eexec section start
  434. $this->if_eexec_start = trim($this->if_eexec_start) . "\n";
  435. $this->eexec_string($this->if_eexec_start);
  436. //+++++++++++++++++++++++++++++++++++++++++++++
  437. // Subroutines
  438. $this->eexec_string("/Subrs 5 array\n");
  439. //Subrs 0 - 4 are obligatory and fixed
  440. $this->eexec_string($this->SubroutineStr);
  441. $this->eexec_string("ND\n2 index ");
  442. //+++++++++++++++++++++++++++++++++++++++++++++
  443. // CharStrings
  444. $of_CharStrings = array();
  445. foreach($this->useChars AS $uc) { // glyphname e.g. lambda
  446. if (isset($this->offs[$uc])) {
  447. $of_CharStrings[$uc] = $this->offs[$uc];
  448. }
  449. }
  450. //NB .notdef is obligatory
  451. $of_CharStrings['.notdef'] = $this->offs['.notdef'];
  452. $this->eexec_string("/CharStrings ".count($of_CharStrings)." dict dup begin\n");
  453. $fh = fopen($this->file_ip .'.dat', "rb") or die("ERROR - Data file not found to embed font subsets - ".$this->file_ip .'.dat');
  454. foreach($of_CharStrings AS $gn => $offset) {
  455. fseek($fh, $offset);
  456. $l = $this->_freadint($fh); // Read 4-byte integer
  457. $cdat = fread($fh, $l) or die("HELP!");
  458. $this->eexec_string("/".$gn." ");
  459. $this->eexec_string($cdat);
  460. $this->eexec_string("\n");
  461. }
  462. fclose($fh);
  463. $this->eexec_string("end\nend\nreadonly put\nnoaccess put\ndup/FontName get exch definefont pop\nmark currentfile closefile\n");
  464. $this->pfb_writer_output_block();
  465. // ASCII trailer
  466. $this->blocktyp = $this->PFB_ASCII;
  467. $this->in_eexec = 0;
  468. for ($i = 0; $i < 8; $i++) {
  469. $this->wob .= "0000000000000000000000000000000000000000000000000000000000000000\n";
  470. }
  471. $this->wob .= "cleartomark\n";
  472. $this->pfb_writer_output_block();
  473. $this->_out(chr($this->PFB_MARKER));
  474. $this->_out(chr($this->PFB_DONE));
  475. // Compress
  476. if ($compress) {
  477. $pos=strpos($this->op_buffer,'eexec');
  478. $this->of_size1=$pos+6;
  479. $pos=strpos($this->op_buffer,'00000000');
  480. $this->of_size2=$pos-$this->of_size1;
  481. $this->op_buffer=substr($this->op_buffer,0,$this->of_size1+$this->of_size2);
  482. $this->op_buffer = gzcompress($this->op_buffer);
  483. $this->file_op = $file.'.z';
  484. }
  485. else {
  486. $this->file_op = $file.'.pfb';
  487. }
  488. // Output to file or return
  489. if ($this->dest == 'F') {
  490. $this->ofp = fopen($this->file_op, "wb");
  491. fwrite($this->ofp,$this->op_buffer,strlen($this->op_buffer));
  492. fclose($this->ofp);
  493. if ($mqr) { set_magic_quotes_runtime($mqr); } // mPDF 4.5.002
  494. }
  495. else {
  496. if ($mqr) { set_magic_quotes_runtime($mqr); } // mPDF 4.5.002
  497. return $this->op_buffer;
  498. }
  499. }
  500. //+++++++++++++++++++++++++++++++++++++++++++++
  501. //+++++++++++++++++++++++++++++++++++++++++++++
  502. //+++++++++++++++++++++++++++++++++++++++++++++
  503. //+++++++++++++++++++++++++++++++++++++++++++++
  504. // Private / internal functions
  505. function _freadint($f)
  506. {
  507. //Read a 4-byte integer from file
  508. $i=ord(fread($f,1))<<24;
  509. $i+=ord(fread($f,1))<<16;
  510. $i+=ord(fread($f,1))<<8;
  511. $i+=ord(fread($f,1));
  512. return $i;
  513. }
  514. function _initialise() {
  515. global $mpdf_tbl_prefix;
  516. $this->tbl_prefix = $mpdf_tbl_prefix;
  517. $this->if_source = 'F';
  518. $this->fid = false;
  519. $this->file_ip = '';
  520. $this->file_op = '';
  521. $this->op_buffer = '';
  522. $this->if_header = '';
  523. $this->if_FullName = '';
  524. $this->if_FontName = '';
  525. $this->if_FamilyName = '';
  526. $this->if_encs = array();
  527. $this->if_eexec_start = '';
  528. $this->if_Subrs = array();
  529. $this->if_CharStrings = array();
  530. $this->SubroutineStr = '';
  531. $this->pdf_diffstr = ''; // String of /Diffs for PDF file
  532. $this->of_encodingstr = '';
  533. $this->useChars = array();
  534. $this->uni2gn = array();
  535. }
  536. function pfb_error($msg) {
  537. echo $msg;
  538. //die($msg);
  539. }
  540. function eencrypt($plain) {
  541. //return $plain;
  542. $plain = ord($plain);
  543. $cipher = ($plain ^ ($this->er >> 8));
  544. $this->er = (($cipher + $this->er) * $this->c1 + $this->c2) & 0xffff;
  545. return chr($cipher);
  546. }
  547. function cencrypt($plain) {
  548. //return $plain;
  549. if ($this->lenIV < 0) return $plain;
  550. $cipher = ($plain ^ ($this->cr >> 8));
  551. $this->cr = (($cipher + $this->cr) * $this->c1 + $this->c2) & 0xffff;
  552. return $cipher;
  553. }
  554. /* This function outputs a byte through possible eexec encryption. */
  555. function eexec_byte($b) {
  556. if ($this->in_eexec)
  557. $this->wob .= ($this->eencrypt($b));
  558. else
  559. $this->wob .= ($b);
  560. }
  561. /* This function outputs a null-terminated string through possible eexec encryption. */
  562. function eexec_string($string) {
  563. if ($this->in_eexec) {
  564. for($i=0; $i<strlen($string); $i++) {
  565. $this->wob .= ($this->eencrypt(substr($string,$i,1)));
  566. }
  567. }
  568. else { $this->wob .= $string; }
  569. }
  570. /* This function encrypts and buffers a single byte of charstring data. */
  571. function charstring_byte($v) {
  572. $b = ($v & 0xff);
  573. $c = $this->cencrypt($b);
  574. return chr($c);
  575. }
  576. /* This function encodes an integer according to charstring number encoding. */
  577. function charstring_int($num) {
  578. $c = '';
  579. if ($num >= -107 && $num <= 107) {
  580. $c .= $this->charstring_byte($num + 139);
  581. } else if ($num >= 108 && $num <= 1131) {
  582. $x = $num - 108;
  583. $c .= $this->charstring_byte($x / 256 + 247);
  584. $c .= $this->charstring_byte($x % 256);
  585. } else if ($num >= -1131 && $num <= -108) {
  586. $x = abs($num) - 108;
  587. $c .= $this->charstring_byte($x / 256 + 251);
  588. $c .= $this->charstring_byte($x % 256);
  589. } else if ($num >= (-2147483647-1) && $num <= 2147483647) {
  590. $c .= $this->charstring_byte(255);
  591. $c .= $this->charstring_byte($num >> 24);
  592. $c .= $this->charstring_byte($num >> 16);
  593. $c .= $this->charstring_byte($num >> 8);
  594. $c .= $this->charstring_byte($num);
  595. } else {
  596. $this->pfb_error("can't format huge number `%d'", $num);
  597. /* output 0 instead */
  598. $c .= $this->charstring_byte(139);
  599. }
  600. return $c;
  601. }
  602. /* This function parses an entire charstring into integers and commands,
  603. outputting bytes through the charstring buffer. */
  604. function parse_charstring($cs) {
  605. /* initializes charstring encryption. */
  606. $buffer = '';
  607. $this->cr = 4330;
  608. for ($i = 0; $i < $this->lenIV; $i++) {
  609. $buffer .= $this->charstring_byte(chr(0));
  610. }
  611. $cc = preg_split('/\s+/',$cs,-1,PREG_SPLIT_NO_EMPTY);
  612. foreach($cc AS $c) {
  613. // Encode the integers according to charstring number encoding
  614. if (preg_match('/^[\-]{0,1}\d+$/',$c)) {
  615. $buffer .= $this->charstring_int($c);
  616. }
  617. // Encode the commands according to charstring command encoding
  618. else if (isset($this->cs_commands[$c])) {
  619. $one = $this->cs_commands[$c][0];
  620. $two = $this->cs_commands[$c][1];
  621. if ($one < 0 || $one > 255)
  622. $this->pfb_error("bad charstring command number $d in %s in %s", $one, $c, $cs);
  623. else if ($two > 255)
  624. $this->pfb_error("bad charstring command number $d in %s in %s", $two, $c, $cs);
  625. else if ($two < 0) {
  626. $buffer .= $this->charstring_byte($one);
  627. }
  628. else {
  629. $buffer .= $this->charstring_byte($one);
  630. $buffer .= $this->charstring_byte($two);
  631. }
  632. }
  633. else {
  634. $this->pfb_error("unknown charstring entry %s in %s", $c, $cs);
  635. }
  636. }
  637. $s = sprintf("%d ", strlen($buffer));
  638. $this->eexec_string($s);
  639. $s = sprintf("%s ", $this->cs_start);
  640. $this->eexec_string($s);
  641. $this->eexec_string($buffer);
  642. $buffer = '';
  643. }
  644. function pfb_writer_output_block() {
  645. $l = strlen($this->wob);
  646. if ($l == 0)
  647. return;
  648. /* output four-byte block length */
  649. $this->_out(chr($this->PFB_MARKER));
  650. $this->_out(chr($this->blocktyp));
  651. $this->_out(chr($l & 0xff));
  652. $this->_out(chr(($l >> 8) & 0xff));
  653. $this->_out(chr(($l >> 16) & 0xff));
  654. $this->_out(chr(($l >> 24) & 0xff));
  655. /* output block data */
  656. $this->_out($this->wob);
  657. $this->wob = '';
  658. }
  659. function _out($s) {
  660. $this->op_buffer .= $s;
  661. }
  662. //+++++++++++++++++++++++++++++++++++++++++++++
  663. } // end of class
  664. ?>