Leaked source code of windows server 2003
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.

2812 lines
98 KiB

  1. /* @(#)CM_VerSion xcf_t1.c atm09 1.3 16499.eco sum= 63806 atm09.002 */
  2. /* @(#)CM_VerSion xcf_t1.c atm08 1.6 16343.eco sum= 18288 atm08.005 */
  3. /***********************************************************************/
  4. /* */
  5. /* Copyright 1995-1996 Adobe Systems Incorporated. */
  6. /* All rights reserved. */
  7. /* */
  8. /* Patents Pending */
  9. /* */
  10. /* NOTICE: All information contained herein is the property of Adobe */
  11. /* Systems Incorporated. Many of the intellectual and technical */
  12. /* concepts contained herein are proprietary to Adobe, are protected */
  13. /* as trade secrets, and are made available only to Adobe licensees */
  14. /* for their internal use. Any reproduction or dissemination of this */
  15. /* software is strictly forbidden unless prior written permission is */
  16. /* obtained from Adobe. */
  17. /* */
  18. /* PostScript and Display PostScript are trademarks of Adobe Systems */
  19. /* Incorporated or its subsidiaries and may be registered in certain */
  20. /* jurisdictions. */
  21. /* */
  22. /***********************************************************************/
  23. /***********************************************************************
  24. Original version: John Felton, April 17, 1996
  25. ************************************************************************/
  26. /* -------------------------------------------------------------------------
  27. Header Includes
  28. --------------------------------------------------------------------------- */
  29. #include "xcf_pub.h"
  30. #include "xcf_priv.h"
  31. #include <math.h>
  32. #ifdef T13
  33. #include "xcf_t13.h"
  34. #endif
  35. #ifdef __cplusplus
  36. extern "C" {
  37. #endif
  38. static Card8 HexTable[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  39. #define MAX_LINE_LENGTH 1024
  40. #define REAL_TO_INT(x) (long)(x < 0 ? x - 0.5 : x + 0.5)
  41. /* Definitions of font data replacement points. */
  42. #define XCF_FONTNAME 0
  43. #define XCF_ENCODING 1
  44. #define XCF_UID 2
  45. #define XCF_XUID 3
  46. /* The following items are artifacts of the Type 1 format and are */
  47. /* no longer considered necessary for the proper functioning of fonts. */
  48. #if 1
  49. #define T1_READONLY ""
  50. #define T1_NOACCESS ""
  51. #else /* old way */
  52. #define T1_READONLY " readonly "
  53. #define T1_NOACCESS " noaccess "
  54. #endif /*1*/
  55. static void BufferEncrypt(XCF_Handle h,
  56. Card8 PTR_PREFIX *inBuf,
  57. Card8 PTR_PREFIX *outBuf,
  58. Int32 inLen,
  59. Card32 PTR_PREFIX *outLen,
  60. Card16 PTR_PREFIX *KeyP,
  61. boolean hexEncode)
  62. {
  63. register Card8 Cipher;
  64. register Card8 PTR_PREFIX *PlainSource = inBuf;
  65. register Card8 PTR_PREFIX *CipherDest = outBuf;
  66. register Card16 R = *KeyP;
  67. Card8 totalEOLs = 0;
  68. if (!hexEncode) /* Binary encode */
  69. { *outLen = inLen;
  70. while (--inLen >= 0)
  71. { Cipher = (*PlainSource++ ^ (Card8)(R >> 8));
  72. R = (Card16)(((Card16)Cipher + R) * 52845 + 22719);
  73. *CipherDest++ = Cipher;
  74. } /* end while */
  75. } /* end if */
  76. else /* Hex Encode */
  77. { Card8 t;
  78. *outLen = (inLen << 1);
  79. while (--inLen >= 0)
  80. { Cipher = (*PlainSource++ ^ (Card8)(R >> 8));
  81. R = (Card16)(((Card16)Cipher + R) * 52845 + 22719);
  82. t = (Card8)(((Cipher >> 4) & 0x0F) + 0x30);
  83. if (t > 0x39)
  84. t += 7;
  85. *CipherDest++ = t;
  86. t = (Card8)((Cipher & 0x0F) + 0x30);
  87. if (t > 0x39)
  88. t += 7;
  89. *CipherDest++ = t;
  90. h->outBuffer.charsOnLine+=2;
  91. if (h->outBuffer.charsOnLine > EOL_SPACING)
  92. {
  93. #if 0
  94. *CipherDest++ = '\r';
  95. *CipherDest++ = '\n';
  96. totalEOLs += 2;
  97. #else
  98. Card8 PTR_PREFIX *p;
  99. for (p = (Card8 *)XCF_NEW_LINE; *p; ++p)
  100. {
  101. *CipherDest++ = *p;
  102. totalEOLs += 1;
  103. }
  104. #endif
  105. h->outBuffer.charsOnLine = 0;
  106. } /* end if */
  107. } /* end while */
  108. *outLen += totalEOLs;
  109. } /* end else */
  110. *KeyP = R;
  111. } /* end BufferEncrypt() */
  112. static void BufferHexEncode(XCF_Handle h,
  113. Card8 PTR_PREFIX *inBuf,
  114. Card8 PTR_PREFIX *outBuf,
  115. Int32 inLen,
  116. Card32 PTR_PREFIX *outLen
  117. )
  118. {
  119. Card8 Datum;
  120. Int32 i;
  121. *outLen = (inLen << 1);
  122. h->outBuffer.charsOnLine = 0;
  123. for (i = 0; i < inLen; i++) /* for all input data */
  124. {
  125. Datum = *inBuf++;
  126. *outBuf++ = HexTable[((Card8)(Datum >> 4)) & 0x0f];
  127. *outBuf++ = HexTable[((Card8)Datum) & 0x0f];
  128. h->outBuffer.charsOnLine+=2;
  129. if (h->outBuffer.charsOnLine > EOL_SPACING) /* End of the line reached */
  130. {
  131. #if 0
  132. *outBuf++ = '\r';
  133. *outBuf++ = '\n';
  134. *outLen += 2;
  135. #else
  136. Card8 PTR_PREFIX *p;
  137. for (p = (Card8 *)XCF_NEW_LINE; *p; ++p)
  138. {
  139. *outBuf++ = *p;
  140. *outLen += 1;
  141. }
  142. #endif
  143. h->outBuffer.charsOnLine = 0;
  144. }
  145. }
  146. }
  147. static void WriteSizedNumber(XCF_Handle h, Card8 PTR_PREFIX *data, Card32
  148. length)
  149. {
  150. Card32 bytesWritten;
  151. if (h->options.hexEncoding)
  152. {
  153. BufferHexEncode(h, data, h->outBuffer.eexecEncodeBuffer, length,
  154. &bytesWritten);
  155. XCF_PutData(h, h->outBuffer.eexecEncodeBuffer, bytesWritten);
  156. }
  157. else
  158. XCF_PutData(h, data, length);
  159. }
  160. #if HAS_COOLTYPE_UFL == 0
  161. static
  162. #endif
  163. void PutSizedNumber(XCF_Handle h, Card32 value, Card16 size)
  164. {
  165. Card8 data;
  166. switch (size)
  167. {
  168. case 4:
  169. data = (Card8) (value >> 24 & 0xff);
  170. WriteSizedNumber(h, &data, 1);
  171. case 3:
  172. data = (Card8) (value >> 16 & 0xff);
  173. WriteSizedNumber(h, &data, 1);
  174. case 2:
  175. data = (Card8) (value >> 8 & 0xff);
  176. WriteSizedNumber(h, &data, 1);
  177. case 1:
  178. data = (Card8) (value & 0xff);
  179. WriteSizedNumber(h, &data, 1);
  180. break;
  181. default:
  182. XCF_FATAL_ERROR(h, XCF_IndexOutOfRange, "bad size on PutSizedNumber", size);
  183. }
  184. }
  185. static void HexEncodeCharString(XCF_Handle h, Card8 PTR_PREFIX *pData,
  186. Card32 length)
  187. {
  188. Card32 blockSize, encodedBlockSize;
  189. while (length > 0)
  190. {
  191. blockSize = MIN(length, MAX_ENCODE_LENGTH);
  192. BufferHexEncode(h, pData, h->outBuffer.eexecEncodeBuffer, blockSize,
  193. &encodedBlockSize);
  194. XCF_PutData(h, h->outBuffer.eexecEncodeBuffer, encodedBlockSize);
  195. length -= blockSize;
  196. pData += blockSize;
  197. }
  198. }
  199. void XT1_PutT1Data(XCF_Handle h, Card8 PTR_PREFIX *pData, Card32 length)
  200. {
  201. Card32 blockSize, encodedBlockSize;
  202. if (!h->outBuffer.eexecOn)
  203. XCF_PutData(h, pData, length);
  204. else
  205. {
  206. while (length > 0)
  207. {
  208. blockSize = MIN(length,MAX_ENCODE_LENGTH);
  209. BufferEncrypt(h, pData, h->outBuffer.eexecEncodeBuffer,
  210. blockSize, &encodedBlockSize, &h->outBuffer.eexecKey,
  211. h->options.hexEncoding);
  212. XCF_PutData(h, h->outBuffer.eexecEncodeBuffer, encodedBlockSize);
  213. length -= blockSize;
  214. pData += blockSize;
  215. }
  216. }
  217. }
  218. #if HAS_COOLTYPE_UFL==0
  219. static
  220. #endif
  221. Card32 PutType1CharString(XCF_Handle h, Card8 PTR_PREFIX *pData, Card32 length) {
  222. Card32 blockSize, encodedBlockSize;
  223. Card16 lenIVKey;
  224. Card32 bytesWritten = length;
  225. if (h->options.lenIV == -1)
  226. {
  227. if (h->options.hexEncoding)
  228. HexEncodeCharString(h, pData, length);
  229. else
  230. XT1_PutT1Data(h, pData, length);
  231. }
  232. else
  233. #ifdef T13
  234. if (!XT13_PutCharString(h, pData, length, &bytesWritten))
  235. #endif
  236. {
  237. bytesWritten += h->options.lenIV;
  238. lenIVKey = LEN_IV_INITIAL_KEY;
  239. BufferEncrypt(h, h->outBuffer.lenIVInitialBytes,
  240. h->outBuffer.charStringEncodeBuffer, h->options.lenIV,
  241. &encodedBlockSize, &lenIVKey, false);
  242. if (h->options.hexEncoding && !h->outBuffer.eexecOn)
  243. HexEncodeCharString(h, h->outBuffer.charStringEncodeBuffer, encodedBlockSize);
  244. else
  245. XT1_PutT1Data(h, h->outBuffer.charStringEncodeBuffer, encodedBlockSize);
  246. while (length > 0)
  247. {
  248. blockSize = MIN(length,MAX_ENCODE_LENGTH);
  249. BufferEncrypt(h, pData, h->outBuffer.charStringEncodeBuffer, blockSize, &encodedBlockSize, &lenIVKey, false);
  250. if (h->options.hexEncoding && !h->outBuffer.eexecOn)
  251. HexEncodeCharString(h, h->outBuffer.charStringEncodeBuffer, encodedBlockSize);
  252. else
  253. XT1_PutT1Data(h, h->outBuffer.charStringEncodeBuffer, encodedBlockSize);
  254. length -= blockSize;
  255. pData += blockSize;
  256. }
  257. }
  258. return bytesWritten;
  259. }
  260. static void PutStringID(XCF_Handle h, StringID sid)
  261. {
  262. char PTR_PREFIX *str;
  263. Card16 len;
  264. XCF_LookUpString(h, sid, &str, &len);
  265. XT1_PutT1Data(h,(Card8 PTR_PREFIX *)str,len);
  266. }
  267. static void PutString(XCF_Handle h, char PTR_PREFIX *str)
  268. {
  269. XT1_PutT1Data(h,(Card8 PTR_PREFIX *)str,h->callbacks.strlen(str));
  270. }
  271. static void PutLine(XCF_Handle h, char PTR_PREFIX *str)
  272. {
  273. PutString(h, str);
  274. PutString(h, XCF_NEW_LINE);
  275. }
  276. static void PutLongNumber(XCF_Handle h, long n)
  277. {
  278. char str[30];
  279. h->callbacks.xcfSprintf(str, CCHOF(str), "%ld", n);
  280. PutString(h,str);
  281. }
  282. #ifdef XCF_REAL_OK
  283. static void PutNumber(XCF_Handle h, Fixed n, boolean fracType)
  284. {
  285. char str[30];
  286. if ((!fracType && (n & 0x0000FFFF) == 0) || (fracType && (n & 0x3FFFFFFF) == 0))
  287. /* n is an integer */
  288. h->callbacks.xcfSprintf(str, CCHOF(str), "%ld", fracType ? (Int32)FRAC_TO_REAL(n) : (Int32)FIXED_TO_INT(n));
  289. else
  290. h->callbacks.xcfSprintf(str, CCHOF(str), "%.7g", fracType ? FRAC_TO_REAL(n) : FIXED_TO_REAL(n));
  291. PutString(h,str);
  292. }
  293. static void PutRoundedFixedNumber(XCF_Handle h, Fixed n)
  294. {
  295. char str[30];
  296. h->callbacks.xcfSprintf(str, CCHOF(str), "%.2f", FIXED_TO_REAL(n));
  297. PutString(h,str);
  298. }
  299. #else
  300. static void PutNumber(XCF_Handle h, Fixed n, boolean fracType)
  301. {
  302. char str[30];
  303. if ((!fracType && (n & 0x0000FFFF) == 0) || (fracType && (n & 0x3FFFFFFF) == 0))
  304. /* n is an integer */
  305. h->callbacks.xcfSprintf(str, CCHOF(str), "%ld", fracType ? (Int32)(n >> 30) : (Int32)FIXED_TO_INT(n));
  306. else
  307. XCF_Fixed2CString(n, str, 7, fracType);
  308. PutString(h,str);
  309. }
  310. static void PutRoundedFixedNumber(XCF_Handle h, Fixed n)
  311. {
  312. char str[30];
  313. XCF_Fixed2CString(n, str, 2, false);
  314. PutString(h,str);
  315. }
  316. #endif /* XCF_REAL_OK */
  317. static void StartEexec(XCF_Handle h)
  318. {
  319. PutString(h,"currentfile eexec ");
  320. XCF_FlushOutputBuffer(h);
  321. h->outBuffer.eexecOn = true;
  322. h->outBuffer.charsOnLine = INITIAL_CHARS_ON_HEX_LINE;
  323. h->outBuffer.eexecKey = EEXEC_INITIAL_KEY;
  324. XT1_PutT1Data(h, h->outBuffer.eexecInitialBytes, 4);
  325. }
  326. static void StopEexec(XCF_Handle h)
  327. {
  328. XCF_FlushOutputBuffer(h);
  329. h->outBuffer.eexecOn = false;
  330. }
  331. static void WriteSIDLine(XCF_Handle h, char *name, Fixed sid, IntX count)
  332. {
  333. if (count)
  334. {
  335. PutString(h, "/");
  336. PutString(h, name);
  337. PutString(h, " (");
  338. PutStringID(h, (StringID)sid);
  339. PutString(h, ")" T1_READONLY " def" XCF_NEW_LINE);
  340. }
  341. }
  342. static void WriteLongNumberLine(XCF_Handle h, char *name, long number, IntX count)
  343. {
  344. if (count)
  345. {
  346. PutString(h, "/");
  347. PutString(h, name);
  348. PutString(h, " ");
  349. PutLongNumber(h, number);
  350. PutString(h, " def" XCF_NEW_LINE);
  351. }
  352. }
  353. static void WriteNumberLine(XCF_Handle h, char *name, Fixed number, IntX count,
  354. boolean fracType)
  355. {
  356. if (count)
  357. {
  358. PutString(h, "/");
  359. PutString(h, name);
  360. PutString(h, " ");
  361. PutNumber(h, number, fracType);
  362. PutString(h, " def" XCF_NEW_LINE);
  363. }
  364. }
  365. static Fixed PutNumberList(XCF_Handle h, Fixed numbers[], IntX count, boolean
  366. delta, Fixed initialValue, boolean fracType)
  367. {
  368. Fixed number = initialValue;
  369. Int16 i;
  370. for (i=0; i < count; ++i)
  371. {
  372. if (delta)
  373. number += numbers[i];
  374. else
  375. number = numbers[i];
  376. PutNumber(h, number, fracType);
  377. PutString(h, " ");
  378. }
  379. return number;
  380. }
  381. static void PutBlendNumberList(XCF_Handle h, Fixed numbers[], IntX count,
  382. boolean delta,
  383. Fixed PTR_PREFIX *pInitialValues,
  384. IntX iniValCount,
  385. boolean fracType)
  386. {
  387. Fixed number;
  388. Int16 i;
  389. for (i=0; (i < count) && (i < iniValCount); ++i)
  390. {
  391. if (delta)
  392. number = numbers[i] + *pInitialValues;
  393. else
  394. number = numbers[i];
  395. PutNumber(h, number, fracType);
  396. PutString(h, " ");
  397. *pInitialValues++ = number;
  398. }
  399. }
  400. static void PutFontMatrix(XCF_Handle h, char (PTR_PREFIX *list)[FONT_MATRIX_ENTRY_SIZE], IntX count)
  401. {
  402. Int16 i;
  403. for (i = 0; i < count; i++)
  404. {
  405. PutString(h, list[i]);
  406. PutString(h, " ");
  407. }
  408. }
  409. static void WriteNumberListLine(XCF_Handle h, char PTR_PREFIX *name, Fixed
  410. numbers[], IntX count, boolean fracType)
  411. {
  412. if (count)
  413. {
  414. PutString(h, "/");
  415. PutString(h, name);
  416. PutString(h, " [");
  417. PutNumberList(h, numbers, count, false, 0, fracType);
  418. PutString(h, "]" T1_READONLY " def" XCF_NEW_LINE);
  419. }
  420. }
  421. static void WriteLongNumberListLine(XCF_Handle h, char PTR_PREFIX *name, Card32
  422. numbers[], IntX count)
  423. {
  424. Int16 i;
  425. if (count)
  426. {
  427. PutString(h, "/");
  428. PutString(h, name);
  429. PutString(h, " [");
  430. for (i = 0; i < count; i++)
  431. {
  432. PutLongNumber(h, numbers[i]);
  433. PutString(h, " ");
  434. }
  435. PutString(h, "]" T1_READONLY " def" XCF_NEW_LINE);
  436. }
  437. }
  438. static void WriteFontMatrix(XCF_Handle h, char PTR_PREFIX *name,
  439. char (PTR_PREFIX *stringList)[FONT_MATRIX_ENTRY_SIZE], IntX count)
  440. {
  441. if (count)
  442. {
  443. PutString(h, "/");
  444. PutString(h, name);
  445. PutString(h, " [");
  446. PutFontMatrix(h, stringList, count);
  447. PutString(h, "]" T1_READONLY " def" XCF_NEW_LINE);
  448. }
  449. }
  450. static Fixed Blend(XCF_Handle h, Fixed numbers[], IntX count, boolean delta,
  451. Fixed PTR_PREFIX *pInitialValues, IntX iniValCount, boolean fracType)
  452. {
  453. Fixed blend = 0;
  454. Fixed value;
  455. IntX i;
  456. if (count == 1)
  457. return(numbers[0]);
  458. else
  459. {
  460. if (count != h->dict.numberOfMasters)
  461. XCF_FATAL_ERROR(h, XCF_InvalidBlendArgumentCount, "Blend argument count does not equal number of masters", count);
  462. for (i=0; (i < count) && (i < iniValCount) ; ++i)
  463. {
  464. if (delta)
  465. value = numbers[i] + *pInitialValues;
  466. else
  467. value = numbers[i];
  468. blend += fracType? XCF_FracMul(value, h->dict.weightVector[i] << 14) : XCF_FixMul(value, h->dict.weightVector[i]);
  469. *pInitialValues++ = value;
  470. }
  471. }
  472. return blend;
  473. }
  474. static void PutBlendedNumber(XCF_Handle h, Fixed numbers[], IntX count,
  475. boolean delta, Fixed PTR_PREFIX *pInitialValues,
  476. IntX iniValCount, boolean fracType)
  477. {
  478. Fixed val = Blend(h, numbers, count, delta, pInitialValues, iniValCount, fracType);
  479. if (fracType)
  480. PutNumber(h, val, true);
  481. else
  482. PutRoundedFixedNumber(h, val);
  483. }
  484. static void PutBlend(XCF_Handle h, Fixed numbers[], IntX count, boolean
  485. instance, boolean squareBrackets, boolean delta, Fixed
  486. PTR_PREFIX *pInitialValues, IntX iniValCount, boolean fracType)
  487. {
  488. IntX i;
  489. if (count == 1)
  490. {
  491. if ((h->dict.numberOfMasters == 0) || (instance))
  492. PutNumber(h, numbers[0], fracType);
  493. else /* expand single value to number of masters */
  494. {
  495. PutString(h, squareBrackets ? "[ " : "{ ");
  496. for (i = 0; i < h->dict.numberOfMasters; ++i)
  497. {
  498. PutNumber(h, numbers[0], fracType);
  499. PutString(h, " ");
  500. }
  501. PutString(h, squareBrackets ? "]" : "}");
  502. }
  503. }
  504. else if (instance)
  505. {
  506. PutBlendedNumber(h, numbers, count, delta, pInitialValues, iniValCount, fracType);
  507. }
  508. else
  509. {
  510. PutString(h, squareBrackets ? "[ " : "{ ");
  511. PutBlendNumberList(h, numbers, count, delta, pInitialValues, iniValCount, fracType);
  512. PutString(h, squareBrackets ? "]" : "}");
  513. }
  514. }
  515. static void WriteBlendLine(XCF_Handle h, char PTR_PREFIX *name, Fixed
  516. numbers[], IntX count, boolean instance, boolean
  517. squareBrackets, boolean delta, boolean fracType)
  518. {
  519. Fixed previousValues[MAX_RASTERIZER_STACK_SIZE] = {0};
  520. if (count)
  521. {
  522. PutString(h, "/");
  523. PutString(h, name);
  524. PutString(h, " ");
  525. PutBlend(h, numbers, count, instance, squareBrackets, delta,
  526. &previousValues[0],
  527. sizeof(previousValues)/sizeof(Fixed), fracType);
  528. PutString(h, " def" XCF_NEW_LINE);
  529. }
  530. }
  531. static void PutBlendArray(XCF_Handle h, Fixed numbers[], IntX count, boolean
  532. instance, boolean squareBrackets, boolean delta,
  533. boolean fracType)
  534. {
  535. IntX blendCount;
  536. IntX i;
  537. Fixed previousValues[MAX_RASTERIZER_STACK_SIZE] = {0};
  538. if (h->dict.numberOfMasters == 0)
  539. PutNumberList(h, numbers, count, delta, 0, fracType);
  540. else
  541. {
  542. blendCount = (IntX) (count / h->dict.numberOfMasters);
  543. for (i = 0; i < blendCount; ++i)
  544. {
  545. PutBlend(h, &numbers[i*h->dict.numberOfMasters], h->dict.numberOfMasters,
  546. instance, squareBrackets, delta, &previousValues[0],
  547. sizeof(previousValues)/sizeof(Fixed), fracType);
  548. PutString(h, " ");
  549. }
  550. }
  551. }
  552. static void WriteBlendArrayLine(XCF_Handle h, char PTR_PREFIX *name, Fixed
  553. numbers[], IntX count, boolean instance,
  554. boolean squareBrackets, boolean delta,
  555. boolean fracType)
  556. {
  557. if (count)
  558. {
  559. PutString(h, "/");
  560. PutString(h, name);
  561. PutString(h, squareBrackets ? " [ " : " { ");
  562. PutBlendArray(h, numbers, count, instance, squareBrackets, delta, fracType);
  563. PutString(h, squareBrackets ? "]" : "}");
  564. PutString(h, " def" XCF_NEW_LINE);
  565. }
  566. }
  567. static void PutBoolean(XCF_Handle h, Fixed value)
  568. {
  569. if (value)
  570. PutString(h, "true ");
  571. else
  572. PutString(h, "false ");
  573. }
  574. static void PutBlendBoolean(XCF_Handle h, Fixed values[], IntX count, boolean instance, Fixed threshold)
  575. {
  576. Fixed blend = 0;
  577. IntX i;
  578. if (count == 1)
  579. {
  580. if ((h->dict.numberOfMasters == 0) || (instance))
  581. PutBoolean(h, values[0]);
  582. else /* expand single value to number of masters */
  583. {
  584. PutString(h, "[ ");
  585. for (i = 0; i < h->dict.numberOfMasters; ++i)
  586. PutBoolean(h, values[0]);
  587. PutString(h, "]");
  588. }
  589. }
  590. else if (instance)
  591. {
  592. for (i=0; i < count ; ++i)
  593. blend += XCF_FixMul(values[i], h->dict.weightVector[i]);
  594. PutBoolean(h, (blend >= threshold));
  595. }
  596. else
  597. {
  598. PutString(h, "[ ");
  599. for (i=0; i < count ; ++i)
  600. PutBoolean(h, values[i]);
  601. PutString(h, "]");
  602. }
  603. }
  604. static char StreamEncodeName(XCF_Handle h)
  605. {
  606. if (!h->options.dlOptions.encodeName)
  607. return 0;
  608. PutString(h, "/Encoding ");
  609. PutString(h, (char PTR_PREFIX *)h->options.dlOptions.encodeName);
  610. PutString(h, " def" XCF_NEW_LINE);
  611. return 1;
  612. }
  613. static char StreamFontName(XCF_Handle h)
  614. {
  615. if (!h->options.dlOptions.fontName)
  616. return 0;
  617. PutString(h, (char PTR_PREFIX *)h->options.dlOptions.fontName);
  618. return 1;
  619. }
  620. static char StreamUID(XCF_Handle h)
  621. {
  622. switch (h->options.uniqueIDMethod)
  623. {
  624. case XCF_KEEP_UID:
  625. return 0;
  626. case XCF_UNDEFINE_UID:
  627. return 1;
  628. case XCF_USER_UID:
  629. WriteLongNumberLine(h, "UniqueID", h->options.uniqueID, 1);
  630. return 1;
  631. default:
  632. return 0;
  633. }
  634. }
  635. static char StreamKeyPointData(XCF_Handle h, Card16 code)
  636. {
  637. switch (code)
  638. {
  639. case XCF_ENCODING:
  640. return StreamEncodeName(h);
  641. break;
  642. case XCF_FONTNAME:
  643. return StreamFontName(h);
  644. break;
  645. case XCF_UID:
  646. return StreamUID(h);
  647. break;
  648. }
  649. return 0;
  650. }
  651. static void WriteBlendBooleanLine(XCF_Handle h, char PTR_PREFIX *name, Fixed values[], IntX count, boolean instance, Fixed threshold)
  652. {
  653. if (count)
  654. {
  655. PutString(h, "/");
  656. PutString(h, name);
  657. PutString(h, " ");
  658. PutBlendBoolean(h, values, count, instance, threshold);
  659. PutString(h, " def" XCF_NEW_LINE);
  660. }
  661. }
  662. #define BLDOTHERSUBRS (5) /* Number of OtherSubrs specific to mmfonts. */
  663. static void WriteRoll(XCF_Handle h, int m, int n)
  664. {
  665. char str[50];
  666. if (m < 2 || n == 0 || n == m)
  667. return;
  668. if (m == 2 && (n == 1 || n == -1))
  669. {
  670. PutString(h, "exch ");
  671. return;
  672. }
  673. if (n < 0 && m + n <= -n)
  674. n = m + n;
  675. h->callbacks.xcfSprintf(str, CCHOF(str), "%ld %ld roll ", m, n);
  676. PutString(h, str);
  677. }
  678. /* Writes the PS code for OtherSubrs 14 - 18, if necessary. If
  679. this OtherSubr is unnecessary, i.e. the # of masters times
  680. the # of results exceeds the font stack limit then no more
  681. OtherSubrs are written out. */
  682. static void WriteBlendOtherSubrs(XCF_Handle h)
  683. {
  684. int i = 0;
  685. int j;
  686. int resultCt[BLDOTHERSUBRS]; /* Number of results after blending */
  687. int numOutput = 0;
  688. resultCt[i++] = 1;
  689. resultCt[i++] = 2;
  690. resultCt[i++] = 3;
  691. resultCt[i++] = 4;
  692. resultCt[i++] = 6;
  693. for (i = 0; i < BLDOTHERSUBRS; i++)
  694. {
  695. if (h->dict.numberOfMasters * resultCt[i] > T1_MAX_OP_STACK)
  696. break;
  697. PutString(h, "{ ");
  698. for (j = resultCt[i]; j > 1; j--)
  699. {
  700. WriteRoll(h, resultCt[i], -1);
  701. WriteRoll(h, j * (h->dict.numberOfMasters - 1) + resultCt[i], 1 -
  702. h->dict.numberOfMasters);
  703. PutString(h, "$Blend ");
  704. }
  705. WriteRoll(h, resultCt[i], -1);
  706. WriteRoll(h, h->dict.numberOfMasters + resultCt[i] - 1,
  707. -(h->dict.numberOfMasters - 1));
  708. PutString(h, "$Blend } bind" XCF_NEW_LINE);
  709. numOutput++;
  710. }
  711. /* Make certain that we output up through OtherSubr #18. */
  712. for (i = numOutput; i < BLDOTHERSUBRS; i++)
  713. PutString(h, "{}" XCF_NEW_LINE);
  714. }
  715. /* Write the PS code for OtherSubrs 19-27. Currently, these are only
  716. defined for fonts with transitional designs and are for backward
  717. compatibility with earlier rasterizers that did not have these
  718. operators defined. */
  719. static void WriteAdditionalOtherSubrs(XCF_Handle h)
  720. {
  721. /* 19 storeWV */
  722. PutString(h, "{currentfont dup /WeightVector get exch /Private get /BuildCharArray get 3 -1 roll cvi 3 -1 roll putinterval}" XCF_NEW_LINE);
  723. /* 20 add */
  724. PutString(h, "{add}" XCF_NEW_LINE);
  725. /* 21 sub */
  726. PutString(h, "{exch sub}" XCF_NEW_LINE);
  727. /* 22 mul */
  728. PutString(h, "{mul}" XCF_NEW_LINE);
  729. /* 23 div */
  730. PutString(h, "{exch div}" XCF_NEW_LINE);
  731. /* 24 put */
  732. PutString(h, "{currentfont /Private get /BuildCharArray get 3 1 roll exch cvi exch put}" XCF_NEW_LINE);
  733. /* 25 get */
  734. PutString(h, "{currentfont /Private get /BuildCharArray get exch cvi get }"
  735. XCF_NEW_LINE);
  736. /* 26 psput */
  737. PutString(h, "{exch dup mark eq {3 1 roll}{exch} ifelse currentfont /Private get /BuildCharArray get 3 1 roll cvi exch put}" XCF_NEW_LINE);
  738. /* 27 ifelse */
  739. PutString(h, "{4 2 roll exch le {exch} if pop}" XCF_NEW_LINE);
  740. }
  741. static void WriteOtherSubrs(XCF_Handle h, boolean flexUsed, boolean hintSubUsed)
  742. {
  743. /* Check if the client requests to use special names for OtherSubrs 0-3. */
  744. if ( h->options.dlOptions.otherSubrNames )
  745. {
  746. unsigned short i;
  747. PutString(h, "/OtherSubrs [" XCF_NEW_LINE);
  748. for ( i = 0; i < 4; i++ )
  749. {
  750. PutString(h, "{");
  751. #if HAS_COOLTYPE_UFL == 1
  752. PutString(h, "ct_CffDict/");
  753. #endif
  754. if ( h->options.dlOptions.otherSubrNames[i] )
  755. {
  756. PutString(h, (char PTR_PREFIX *)h->options.dlOptions.otherSubrNames[i]);
  757. #if HAS_COOLTYPE_UFL == 1
  758. PutString(h, " get exec");
  759. #endif
  760. PutString(h, "}executeonly");
  761. }
  762. else
  763. {
  764. PutString(h, "}");
  765. }
  766. }
  767. if (h->dict.numberOfMasters)
  768. {
  769. PutString(h, "{} {} {}" XCF_NEW_LINE); /* 4-6 */
  770. PutString(h, "{} {} {} {} {} {} {} " XCF_NEW_LINE); /* 7-13 */
  771. WriteBlendOtherSubrs(h); /* 14-18 */
  772. if (XCF_TransDesignFont(h))
  773. WriteAdditionalOtherSubrs(h); /* 19-27 */
  774. }
  775. PutString(h, "] |-" XCF_NEW_LINE);
  776. return;
  777. }
  778. if (flexUsed || hintSubUsed || h->dict.numberOfMasters)
  779. {
  780. PutString(h, "/OtherSubrs" XCF_NEW_LINE);
  781. if (flexUsed)
  782. {
  783. PutString(h, FlexOtherSubrStr1);
  784. PutString(h, FlexOtherSubrStr2);
  785. PutString(h, FlexOtherSubrStr3);
  786. PutString(h, FlexOtherSubrStr4);
  787. PutString(h, FlexOtherSubrStr5);
  788. PutString(h, FlexOtherSubrStr6);
  789. PutString(h, FlexOtherSubrStr7);
  790. PutString(h, FlexOtherSubrStr8);
  791. PutString(h, FlexOtherSubrStr9);
  792. PutString(h, FlexOtherSubrStr10);
  793. PutString(h, FlexOtherSubrStr11);
  794. PutString(h, FlexOtherSubrStr12);
  795. PutString(h, FlexOtherSubrStr13);
  796. PutString(h, FlexOtherSubrStr14);
  797. PutString(h, FlexOtherSubrStr15);
  798. PutString(h, FlexOtherSubrStr16);
  799. PutString(h, FlexOtherSubrStr17);
  800. }
  801. else
  802. {
  803. PutString(h, "[ {} {} {}" XCF_NEW_LINE);
  804. }
  805. if (hintSubUsed)
  806. {
  807. PutString(h, HintSubtitutionOtherSubrStr);
  808. }
  809. else
  810. {
  811. PutString(h, "{}" XCF_NEW_LINE); /* 3 */
  812. }
  813. PutString(h, "{} {} {}" XCF_NEW_LINE); /* 4-6 */
  814. if (h->dict.numberOfMasters)
  815. {
  816. PutString(h, "{} {} {} {} {} {} {} " XCF_NEW_LINE); /* 7-13 */
  817. WriteBlendOtherSubrs(h); /* 14-18 */
  818. if (XCF_TransDesignFont(h))
  819. WriteAdditionalOtherSubrs(h); /* 19-27 */
  820. }
  821. PutString(h, "]|-" XCF_NEW_LINE);
  822. }
  823. }
  824. static void WriteCIDOtherSubrs(XCF_Handle h)
  825. {
  826. PutLine(h, XCF_NEW_LINE "/OtherSubrs [ {} {} {} { systemdict /internaldict known not" XCF_NEW_LINE
  827. "{ pop 3 } { 1183615869 systemdict /internaldict get exec dup" XCF_NEW_LINE
  828. "/startlock known { /startlock get exec }" XCF_NEW_LINE
  829. "{ dup /strtlck known { /strtlck get exec } { pop 3 } ifelse } ifelse } ifelse } bind" XCF_NEW_LINE
  830. "{} {} {} {} {} {} {} {} {}" XCF_NEW_LINE
  831. "{ 2 {cvi { { pop 0 lt { exit } if } loop } repeat } repeat } bind" XCF_NEW_LINE
  832. "{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} ] def");
  833. }
  834. static void PutCharacterName(XCF_Handle h, CardX index,
  835. unsigned char PTR_PREFIX **pGlyphName)
  836. {
  837. if (pGlyphName)
  838. PutString(h, (char PTR_PREFIX *)pGlyphName[index]);
  839. else
  840. {
  841. if (index)
  842. PutStringID(h, h->type1.pCharset[index-1]);
  843. else
  844. PutStringID(h, 0);
  845. }
  846. }
  847. static void PutFontName(XCF_Handle h)
  848. {
  849. if (!StreamKeyPointData(h, XCF_FONTNAME))
  850. {
  851. XCF_LookUpTableEntry(h, &h->fontSet.fontNames, h->fontSet.fontIndex);
  852. XT1_PutT1Data(h,(Card8 PTR_PREFIX *)h->inBuffer.start, (Card16)h->inBuffer.blockLength);
  853. }
  854. }
  855. /*
  856. Dictionary Entries
  857. *** Font Info Dict ***
  858. version
  859. Notice
  860. FullName
  861. FamilyName
  862. Weight
  863. isFixedPitch Default = "false"
  864. ItalicAngle Default = 0
  865. UnderlinePosition Default = -100
  866. UnderlineThickness Default = 50
  867. Copyright
  868. SyntheticBase
  869. BaseFontName
  870. BaseFontBlend
  871. *** Font Dict ***
  872. FontName
  873. Encoding Default = StandardEncoding
  874. PaintType Default = 0
  875. FontType
  876. FontMatrix Default = [0.001 0 0 0.001 0 0]
  877. FontBBox
  878. UniqueID
  879. XUID
  880. StrokeWidth Default = 0
  881. Private
  882. CharStrings
  883. BlendDesignMap
  884. BlendAxisTypes
  885. WeightVector
  886. *** Private Dict ***
  887. BlueValues Default = [] -- Emit empty brackets if there are no BlueValues
  888. OtherBlues
  889. FamilyBlues
  890. FamilyOtherBlues
  891. StdHW
  892. StdVW
  893. BlueScale Default = 0.039625
  894. BlueShift Default = 7
  895. BlueFuzz Default = 1
  896. StemSnapH
  897. StemSnapV
  898. ForceBold Default = "false"
  899. ForceBoldThreshold Default = 0
  900. lenIV
  901. LanguageGroup Default = 0
  902. ExpansionFactor Default = 0.06
  903. initialRandomSeed Default = 0
  904. PostScript
  905. defaultWidthX
  906. nominalWidthX
  907. NDV
  908. CDV
  909. lenBuildCharArray
  910. */
  911. static boolean GlyphInCharSet(XCF_Handle h, StringID sid)
  912. {
  913. CardX i;
  914. for (i=0; i < h->type1.charsetSize; ++i)
  915. if (sid == h->type1.pCharset[i])
  916. return true;
  917. return false;
  918. }
  919. static void WriteEncodingArray(XCF_Handle h)
  920. {
  921. char str[50];
  922. CardX i;
  923. if (h->options.dlOptions.notdefEncoding)
  924. {
  925. PutString(h, "/Encoding 256 array" XCF_NEW_LINE);
  926. PutString(h, "0 1 255 {1 index exch /.notdef put} for");
  927. #if HAS_COOLTYPE_UFL == 1
  928. /* If this font needs to be parsed by CoolType or ATM then the
  929. * Encoding array needs to explicitly define at least one
  930. * encoding via the dup <charcode>/<name> put format.
  931. */
  932. PutString(h, XCF_NEW_LINE);
  933. PutString(h, "dup 0 /.notdef put" XCF_NEW_LINE);
  934. PutString(h, T1_READONLY " def" XCF_NEW_LINE);
  935. #else
  936. PutString(h, " def" XCF_NEW_LINE);
  937. #endif
  938. return;
  939. }
  940. if ((!h->dict.encodingCount) || (h->dict.encoding == cff_StandardEncoding))
  941. PutString(h, "/Encoding StandardEncoding def" XCF_NEW_LINE);
  942. else
  943. {
  944. PutString(h, "/Encoding 256 array" XCF_NEW_LINE);
  945. PutString(h, "0 1 255 {1 index exch /.notdef put} for" XCF_NEW_LINE);
  946. for (i=0;i<256;++i)
  947. {
  948. if (h->type1.pEncoding[i] != NOTDEF_SID)
  949. {
  950. if ((h->dict.encoding != cff_ExpertEncoding) || GlyphInCharSet(h, h->type1.pEncoding[i]))
  951. {
  952. h->callbacks.xcfSprintf(str, CCHOF(str), "dup %ld /",(long int)i);
  953. PutString(h, str);
  954. PutStringID(h, h->type1.pEncoding[i]);
  955. PutString(h," put" XCF_NEW_LINE);
  956. }
  957. }
  958. }
  959. PutString(h, T1_READONLY " def" XCF_NEW_LINE);
  960. }
  961. }
  962. static void WriteBlendAxisTypes(XCF_Handle h)
  963. {
  964. IntX i;
  965. if (!h->dict.blendAxisTypesCount)
  966. return;
  967. PutString(h, "/BlendAxisTypes [");
  968. for (i=0;i<h->dict.blendAxisTypesCount;++i)
  969. {
  970. PutString(h, "/");
  971. PutStringID(h, (StringID)h->dict.blendAxisTypes[i]);
  972. PutString(h, " ");
  973. }
  974. PutString(h, "] def" XCF_NEW_LINE);
  975. }
  976. static CardX FontInfoDictCount(XCF_Handle h)
  977. {
  978. CardX count = 5; /* Add extra space for safety margin */
  979. count += (h->dict.noticeCount != 0);
  980. count += (h->dict.copyrightCount != 0);
  981. count += (h->dict.versionCount != 0);
  982. count += (h->dict.fullNameCount != 0);
  983. count += (h->dict.familyNameCount != 0);
  984. count += (h->dict.baseFontNameCount != 0);
  985. count += (h->dict.baseFontBlendCount != 0);
  986. count += (h->dict.weightCount != 0);
  987. count += (h->dict.italicAngleCount != 0);
  988. count += (h->dict.isFixedPitchCount != 0);
  989. count += (h->dict.underlinePositionCount != 0);
  990. count += (h->dict.underlineThicknessCount != 0);
  991. count += (h->dict.blendAxisTypesCount != 0);
  992. count += (h->callbacks.getFSType != 0);
  993. if (h->dict.numberOfMasters != 0)
  994. count += 4; /* Add for /DesignVector, /NormDesignVector,
  995. * /BlendDesignPositions, and /BlendDesignMap */
  996. return count;
  997. }
  998. static CardX FontDictCount(XCF_Handle h)
  999. {
  1000. CardX count;
  1001. /* Add extra space for FontName, Encoding, FontType, etc. plus safety margin.
  1002. * For mm fonts enough space is added for all of the extra mm definitions */
  1003. count = (h->dict.numberOfMasters != 0) ? 25 : 10;
  1004. count += (h->dict.paintTypeCount != 0);
  1005. count += (h->dict.fontMatrixCount != 0);
  1006. count += (h->dict.fontBBoxCount != 0);
  1007. count += (h->dict.uniqueIDCount != 0);
  1008. count += (h->dict.xUIDCount != 0);
  1009. count += (h->dict.strokeWidthCount != 0);
  1010. return count;
  1011. }
  1012. static CardX PrivateDictCount(XCF_Handle h)
  1013. {
  1014. CardX count = 15; /* Add extra space for LenIV, MinFeature, password, Erode, OtherSubrs, Subr, etc. plus safety margin */
  1015. count += (h->dict.uniqueIDCount != 0);
  1016. count += (h->dict.blueValuesCount != 0);
  1017. count += (h->dict.otherBluesCount != 0);
  1018. count += (h->dict.familyBluesCount != 0);
  1019. count += (h->dict.familyOtherBluesCount != 0);
  1020. count += (h->dict.stdHWCount != 0);
  1021. count += (h->dict.stdVWCount != 0);
  1022. count += (h->dict.blueScaleCount != 0);
  1023. count += (h->dict.blueShiftCount != 0);
  1024. count += (h->dict.blueFuzzCount != 0);
  1025. count += (h->dict.stemSnapHCount != 0);
  1026. count += (h->dict.stemSnapVCount != 0);
  1027. count += (h->dict.forceBoldCount != 0);
  1028. count += (h->dict.forceBoldThresholdCount != 0);
  1029. count += (h->dict.languageGroupCount != 0);
  1030. count += (h->dict.expansionFactorCount != 0);
  1031. count += (h->dict.initialRandomSeedCount != 0);
  1032. if (h->options.outputCharstrType != 1)
  1033. {
  1034. count += (h->dict.defaultWidthXCount != 0);
  1035. count += (h->dict.nominalWidthXCount != 0);
  1036. }
  1037. if (h->dict.lenBuildCharArrayCount != 0)
  1038. count += 2; /* Add extra one for /BuildCharArray */
  1039. if (h->dict.numberOfMasters > 0)
  1040. count += 2; /* Add 2 for NDV and CDV */
  1041. count += (h->dict.embeddedPostscriptCount != 0);
  1042. #ifdef T13
  1043. if (XT13_IST13(h))
  1044. count++;
  1045. #endif
  1046. return count;
  1047. }
  1048. static void WriteBlendProc(XCF_Handle h)
  1049. {
  1050. IntX vectorIndex;
  1051. if (h->dict.numberOfMasters == 0)
  1052. return;
  1053. PutString(h, "/$Blend {");
  1054. for (vectorIndex = 1; vectorIndex < h->dict.numberOfMasters; ++vectorIndex)
  1055. {
  1056. PutRoundedFixedNumber(h, h->dict.weightVector[vectorIndex]);
  1057. PutString(h, " mul ");
  1058. if (vectorIndex > 1)
  1059. PutString(h, "add ");
  1060. if (vectorIndex < h->dict.numberOfMasters - 1)
  1061. PutString(h, "exch ");
  1062. }
  1063. PutString(h, "add } bind def" XCF_NEW_LINE);
  1064. }
  1065. #if HAS_COOLTYPE_UFL == 1
  1066. static void WriteBlendDict(XCF_Handle h)
  1067. {
  1068. PutString(h, "/Blend 3 dict dup begin" XCF_NEW_LINE );
  1069. WriteBlendArrayLine(h, "FontBBox", h->dict.fontBBox, h->dict.fontBBoxCount,
  1070. false, false, false, false);
  1071. PutString(h, "/FontInfo 3 dict dup begin" XCF_NEW_LINE);
  1072. WriteBlendLine(h, "ItalicAngle", h->dict.italicAngle,
  1073. h->dict.italicAngleCount, false, true, true, false);
  1074. WriteBlendLine(h, "UnderlinePosition", h->dict.underlinePosition,
  1075. h->dict.underlinePositionCount, false, true, true, false);
  1076. WriteBlendLine(h, "UnderlineThickness", h->dict.underlineThickness,
  1077. h->dict.underlineThicknessCount, false, true, true, false);
  1078. PutString(h, "end def" XCF_NEW_LINE);
  1079. PutString(h, "/Private 14 dict def" XCF_NEW_LINE "end def" XCF_NEW_LINE);
  1080. }
  1081. static void WriteMakeBlendedFontOp(XCF_Handle h)
  1082. {
  1083. #include "xcf_mkbf.h"
  1084. }
  1085. static void WriteInterpCharString(XCF_Handle h)
  1086. {
  1087. boolean unprocessed = h->options.outputCharstrType == 2;
  1088. #include "xcf_ics.h"
  1089. }
  1090. static void WriteMMFindFontDef(XCF_Handle h)
  1091. {
  1092. #include "xcf_mmff.h"
  1093. }
  1094. /* Writes the multiple master font specific NormalizeDesignVector and
  1095. * ConvertDesignVector procedures.
  1096. */
  1097. static void WriteDesignVectorProcs(XCF_Handle h)
  1098. {
  1099. char icsmemname[128];
  1100. char icsflagname[128];
  1101. char str[128];
  1102. char fontName[512];
  1103. Card32 subrNum = h->options.outputCharstrType == 1 ?
  1104. h->type1.subrOffsets.cnt : h->dict.localSubrs.count;
  1105. if (h->options.dlOptions.fontName)
  1106. {
  1107. unsigned short int length = sizeof(fontName);
  1108. /* add 1 for null terminator */
  1109. if (length > (unsigned short int)(h->callbacks.strlen((const char PTR_PREFIX *)h->options.dlOptions.fontName) + 1))
  1110. length = (unsigned short int)(h->callbacks.strlen((const char PTR_PREFIX *)h->options.dlOptions.fontName) + 1);
  1111. h->callbacks.memcpy(fontName, h->options.dlOptions.fontName, length);
  1112. }
  1113. else
  1114. XCF_FontName(h, (unsigned short int)h->fontSet.fontIndex, fontName,
  1115. (unsigned short int)(sizeof(fontName)));
  1116. h->callbacks.xcfSprintf(icsmemname, CCHOF(icsmemname), "&%sicsmem", fontName);
  1117. h->callbacks.xcfSprintf(icsflagname, CCHOF(icsflagname), "&%sflag", fontName);
  1118. PutString(h, "/ICSsetup {" XCF_NEW_LINE);
  1119. h->callbacks.xcfSprintf(str, CCHOF(str), "userdict /%s known not {%s", icsmemname,
  1120. XCF_NEW_LINE);
  1121. PutString(h, str);
  1122. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s 25 dict put%s", icsmemname,
  1123. XCF_NEW_LINE);
  1124. PutString(h, str);
  1125. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get /&thisfontdict currentdict put%s", icsmemname, XCF_NEW_LINE);
  1126. PutString(h, str);
  1127. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get /:savestack 10 array put%s",
  1128. icsmemname, XCF_NEW_LINE);
  1129. PutString(h, str);
  1130. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get /:savelevel 0 put%s",
  1131. icsmemname, XCF_NEW_LINE);
  1132. PutString(h, str);
  1133. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get dup /&me exch put%s",
  1134. icsmemname, XCF_NEW_LINE);
  1135. PutString(h, str);
  1136. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get /WeightVector known not {%s",
  1137. icsmemname, XCF_NEW_LINE);
  1138. PutString(h, str);
  1139. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get /WeightVector %d array put%s", icsmemname, h->dict.numberOfMasters, XCF_NEW_LINE);
  1140. PutString(h, str);
  1141. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get /NormDesignVector %d array put%s", icsmemname, h->dict.userDesignVectorCount, XCF_NEW_LINE);
  1142. PutString(h, str);
  1143. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get /DesignVector %d array put%s", icsmemname, h->dict.userDesignVectorCount, XCF_NEW_LINE);
  1144. PutString(h, str);
  1145. PutString(h, " } if" XCF_NEW_LINE);
  1146. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s get {%s", icsflagname, XCF_NEW_LINE);
  1147. PutString(h, str);
  1148. h->callbacks.xcfSprintf(str, CCHOF(str), " currentdict /WeightVector get aload pop userdict /%s", icsmemname);
  1149. PutString(h, str);
  1150. PutString(h, " get /WeightVector get astore pop" XCF_NEW_LINE);
  1151. h->callbacks.xcfSprintf(str, CCHOF(str), " currentdict /NormDesignVector get aload pop userdict /%s", icsmemname);
  1152. PutString(h, str);
  1153. PutString(h, " get /NormDesignVector get astore pop" XCF_NEW_LINE);
  1154. h->callbacks.xcfSprintf(str, CCHOF(str), " currentdict /DesignVector get aload pop userdict /%s", icsmemname);
  1155. PutString(h, str);
  1156. PutString(h, " get /DesignVector get astore pop" XCF_NEW_LINE);
  1157. PutString(h, " } if" XCF_NEW_LINE);
  1158. PutString(h, "} if } bind def" XCF_NEW_LINE);
  1159. PutString(h, "/Pre-N&C {" XCF_NEW_LINE);
  1160. h->callbacks.xcfSprintf(str, CCHOF(str), " userdict /%s known not {userdict /%s true put}%s", icsflagname, icsflagname, XCF_NEW_LINE);
  1161. PutString(h, str);
  1162. h->callbacks.xcfSprintf(str, CCHOF(str), " {/%s true store} ifelse%s", icsflagname,
  1163. XCF_NEW_LINE);
  1164. PutString(h, str);
  1165. PutString(h, "} bind def" XCF_NEW_LINE);
  1166. h->callbacks.xcfSprintf(str, CCHOF(str), "/Post-N&C {/%s false store} bind def%s",
  1167. icsflagname, XCF_NEW_LINE);
  1168. PutString(h, str);
  1169. /* Write NormalizeDesignVector procedure. */
  1170. PutString(h, "/NormalizeDesignVector {" XCF_NEW_LINE);
  1171. PutString(h, "Pre-N&C ICSsetup" XCF_NEW_LINE);
  1172. h->callbacks.xcfSprintf(str, CCHOF(str), "%s /DesignVector get astore pop%s", icsmemname,
  1173. XCF_NEW_LINE);
  1174. PutString(h, str);
  1175. h->callbacks.xcfSprintf(str, CCHOF(str), "%d %s interpcharstring%s", (IntX) subrNum, icsmemname, XCF_NEW_LINE);
  1176. PutString(h, str);
  1177. h->callbacks.xcfSprintf(str, CCHOF(str), "%s /NormDesignVector get aload pop ", icsmemname);
  1178. PutString(h, str);
  1179. PutString(h, XCF_NEW_LINE "} bind def" XCF_NEW_LINE);
  1180. /* Write ConvertDesignVector procedure. */
  1181. PutString(h, "/ConvertDesignVector {" XCF_NEW_LINE);
  1182. PutString(h, "Pre-N&C ICSsetup" XCF_NEW_LINE);
  1183. h->callbacks.xcfSprintf(str, CCHOF(str), "%s /NormDesignVector get astore pop%s",
  1184. icsmemname, XCF_NEW_LINE);
  1185. PutString(h, str);
  1186. h->callbacks.xcfSprintf(str, CCHOF(str), "%d %s interpcharstring%s",
  1187. (IntX) subrNum + 1, icsmemname, XCF_NEW_LINE);
  1188. PutString(h, str);
  1189. PutString(h, "Post-N&C" XCF_NEW_LINE);
  1190. h->callbacks.xcfSprintf(str, CCHOF(str), "%s /WeightVector get aload pop ", icsmemname);
  1191. PutString(h, str);
  1192. PutString(h, XCF_NEW_LINE "} bind def" XCF_NEW_LINE);
  1193. }
  1194. #endif /* HAS_COOLTYPE_UFL */
  1195. static void PutStemSnapBugFix(XCF_Handle h, Fixed arg1, Fixed numbers[], IntX count)
  1196. {
  1197. Fixed arg2 = 0;
  1198. IntX i;
  1199. for (i=0; i < count; ++i)
  1200. arg2 += numbers[i];
  1201. PutString(h, XCF_NEW_LINE " systemdict /internaldict known" XCF_NEW_LINE "{1183615869 systemdict /internaldict get exec" XCF_NEW_LINE "/StemSnapLength 2 copy known {get ");
  1202. PutLongNumber(h, count);
  1203. PutString(h, " lt} {pop pop true} ifelse}" XCF_NEW_LINE "{true} ifelse {pop [");
  1204. PutNumber(h, arg1, false);
  1205. PutString(h, " ");
  1206. PutNumber(h, arg2, false);
  1207. PutString(h, "]} if def" XCF_NEW_LINE);
  1208. }
  1209. static void WriteStemSnap(XCF_Handle h, boolean instance)
  1210. {
  1211. WriteBlendArrayLine(h, "StdHW", h->dict.stdHW, h->dict.stdHWCount, instance,
  1212. true, true, false);
  1213. WriteBlendArrayLine(h, "StdVW", h->dict.stdVW, h->dict.stdVWCount, instance,
  1214. true, true, false);
  1215. if (h->dict.stemSnapHCount)
  1216. {
  1217. PutString(h, "/StemSnapH [ ");
  1218. PutBlendArray(h, h->dict.stemSnapH, h->dict.stemSnapHCount, instance, true,
  1219. true, false);
  1220. PutString(h, "] ");
  1221. if ((h->dict.stemSnapHCount > 2) && (!h->dict.numberOfMasters))/* xxx fix stem snap bug fix to work for MM */
  1222. PutStemSnapBugFix(h, h->dict.stdHW[0], h->dict.stemSnapH, h->dict.stemSnapHCount);
  1223. else
  1224. PutString(h, "def" XCF_NEW_LINE);
  1225. }
  1226. if (h->dict.stemSnapVCount)
  1227. {
  1228. PutString(h, "/StemSnapV [ ");
  1229. PutBlendArray(h, h->dict.stemSnapV, h->dict.stemSnapVCount, instance, true,
  1230. true, false);
  1231. PutString(h, "] ");
  1232. if ((h->dict.stemSnapVCount > 2) && (!h->dict.numberOfMasters))/* xxx fix stem snap bug fix to work for MM */
  1233. PutStemSnapBugFix(h, h->dict.stdVW[0], h->dict.stemSnapV, h->dict.stemSnapVCount);
  1234. else
  1235. PutString(h, "def" XCF_NEW_LINE);
  1236. }
  1237. }
  1238. #define FIXEDEIGHT 0x00080000L
  1239. static void WriteErode(XCF_Handle h, boolean instance) /* xxx fix to use instance */
  1240. {
  1241. IntX i;
  1242. Fixed value = 0;
  1243. Fixed previousValues[MAX_RASTERIZER_STACK_SIZE] = {0};
  1244. Fixed blend = 0;
  1245. Fixed blendedStdVW = Blend(h, h->dict.stdVW, h->dict.stdVWCount, true,
  1246. &previousValues[0],
  1247. sizeof(previousValues)/sizeof(Fixed), false);
  1248. if ((h->dict.stdVWCount) && (h->dict.stdVW[0] != 0))
  1249. {
  1250. PutString(h,"/Erode{" XCF_NEW_LINE);
  1251. if (!h->dict.numberOfMasters)
  1252. PutNumber(h, XCF_FixDiv(h->dict.stdVW[0],FIXEDEIGHT), false); /* trunc(stdvw/8) + 0.5 */
  1253. else if (instance)
  1254. {
  1255. for (i = 0; i < h->dict.stdVWCount; ++i)
  1256. {
  1257. value = h->dict.stdVW[i];
  1258. blend += XCF_FixMul(XCF_FixDiv(value, FIXEDEIGHT), h->dict.weightVector[i]);
  1259. }
  1260. PutNumber(h, blend, false);
  1261. PutString(h, " ");
  1262. }
  1263. else
  1264. {
  1265. PutString(h, "{ ");
  1266. for (i = 0; i < h->dict.stdVWCount; ++i)
  1267. {
  1268. value = h->dict.stdVW[i];
  1269. PutNumber(h, XCF_FixDiv(value, FIXEDEIGHT), false); /* trunc(stdvw/8) + 0.5 */
  1270. PutString(h, " ");
  1271. }
  1272. PutString(h, "}");
  1273. }
  1274. PutString(h," dup 3 -1 roll 0.1 mul exch 0.5 sub mul cvi sub dup mul" XCF_NEW_LINE);
  1275. if ((instance) || (!h->dict.numberOfMasters))
  1276. PutNumber(h, blendedStdVW, false);
  1277. else
  1278. {
  1279. PutString(h, "{ ");
  1280. PutNumberList(h, h->dict.stdVW, h->dict.stdVWCount, false, 0, false);
  1281. PutString(h, "}");
  1282. }
  1283. /* PutNumber(h,h->dict.stdVW[0]); */
  1284. PutString(h," 0 dtransform dup mul exch dup mul add" XCF_NEW_LINE "le{pop pop 1.0 1.0}{pop pop 0.0 1.5}ifelse}def" XCF_NEW_LINE);
  1285. }
  1286. }
  1287. static void WritePrivateBlendDict(XCF_Handle h)
  1288. {
  1289. if (h->dict.numberOfMasters == 0)
  1290. return;
  1291. PutString(h, "3 index /Blend get /Private get begin" XCF_NEW_LINE );
  1292. WriteBlendArrayLine(h, "BlueValues", h->dict.blueValues,
  1293. h->dict.blueValuesCount, false, true, true, false);
  1294. WriteBlendArrayLine(h, "OtherBlues", h->dict.otherBlues,
  1295. h->dict.otherBluesCount, false, true, true, false);
  1296. WriteBlendLine(h, "BlueScale", h->dict.blueScale, h->dict.blueScaleCount,
  1297. false, true, true, true);
  1298. WriteBlendLine(h, "BlueShift", h->dict.blueShift, h->dict.blueShiftCount,
  1299. false, true, true, false);
  1300. WriteBlendArrayLine(h, "FamilyBlues", h->dict.familyBlues,
  1301. h->dict.familyBluesCount, false, true, true, false);
  1302. WriteBlendArrayLine(h, "FamilyOtherBlues", h->dict.familyOtherBlues,
  1303. h->dict.familyOtherBluesCount, false, true, true, false);
  1304. WriteBlendBooleanLine(h, "ForceBold", h->dict.forceBold, h->dict.forceBoldCount, false, h->dict.forceBoldThreshold);
  1305. WriteStemSnap(h, false);
  1306. WriteErode(h, false);
  1307. PutString(h, "end" XCF_NEW_LINE );
  1308. }
  1309. /*
  1310. 3 index /Blend get /Private get begin
  1311. /BlueValues[[ -18 -25][ 0 0][ 528 532][ 553 557][ 430 432][ 450 457][ 520 516][ 521 524][ 563 588][ 588 607][ 605 627][ 612 638]] def
  1312. /OtherBlues[[ 252 263][ 259 268][ -144 -168][ -121 -143][ -85 -114][ -68 -105]] def
  1313. /FamilyBlues[[ -18 -18][ 0 0][ 528 528][ 553 553][ 430 430][ 450 450][ 520 520][ 521 521][ 563 563][ 588 588][ 605 605][ 612 612]] def
  1314. /FamilyOtherBlues[[ 252 252][ 259 259][ -144 -144][ -121 -121][ -85 -85][ -68 -68]] def
  1315. /ForceBold [ false true] def
  1316. /StdHW [[25 60 ]] def
  1317. /StdVW [[45 140 ]] def
  1318. /Erode{
  1319. {5.5 17.5 } dup 3 -1 roll 0.1 mul exch 0.5 sub mul cvi sub dup mul
  1320. {45 140 } 0 dtransform dup mul exch dup mul add
  1321. le{pop pop 1.0 1.0}{pop pop 0.0 1.5}ifelse}def
  1322. end
  1323. /Erode{
  1324. 8.166522 dup 3 -1 roll 0.1 mul exch 0.5 sub mul cvi sub dup mul
  1325. 66.11 0 dtransform dup mul exch dup mul add
  1326. le{pop pop 1.0 1.0}{pop pop 0.0 1.5}ifelse}def
  1327. */
  1328. static void WriteFontDict(XCF_Handle h)
  1329. {
  1330. char line[MAX_LINE_LENGTH];
  1331. /* Note: for ATM compatibility
  1332. * for mm fonts the BlendDict must come after the BlendDesignPositions,
  1333. * BlendDesignMap, and BlendAxisTypes definitions.
  1334. */
  1335. PutString(h, "%!FontType1" XCF_NEW_LINE);
  1336. /**** Start Font & FontInfo Dicts ****/
  1337. h->callbacks.xcfSprintf(line, CCHOF(line), "%ld dict begin" XCF_NEW_LINE "/FontInfo %ld dict dup begin" XCF_NEW_LINE, (Card32) FontDictCount(h), (Card32) FontInfoDictCount(h));
  1338. PutString(h,line);
  1339. /**** Write Info Dict ****/
  1340. WriteSIDLine(h, "Notice", h->dict.notice, h->dict.noticeCount);
  1341. WriteSIDLine(h, "Copyright", h->dict.copyright, h->dict.copyrightCount);
  1342. WriteSIDLine(h, "version", h->dict.version, h->dict.versionCount);
  1343. WriteSIDLine(h, "FullName", h->dict.fullName, h->dict.fullNameCount);
  1344. WriteSIDLine(h, "FamilyName", h->dict.familyName, h->dict.familyNameCount);
  1345. WriteSIDLine(h, "BaseFontName", h->dict.baseFontName, h->dict.baseFontNameCount);
  1346. WriteNumberListLine(h, "BaseFontBlend", h->dict.baseFontBlend,
  1347. h->dict.baseFontBlendCount, false);
  1348. WriteSIDLine(h, "Weight", h->dict.weight, h->dict.weightCount);
  1349. WriteBlendLine(h, "ItalicAngle", h->dict.italicAngle,
  1350. h->dict.italicAngleCount, true, true, true, false);
  1351. WriteBlendBooleanLine(h, "isFixedPitch", h->dict.isFixedPitch, h->dict.isFixedPitchCount, true, FIXEDHALF); /* xxx What do we use for threshold? */
  1352. WriteBlendLine(h, "UnderlinePosition", h->dict.underlinePosition,
  1353. h->dict.underlinePositionCount, true, true, true, false);
  1354. WriteBlendLine(h, "UnderlineThickness", h->dict.underlineThickness,
  1355. h->dict.underlineThicknessCount, true, true, true, false);
  1356. if (h->callbacks.getFSType)
  1357. {
  1358. long fsType;
  1359. h->callbacks.getFSType(h, &fsType, h->callbacks.getFSTypeHook);
  1360. if (fsType != -1)
  1361. WriteLongNumberLine(h, "FSType", fsType, 1);
  1362. }
  1363. if (h->dict.numberOfMasters != 0)
  1364. {
  1365. #if HAS_COOLTYPE_UFL == 1
  1366. if (h->callbacks.getDesignPositions)
  1367. {
  1368. char *bdp;
  1369. h->callbacks.getDesignPositions(h, &bdp, h->callbacks.getDesignPositionsHook);
  1370. if (bdp[0] != 0)
  1371. {
  1372. h->callbacks.xcfSprintf(line, CCHOF(line), "/BlendDesignPositions %s def" XCF_NEW_LINE, bdp);
  1373. PutString(h, line);
  1374. }
  1375. }
  1376. if (h->callbacks.getDesignMap)
  1377. {
  1378. char *bdm;
  1379. h->callbacks.getDesignMap(h, &bdm, h->callbacks.getDesignMapHook);
  1380. if (bdm[0] != 0)
  1381. {
  1382. h->callbacks.xcfSprintf(line, CCHOF(line), "/BlendDesignMap %s def" XCF_NEW_LINE, bdm);
  1383. PutString(h, line);
  1384. }
  1385. }
  1386. #endif
  1387. WriteBlendAxisTypes(h);
  1388. }
  1389. PutString(h,"end" T1_READONLY " def" XCF_NEW_LINE); /* end of FontInfo dict*/
  1390. /**** Write Font Dict ****/
  1391. PutString(h, "/FontName /");
  1392. PutFontName(h);
  1393. PutString(h, " def" XCF_NEW_LINE);
  1394. if (!StreamKeyPointData(h, XCF_ENCODING))
  1395. WriteEncodingArray(h);
  1396. WriteNumberLine(h, "PaintType", h->dict.paintType, h->dict.paintTypeCount, false);
  1397. WriteLongNumberLine(h, "FontType", h->options.outputCharstrType, 1);
  1398. WriteNumberListLine(h, "DesignVector", h->dict.userDesignVector,
  1399. h->dict.userDesignVectorCount, false);
  1400. WriteNumberListLine(h, "NormDesignVector", h->dict.normDesignVector,
  1401. h->dict.normDesignVectorCount, false);
  1402. WriteNumberListLine(h, "WeightVector", h->dict.weightVector,
  1403. h->dict.numberOfMasters, false);
  1404. WriteBlendProc(h);
  1405. WriteFontMatrix(h, "FontMatrix", h->dict.fontMatrix, h->dict.fontMatrixCount);
  1406. WriteBlendArrayLine(h, "FontBBox", h->dict.fontBBox,
  1407. h->dict.fontBBoxCount, true, false, false, false);
  1408. #if HAS_COOLTYPE_UFL == 1
  1409. if (h->dict.numberOfMasters != 0)
  1410. {
  1411. WriteBlendDict(h);
  1412. WriteMakeBlendedFontOp(h);
  1413. WriteInterpCharString(h);
  1414. WriteDesignVectorProcs(h);
  1415. WriteMMFindFontDef(h);
  1416. }
  1417. #endif
  1418. if (!StreamKeyPointData(h, XCF_UID))
  1419. WriteLongNumberLine(h, "UniqueID", h->dict.uniqueID,
  1420. h->dict.uniqueIDCount);
  1421. if (h->dict.xUIDCount > 0)
  1422. WriteLongNumberListLine(h, "XUID", h->dict.xUID, h->dict.xUIDCount);
  1423. WriteBlendLine(h, "StrokeWidth", h->dict.strokeWidth,
  1424. h->dict.strokeWidthCount, true, true, true, false);
  1425. PutString(h, "currentdict end" XCF_NEW_LINE);
  1426. }
  1427. static void GetSubr(XCF_Handle h,
  1428. CardX index,
  1429. boolean unprocessed,
  1430. Card8 PTR_PREFIX * PTR_PREFIX *ppSubr,
  1431. Card16 PTR_PREFIX *pSubrLength)
  1432. {
  1433. Offset subrOffset, nextSubrOffset;
  1434. if (unprocessed)
  1435. {
  1436. XCF_LookUpTableEntry(h, &h->dict.localSubrs, index);
  1437. *pSubrLength = (Card16) h->inBuffer.blockLength;
  1438. *ppSubr = h->inBuffer.start;
  1439. }
  1440. else
  1441. {
  1442. subrOffset = *da_INDEX(h->type1.subrOffsets, index);
  1443. nextSubrOffset = *da_INDEX(h->type1.subrOffsets, index+1);
  1444. *pSubrLength = (Card16)(nextSubrOffset - subrOffset);
  1445. *ppSubr = da_INDEX(h->type1.subrs, subrOffset);
  1446. }
  1447. }
  1448. void XT1_CIDWriteSubrs(XCF_Handle h, Card16 fdIndex)
  1449. {
  1450. CardX i;
  1451. Card8 PTR_PREFIX *pSubr;
  1452. Card16 subrLength;
  1453. Card32 numberOfSubrs;
  1454. h->dict.localSubrs = h->type1.cid.localSubrs[fdIndex];
  1455. h->dict.localSubrBias = h->type1.cid.localSubrBias[fdIndex];
  1456. numberOfSubrs = h->options.outputCharstrType == 2 ?
  1457. h->dict.localSubrs.count : h->type1.subrOffsets.cnt - 1;
  1458. for (i=0 ; i < numberOfSubrs ; ++i)
  1459. {
  1460. GetSubr(h, i, h->options.outputCharstrType == 2, &pSubr, &subrLength);
  1461. PutType1CharString(h, pSubr, subrLength);
  1462. }
  1463. }
  1464. void XT1_CIDWriteSubrMap(XCF_Handle h, Card16 fdIndex)
  1465. {
  1466. CardX i;
  1467. Offset subrOffset = 0;
  1468. Card16 lenIVextraBytes = (h->options.lenIV == -1) ? 0 : h->options.lenIV;
  1469. Card32 accum = h->type1.cid.subrDataStart - h->type1.cid.charMapStart;
  1470. boolean unprocessed = h->options.outputCharstrType == 2;
  1471. Card32 numberOfSubrs = unprocessed ?
  1472. h->type1.cid.localSubrs[fdIndex].count : h->type1.subrOffsets.cnt;
  1473. for (i=0 ; i < numberOfSubrs ; ++i)
  1474. {
  1475. subrOffset = unprocessed ? i : *da_INDEX(h->type1.subrOffsets, i);
  1476. PutSizedNumber(h, accum + subrOffset, 4); /* xxx will change if SDBytes is not 4! */
  1477. accum += lenIVextraBytes;
  1478. }
  1479. }
  1480. static void GetCIDCharString(XCF_Handle h, Card8 PTR_PREFIX *PTR_PREFIX
  1481. *ppCharStr, Card16 PTR_PREFIX *charStrLength)
  1482. {
  1483. if ((h->options.outputCharstrType != 2) && (h->dict.fontType != 1))
  1484. {
  1485. *ppCharStr = h->type1.charStrs.array;
  1486. *charStrLength = (Card16) h->type1.charStrs.cnt;
  1487. }
  1488. else
  1489. {
  1490. XCF_LookUpTableEntry(h, &h->fontSet.charStrings, (Card16)h->type1.charStrs.cnt);
  1491. *charStrLength = (Card16) h->inBuffer.blockLength;
  1492. *ppCharStr = h->inBuffer.start;
  1493. }
  1494. }
  1495. void XT1_CIDWriteCharString(XCF_Handle h)
  1496. {
  1497. Card8 PTR_PREFIX *pCharStr;
  1498. Card16 charStrLength;
  1499. GetCIDCharString(h, &pCharStr, &charStrLength);
  1500. h->type1.cid.charDataCount += PutType1CharString(h, pCharStr, charStrLength);
  1501. *da_NEXT(h->type1.charStrOffsets) = h->type1.cid.charDataCount;
  1502. }
  1503. static void WriteDVSubr(XCF_Handle h, Card32 subrNum, StringID sid, Card16 lenIVextraBytes)
  1504. {
  1505. char PTR_PREFIX *pSubr;
  1506. Card16 length;
  1507. char str[50];
  1508. XCF_LookUpString(h, sid, &pSubr, &length);
  1509. h->callbacks.xcfSprintf(str, CCHOF(str), "dup %ld %lu -| ", (long int)subrNum,
  1510. (long unsigned int) (length + lenIVextraBytes));
  1511. PutString(h, str);
  1512. PutType1CharString(h, (Card8 PTR_PREFIX *)pSubr, length);
  1513. PutString(h," |" XCF_NEW_LINE);
  1514. }
  1515. static void WriteSubrs(XCF_Handle h, boolean unprocessed)
  1516. {
  1517. CardX i;
  1518. char str[50];
  1519. Card8 PTR_PREFIX *pSubr;
  1520. Card16 subrLength;
  1521. Card16 lenIVextraBytes;
  1522. Card32 numberOfSubrs;
  1523. if (unprocessed)
  1524. numberOfSubrs = h->dict.localSubrs.count;
  1525. else
  1526. numberOfSubrs = h->type1.subrOffsets.cnt - 1;
  1527. if ((numberOfSubrs == 0) && !(h->dict.numberOfMasters && unprocessed))
  1528. return;
  1529. h->callbacks.xcfSprintf(str, CCHOF(str), "/Subrs %u array" XCF_NEW_LINE,
  1530. /* Add 2 for NDV, CDV */
  1531. numberOfSubrs + ((unprocessed && (h->dict.numberOfMasters > 0)) ? 2 : 0));
  1532. PutString(h,str);
  1533. lenIVextraBytes = (h->options.lenIV == -1) ? 0 : h->options.lenIV;
  1534. for (i=0;i<numberOfSubrs;++i)
  1535. {
  1536. GetSubr(h, i, unprocessed, &pSubr, &subrLength);
  1537. h->callbacks.xcfSprintf(str, CCHOF(str), "dup %ld %lu -| ",(long int)i,(long unsigned int) (subrLength+lenIVextraBytes));
  1538. PutString(h, str);
  1539. PutType1CharString(h, pSubr, subrLength);
  1540. PutString(h," |" XCF_NEW_LINE);
  1541. }
  1542. if (unprocessed && (h->dict.numberOfMasters > 0))
  1543. {
  1544. WriteDVSubr(h, numberOfSubrs, h->dict.ndv, lenIVextraBytes);
  1545. WriteDVSubr(h, numberOfSubrs + 1, h->dict.cdv, lenIVextraBytes);
  1546. }
  1547. PutString(h,"|-" XCF_NEW_LINE);
  1548. }
  1549. static void GetCharstring(XCF_Handle h,
  1550. CardX index,
  1551. boolean unprocessed,
  1552. Card8 PTR_PREFIX * PTR_PREFIX *ppCharStr,
  1553. Card16 PTR_PREFIX *pCharStrLength)
  1554. {
  1555. Offset charStrOffset, nextCharStrOffset;
  1556. if (h->options.subrFlatten && !unprocessed)
  1557. /* Need to process the charstring first since we always re-use data
  1558. space in the DA charstring */
  1559. ProcessOneCharString(h, index);
  1560. else
  1561. /* We already processed all the charstrings, but we still need to
  1562. check for seac characters. */
  1563. CheckSeacCharString(h, index);
  1564. if (unprocessed)
  1565. {
  1566. XCF_LookUpTableEntry(h, &h->fontSet.charStrings, index);
  1567. *pCharStrLength = (Card16) h->inBuffer.blockLength;
  1568. *ppCharStr = h->inBuffer.start;
  1569. }
  1570. else
  1571. {
  1572. charStrOffset = *da_INDEX(h->type1.charStrOffsets,
  1573. h->options.subrFlatten ? 0 : index);
  1574. if (!h->options.subrFlatten)
  1575. {
  1576. nextCharStrOffset = *da_INDEX(h->type1.charStrOffsets, index+1);
  1577. *pCharStrLength = (Card16)(nextCharStrOffset - charStrOffset);
  1578. }
  1579. else
  1580. *pCharStrLength = (Card16)h->type1.charStrs.cnt;
  1581. *ppCharStr = da_INDEX(h->type1.charStrs, charStrOffset);
  1582. }
  1583. }
  1584. static Card32 GetSeacGlyphID(XCF_Handle h, CardX index)
  1585. {
  1586. char PTR_PREFIX *stdName;
  1587. char PTR_PREFIX *str;
  1588. Card16 len;
  1589. Card32 i;
  1590. Card32 id = (Card32)-1;
  1591. /* Get the correct glyph id for a seac character. Seac character index
  1592. always uses standard encoding
  1593. */
  1594. if (h->dict.charset == cff_ISOAdobeCharset)
  1595. {
  1596. id = GetStdEncodeSID(index);
  1597. }
  1598. else if (index)
  1599. {
  1600. stdName = GetStdEncodingName(index);
  1601. if (index < h->fontSet.charStrings.count)
  1602. { /* See if the glyph name matches the one in Standard encoding */
  1603. XCF_LookUpString(h, h->type1.pCharset[index-1], &str, &len);
  1604. if (len)
  1605. {
  1606. if (!h->callbacks.strcmp(stdName, str))
  1607. id = h->type1.pCharset[index - 1];
  1608. }
  1609. }
  1610. if (id == (Card32)-1)
  1611. {
  1612. /* Search for the glyphID. Worse case is we have to search the
  1613. entire charset. We may want to sort the character list to
  1614. improve the searching performance. */
  1615. for (i = 0; i < h->type1.charsetSize; i++)
  1616. {
  1617. XCF_LookUpString(h, h->type1.pCharset[i], &str, &len);
  1618. if (len)
  1619. {
  1620. if (!h->callbacks.strcmp(stdName, str))
  1621. {
  1622. id = i+1;
  1623. break;
  1624. }
  1625. }
  1626. }
  1627. }
  1628. }
  1629. return id;
  1630. }
  1631. static unsigned short GetSeacCharacters(XCF_Handle h,
  1632. XCFGlyphID PTR_PREFIX *seacID)
  1633. {
  1634. Card32 gid;
  1635. unsigned short cSeacGlyphs;
  1636. cSeacGlyphs = 0;
  1637. if (h->cstr.baseSeac != 0)
  1638. {
  1639. gid = GetSeacGlyphID(h, h->cstr.baseSeac);
  1640. if (gid != -1)
  1641. seacID[cSeacGlyphs++] = (unsigned short)gid;
  1642. }
  1643. if (h->cstr.accentSeac != 0)
  1644. {
  1645. gid = GetSeacGlyphID(h, h->cstr.accentSeac);
  1646. if (gid != -1)
  1647. seacID[cSeacGlyphs++] = (unsigned short)gid;
  1648. }
  1649. return cSeacGlyphs;
  1650. }
  1651. static void WriteCharstringDict(XCF_Handle h)
  1652. {
  1653. char str[50];
  1654. Card32 numberOfCharString;
  1655. numberOfCharString = h->fontSet.charStrings.count;
  1656. h->callbacks.xcfSprintf(str, CCHOF(str), "2 index /CharStrings %lu dict dup begin" XCF_NEW_LINE, (long unsigned int) numberOfCharString);
  1657. PutString(h, str);
  1658. }
  1659. static void WriteCharstrings(XCF_Handle h, boolean flSeac,
  1660. short cGlyphs, XCFGlyphID PTR_PREFIX *pGlyphID,
  1661. unsigned char PTR_PREFIX **pGlyphName,
  1662. unsigned long PTR_PREFIX *pCharStrLength)
  1663. {
  1664. IntX i;
  1665. char str[50];
  1666. Card8 PTR_PREFIX *pCharStr;
  1667. Card16 charStrLength;
  1668. boolean flDownload;
  1669. boolean unprocessed;
  1670. boolean flCompleteFont = 0;
  1671. short glyphID;
  1672. Card16 lenIVextraBytes;
  1673. short totalGlyphs = cGlyphs;
  1674. unprocessed = (h->options.outputCharstrType == 2);
  1675. if (pCharStrLength && !flSeac)
  1676. *pCharStrLength = 0;
  1677. if (cGlyphs == -1)
  1678. /* Check to see if the request is to download the entire font */
  1679. {
  1680. totalGlyphs = (short)h->fontSet.charStrings.count;
  1681. flCompleteFont = 1;
  1682. }
  1683. lenIVextraBytes = (h->options.lenIV == -1) ? 0 : h->options.lenIV;
  1684. for (i=0; i < totalGlyphs; i++)
  1685. {
  1686. glyphID = (short)((flCompleteFont) ? i : *pGlyphID);
  1687. if (glyphID > (long)h->fontSet.charStrings.count)
  1688. XCF_FATAL_ERROR(h, XCF_InvalidGID, "bad Glyph ID", glyphID);
  1689. if (!flSeac)
  1690. flDownload = (!IS_GLYPH_SENT(h->dl.glyphs, glyphID));
  1691. else
  1692. {
  1693. flDownload = (h->options.dlOptions.useSpecialEncoding) ?
  1694. (!IS_GLYPH_SENT(h->dl.seacs, glyphID)) :
  1695. (!IS_GLYPH_SENT(h->dl.glyphs, glyphID));
  1696. }
  1697. if (flDownload)
  1698. {
  1699. PutString(h,"/");
  1700. PutCharacterName(h, pGlyphName ? i : glyphID, pGlyphName);
  1701. GetCharstring(h, glyphID, unprocessed, &pCharStr, &charStrLength);
  1702. h->callbacks.xcfSprintf(str, CCHOF(str), " %lu -| ", (long unsigned int)
  1703. (charStrLength+lenIVextraBytes));
  1704. PutString(h,str);
  1705. PutType1CharString(h, pCharStr, charStrLength);
  1706. PutString(h," |-" XCF_NEW_LINE);
  1707. /* Set downloaded status for this glyph */
  1708. if (!flSeac)
  1709. SET_GLYPH_SENT_STATUS(h->dl.glyphs, glyphID);
  1710. else
  1711. {
  1712. if (h->options.dlOptions.useSpecialEncoding)
  1713. SET_GLYPH_SENT_STATUS(h->dl.seacs, glyphID);
  1714. else
  1715. SET_GLYPH_SENT_STATUS(h->dl.glyphs, glyphID);
  1716. }
  1717. if (pCharStrLength)
  1718. *pCharStrLength += (unsigned long)charStrLength;
  1719. /* Take care of seac characters .*/
  1720. if (!flCompleteFont && !flSeac)
  1721. {
  1722. XCFGlyphID seacID[2];
  1723. unsigned short cSeacGlyphs;
  1724. cSeacGlyphs = GetSeacCharacters(h, (XCFGlyphID *)seacID);
  1725. if (cSeacGlyphs)
  1726. {
  1727. /* Don't pass in the client's glyphName because:
  1728. 1. We are downloading a seac's base or accent character.
  1729. 2. The client uses a special encoding array that is not
  1730. derived from Adobe Standard Encoding (G00..GFF).
  1731. We need to use the real PS character name in this case.
  1732. */
  1733. WriteCharstrings(h, 1, cSeacGlyphs, seacID, 0, pCharStrLength);
  1734. }
  1735. }
  1736. }
  1737. if (!flCompleteFont)
  1738. pGlyphID++;
  1739. }
  1740. } /* end WriteCharstrings */
  1741. /*
  1742. xxx complete
  1743. The following table shows the value types associated with various dict keys:
  1744. Key Type
  1745. --- ----
  1746. WeightVector Array
  1747. isFixedPitch Blend
  1748. * ItalicAngle Blend
  1749. * UnderlinePosition Blend
  1750. * UnderlineThickness Blend
  1751. StrokeWidth Blend
  1752. BlendDesignMap Array
  1753. BlendAxisTypes Array (of SIDs)
  1754. XUID Array
  1755. BaseFontBlend DeltaArray
  1756. * BlueValues BlendArray
  1757. * OtherBlues BlendArray
  1758. * FamilyBlues BlendArray
  1759. * FamilyOtherBlues BlendArray
  1760. * BlueScale Blend
  1761. * BlueShift Blend
  1762. * BlueFuzz Blend
  1763. * StdHW Blend
  1764. * StdVW Blend
  1765. * StemSnapH BlendArray
  1766. * StemSnapV BlendArray
  1767. */
  1768. static void WritePrivateDict(XCF_Handle h, short cGlyphs,
  1769. XCFGlyphID PTR_PREFIX *pGlyphID,
  1770. unsigned char PTR_PREFIX **pGlyphName,
  1771. unsigned long PTR_PREFIX *pCharStrLength)
  1772. {
  1773. char line[MAX_LINE_LENGTH];
  1774. boolean unprocessed = (h->options.outputCharstrType == 2);
  1775. static XCFGlyphID notdefID = 0;
  1776. /**** Start Private Dict ****/
  1777. h->callbacks.xcfSprintf(line, CCHOF(line), "dup /Private %ld dict dup begin" XCF_NEW_LINE, (Card32) PrivateDictCount(h));
  1778. PutString(h,line);
  1779. if (h->options.hexEncoding && !h->options.eexecEncryption)
  1780. PutString(h, "/-|{string currentfile exch readhexstring pop}executeonly def" XCF_NEW_LINE);
  1781. else
  1782. PutString(h, "/-|{string currentfile exch readstring pop}executeonly def" XCF_NEW_LINE);
  1783. PutString(h, "/|-{" T1_NOACCESS "def}executeonly def" XCF_NEW_LINE);
  1784. PutString(h, "/|{" T1_NOACCESS "put}executeonly def" XCF_NEW_LINE);
  1785. /**** Write Private Dict ****/
  1786. if (!StreamKeyPointData(h, XCF_UID))
  1787. /* Duplicated from Font Dict */
  1788. WriteLongNumberLine(h, "UniqueID", h->dict.uniqueID, h->dict.uniqueIDCount);
  1789. if (!h->dict.blueValuesCount) /* Write BlueValues array if not present in cff */
  1790. PutString(h, "/BlueValues [ ] |-" XCF_NEW_LINE);
  1791. WriteBlendArrayLine(h, "BlueValues", h->dict.blueValues,
  1792. h->dict.blueValuesCount, true, true, true, false);
  1793. WriteBlendArrayLine(h, "OtherBlues", h->dict.otherBlues,
  1794. h->dict.otherBluesCount, true, true, true, false);
  1795. WriteBlendArrayLine(h, "FamilyBlues", h->dict.familyBlues,
  1796. h->dict.familyBluesCount, true, true, true, false);
  1797. WriteBlendArrayLine(h, "FamilyOtherBlues", h->dict.familyOtherBlues,
  1798. h->dict.familyOtherBluesCount, true, true, true, false);
  1799. WriteStemSnap(h, true);
  1800. WriteBlendLine(h, "BlueScale", h->dict.blueScale, h->dict.blueScaleCount,
  1801. true, true, true, true);
  1802. WriteBlendLine(h, "BlueShift", h->dict.blueShift, h->dict.blueShiftCount,
  1803. true, true, true, false);
  1804. WriteBlendLine(h, "BlueFuzz", h->dict.blueFuzz, h->dict.blueFuzzCount, true,
  1805. true, true, false);
  1806. WriteBlendBooleanLine(h, "ForceBold", h->dict.forceBold, h->dict.forceBoldCount, true, h->dict.forceBoldThreshold);
  1807. WriteNumberLine(h, "ForceBoldThreshold", h->dict.forceBoldThreshold,
  1808. h->dict.forceBoldThresholdCount, false);
  1809. if ((h->dict.languageGroupCount) && (h->dict.languageGroup == 1))
  1810. PutString(h, "/RndStemUp false def" XCF_NEW_LINE);
  1811. WriteLongNumberLine(h, "LanguageGroup", h->dict.languageGroup,
  1812. h->dict.languageGroupCount);
  1813. WriteNumberLine(h, "ExpansionFactor", h->dict.expansionFactor,
  1814. h->dict.expansionFactorCount, true);
  1815. WriteNumberLine(h, "initialRandomSeed", h->dict.initialRandomSeed,
  1816. h->dict.initialRandomSeedCount, false);
  1817. if (unprocessed)
  1818. {
  1819. WriteNumberLine(h, "defaultWidthX", h->dict.defaultWidthX,
  1820. h->dict.defaultWidthXCount, false);
  1821. WriteNumberLine(h, "nominalWidthX", h->dict.nominalWidthX,
  1822. h->dict.nominalWidthXCount, false);
  1823. /* Need to account for the NDV and CDV subrs in mmfonts. */
  1824. if (h->dict.localSubrs.count > 0)
  1825. WriteLongNumberLine(h, "subroutineNumberBias", h->dict.numberOfMasters ?
  1826. XCF_CalculateSubrBias(h->dict.localSubrs.count + 2) : h->dict.localSubrBias, 1);
  1827. }
  1828. if (h->dict.fontType == 2)
  1829. WriteLongNumberLine(h, "lenIV", h->options.lenIV, 1);
  1830. else if ((h->dict.fontType == 1) && (h->options.outputCharstrType == 1))
  1831. WriteLongNumberLine(h, "lenIV", h->dict.lenIV, h->dict.lenIVCount);
  1832. if (h->dict.numberOfMasters > 0)
  1833. { /* Write out ndv, cdv and include as subroutines. */
  1834. Card32 subrNum = unprocessed ? h->dict.localSubrs.count:
  1835. h->type1.subrOffsets.cnt;
  1836. WriteLongNumberLine(h, "NDV", subrNum, 1);
  1837. WriteLongNumberLine(h, "CDV", subrNum + 1, 1);
  1838. if (h->options.outputCharstrType == 1)
  1839. XC_DVToSubr(h);
  1840. }
  1841. WriteLongNumberLine(h, "lenBuildCharArray", h->dict.lenBuildCharArray,
  1842. h->dict.lenBuildCharArrayCount);
  1843. if (h->dict.lenBuildCharArrayCount)
  1844. PutString(h, "/BuildCharArray lenBuildCharArray array def" XCF_NEW_LINE);
  1845. PutString(h, "/MinFeature {16 16} def" XCF_NEW_LINE);
  1846. PutString(h, "/password 5839 def" XCF_NEW_LINE);
  1847. WriteErode(h, true);
  1848. WritePrivateBlendDict(h);
  1849. if (h->dict.embeddedPostscriptCount)
  1850. {
  1851. PutStringID(h, (StringID)h->dict.embeddedPostscript);
  1852. PutString(h, XCF_NEW_LINE);
  1853. }
  1854. WriteOtherSubrs(h, h->cstr.flexUsed, (h->type1.subrOffsets.cnt > 5));
  1855. WriteSubrs(h, (h->options.outputCharstrType == 2));
  1856. WriteCharstringDict(h);
  1857. if (cGlyphs != -1)
  1858. /* Always download the .notdef character. */
  1859. WriteCharstrings(h, 0, 1, &notdefID, 0, pCharStrLength);
  1860. WriteCharstrings(h, 0, cGlyphs, pGlyphID, pGlyphName, pCharStrLength);
  1861. /* Flag -- Add support for
  1862. NDV
  1863. CDV
  1864. */
  1865. }
  1866. static void T1Init(XCF_Handle h)
  1867. {
  1868. h->outBuffer.eexecOn = false;
  1869. }
  1870. /* Called for each dict in the FDArray of a CIDFont. */
  1871. void XT1_WriteCIDDict(XCF_Handle h, Card16 fd, Card32 subrMapOffset, Card16 subrCount)
  1872. {
  1873. char line[MAX_LINE_LENGTH];
  1874. h->callbacks.xcfSprintf(line, CCHOF(line), "dup %d" XCF_NEW_LINE, fd);
  1875. PutLine(h,line);
  1876. PutLine(h,"%ADOBeginFontDict");
  1877. h->callbacks.xcfSprintf(line, CCHOF(line),
  1878. "%ld dict" XCF_NEW_LINE "begin",
  1879. (Card32)FontDictCount(h) /* xxx wrong number? */);
  1880. PutLine(h,line);
  1881. if (h->dict.fdFontNameCount)
  1882. {
  1883. PutString(h, "/FontName /");
  1884. PutStringID(h, (StringID)h->dict.fdFontName);
  1885. PutLine(h, " def");
  1886. }
  1887. WriteLongNumberLine(h, "FontType", h->options.outputCharstrType, 1);
  1888. WriteFontMatrix(h, "FontMatrix", h->dict.fontMatrix, h->dict.fontMatrixCount);
  1889. WriteNumberLine(h, "PaintType", h->dict.paintType, h->dict.paintTypeCount, false);
  1890. PutLine(h,XCF_NEW_LINE "%ADOBeginPrivateDict");
  1891. h->callbacks.xcfSprintf(line, CCHOF(line),
  1892. "/Private %ld dict dup" XCF_NEW_LINE "begin",
  1893. (Card32)PrivateDictCount(h) /* xxx wrong number? */);
  1894. PutLine(h,line);
  1895. PutLine(h, "/MinFeature {16 16} def");
  1896. /* xxx deal with lenIV output */
  1897. if ((h->dict.fontType == 2) && (h->options.outputCharstrType == 1))
  1898. WriteLongNumberLine(h, "lenIV", h->options.lenIV, 1);
  1899. else if ((h->dict.fontType == 2) && (h->options.outputCharstrType == 2))
  1900. WriteLongNumberLine(h, "lenIV", -1, 1);
  1901. else if ((h->dict.fontType == 1) && (h->options.outputCharstrType == 1))
  1902. WriteLongNumberLine(h, "lenIV", h->dict.lenIV, h->dict.lenIVCount);
  1903. #ifdef T13
  1904. else
  1905. XT13_WritePrivDictValues(h);
  1906. #endif
  1907. WriteLongNumberLine(h, "LanguageGroup", h->dict.languageGroup,
  1908. h->dict.languageGroupCount);
  1909. if ((h->dict.languageGroupCount) && (h->dict.languageGroup == 1))
  1910. PutString(h, "/RndStemUp false def" XCF_NEW_LINE);
  1911. if ((h->dict.fontType == 2) && (h->options.outputCharstrType == 2))
  1912. {
  1913. WriteNumberLine(h, "defaultWidthX", h->dict.defaultWidthX,
  1914. h->dict.defaultWidthXCount, false);
  1915. WriteNumberLine(h, "nominalWidthX", h->dict.nominalWidthX,
  1916. h->dict.nominalWidthXCount, false);
  1917. }
  1918. if (!h->dict.blueValuesCount) /* Write BlueValues array if not present in cff */
  1919. PutString(h, "/BlueValues [ ] def" XCF_NEW_LINE);
  1920. WriteBlendArrayLine(h, "BlueValues", h->dict.blueValues,
  1921. h->dict.blueValuesCount, true, true, true, false);
  1922. WriteBlendArrayLine(h, "OtherBlues", h->dict.otherBlues,
  1923. h->dict.otherBluesCount, true, true, true, false);
  1924. WriteBlendLine(h, "BlueScale", h->dict.blueScale, h->dict.blueScaleCount,
  1925. true, true, true, true);
  1926. WriteBlendLine(h, "BlueShift", h->dict.blueShift, h->dict.blueShiftCount,
  1927. true, true, true, false);
  1928. WriteBlendLine(h, "BlueFuzz", h->dict.blueFuzz, h->dict.blueFuzzCount, true,
  1929. true, true, false);
  1930. WriteStemSnap(h, true);
  1931. WriteCIDOtherSubrs(h);
  1932. WriteErode(h, true);
  1933. PutLine(h, XCF_NEW_LINE "/password 5839 def" XCF_NEW_LINE);
  1934. if (subrCount)
  1935. {
  1936. h->callbacks.xcfSprintf(line, CCHOF(line), "/SubrMapOffset %d def", subrMapOffset);
  1937. PutLine(h,line);
  1938. PutLine(h, "/SDBytes 4 def");
  1939. h->callbacks.xcfSprintf(line, CCHOF(line), "/SubrCount %d def", subrCount);
  1940. PutLine(h,line);
  1941. }
  1942. PutLine(h, "end def" XCF_NEW_LINE
  1943. "%ADOEndPrivateDict" XCF_NEW_LINE XCF_NEW_LINE
  1944. "currentdict" XCF_NEW_LINE
  1945. "end" XCF_NEW_LINE
  1946. "%ADOEndFontDict" XCF_NEW_LINE XCF_NEW_LINE
  1947. "put");
  1948. }
  1949. /* Write top-level dict, up to FDArray */
  1950. #define MAX_FONTNAME_LENGTH 128
  1951. void XT1_WriteCIDTop(XCF_Handle h)
  1952. {
  1953. char line[MAX_LINE_LENGTH];
  1954. char fontName[MAX_FONTNAME_LENGTH];
  1955. T1Init(h);
  1956. PutLine(h, "%!PS-Adobe-3.0 Resource-CIDFont");
  1957. PutLine(h, "%%DocumentNeededResources: ProcSet (CIDInit)");
  1958. PutLine(h, "%%IncludeResource: ProcSet (CIDInit)");
  1959. /* FontName */
  1960. if (!h->options.dlOptions.fontName)
  1961. {
  1962. Card16 length = sizeof(fontName) - 1;
  1963. XCF_LookUpTableEntry(h, &h->fontSet.fontNames, h->fontSet.fontIndex);
  1964. if ((Card16)h->inBuffer.blockLength < length)
  1965. length = (Card16)h->inBuffer.blockLength;
  1966. h->callbacks.memcpy(fontName, (Card8 PTR_PREFIX *)h->inBuffer.start, length);
  1967. fontName[length] = '\0';
  1968. }
  1969. else
  1970. {
  1971. Card16 length = h->callbacks.strlen((char PTR_PREFIX *)h->options.dlOptions.fontName);
  1972. if (length > (sizeof(fontName) - 1))
  1973. length = sizeof(fontName) - 1;
  1974. h->callbacks.memcpy(fontName, h->options.dlOptions.fontName, length);
  1975. fontName[length] = '\0';
  1976. }
  1977. h->callbacks.xcfSprintf(line, CCHOF(line), "%%%%BeginResource: CIDFont (%s)", fontName);
  1978. PutLine(h,line);
  1979. /* Title */
  1980. PutString(h, "%%Title: (");
  1981. PutStringID(h, (StringID) h->dict.fullName);
  1982. PutString(h, " ");
  1983. PutStringID(h, (StringID) h->dict.ROS[0]);
  1984. PutString(h, " ");
  1985. PutStringID(h, (StringID) h->dict.ROS[1]);
  1986. PutString(h, " ");
  1987. PutLongNumber(h, h->dict.ROS[2]);
  1988. PutLine(h, ")");
  1989. /* Version */
  1990. h->callbacks.xcfSprintf(line, CCHOF(line), "%%%%Version: %s", h->dict.cidFontVersion);
  1991. PutLine(h,line);
  1992. PutLine(h, XCF_NEW_LINE "/CIDInit /ProcSet findresource begin" XCF_NEW_LINE);
  1993. PutLine(h, "20 dict begin" XCF_NEW_LINE);
  1994. h->callbacks.xcfSprintf(line, CCHOF(line), "/CIDFontName /%s def", fontName);
  1995. PutLine(h,line);
  1996. if (h->dict.cidFontVersionCount > 0)
  1997. {
  1998. h->callbacks.xcfSprintf(line, CCHOF(line), "/CIDFontVersion %s def", h->dict.cidFontVersion);
  1999. PutLine(h,line);
  2000. }
  2001. WriteLongNumberLine(h, "CIDFontType", h->dict.cidFontType,
  2002. h->dict.cidFontTypeCount);
  2003. PutLine(h, XCF_NEW_LINE "/CIDSystemInfo 3 dict dup begin");
  2004. WriteSIDLine(h, "Registry", h->dict.ROS[0], h->dict.ROSCount);
  2005. WriteSIDLine(h, "Ordering", h->dict.ROS[1], h->dict.ROSCount);
  2006. WriteLongNumberLine(h, "Supplement", h->dict.ROS[2], h->dict.ROSCount);
  2007. PutLine(h, "end def" XCF_NEW_LINE);
  2008. WriteNumberListLine(h, "FontBBox", h->dict.fontBBox, h->dict.fontBBoxCount, false);
  2009. PutString(h, XCF_NEW_LINE);
  2010. // JJIA: fix bug 366539. Added Metrics2 for vertical printing.
  2011. PutLine(h, "/Metrics2 16 dict def" XCF_NEW_LINE);
  2012. PutLine(h, "/CDevProc {pop 4 index add} bind def" XCF_NEW_LINE);
  2013. if ( h->options.uniqueIDMethod != XCF_UNDEFINE_UID )
  2014. {
  2015. WriteLongNumberLine(h, "UIDBase", h->dict.uidBase, h->dict.uidBaseCount);
  2016. WriteLongNumberListLine(h, "XUID", h->dict.xUID, h->dict.xUIDCount);
  2017. }
  2018. PutLine(h, XCF_NEW_LINE "/FontInfo 3 dict dup begin");
  2019. WriteSIDLine(h, "Notice", h->dict.notice, h->dict.noticeCount);
  2020. WriteSIDLine(h, "FullName", h->dict.fullName, h->dict.fullNameCount);
  2021. if (h->callbacks.getFSType)
  2022. {
  2023. long fsType;
  2024. h->callbacks.getFSType(h, &fsType, h->callbacks.getFSTypeHook);
  2025. if (fsType != -1)
  2026. WriteLongNumberLine(h, "FSType", fsType, 1);
  2027. }
  2028. // GOODNAME
  2029. if (h->callbacks.isKnownROS)
  2030. {
  2031. long knownROS;
  2032. char PTR_PREFIX *R;
  2033. Card16 lenR;
  2034. char PTR_PREFIX *O;
  2035. Card16 lenO;
  2036. XCF_LookUpString(h, (StringID) h->dict.ROS[0], &R, &lenR);
  2037. XCF_LookUpString(h, (StringID) h->dict.ROS[1], &O, &lenO);
  2038. h->callbacks.isKnownROS(h, &knownROS,
  2039. R, lenR,
  2040. O, lenO,
  2041. h->dict.ROS[2],
  2042. h->callbacks.isKnownROSHook);
  2043. if (knownROS == 0)
  2044. {
  2045. PutLine(h, "/GlyphNames2Unicode 16 dict def");
  2046. PutLine(h, "/GlyphNames2HostCode 16 dict def");
  2047. }
  2048. }
  2049. PutLine(h,
  2050. "end" T1_READONLY " def" XCF_NEW_LINE XCF_NEW_LINE
  2051. "/CIDMapOffset 0 def" XCF_NEW_LINE XCF_NEW_LINE
  2052. "/GDBytes 4 def");
  2053. h->callbacks.xcfSprintf(line, CCHOF(line), "/FDBytes %s def", (h->type1.cid.fdCount > 1 ? "1" : "0"));
  2054. PutLine(h,line);
  2055. #ifdef T13
  2056. XT13_WriteSetup(h);
  2057. #endif
  2058. WriteLongNumberLine(h, "CIDCount", h->dict.cidCount, h->dict.cidCountCount);
  2059. h->type1.cid.cidCount = (Card32) h->dict.cidCount;
  2060. h->callbacks.xcfSprintf(line, CCHOF(line), XCF_NEW_LINE "/FDArray %d array", h->type1.cid.fdCount);
  2061. PutLine(h,line);
  2062. }
  2063. static Card16 CalculateTotalSubrLength(XCF_Handle h, boolean unprocessed)
  2064. {
  2065. Card16 subrLength = 0;
  2066. Card8 PTR_PREFIX *pSubr;
  2067. Card16 len;
  2068. Card16 fd;
  2069. Card16 lenIVextraBytes;
  2070. CardX i;
  2071. Card32 numberOfSubrs;
  2072. lenIVextraBytes = (h->options.lenIV == -1) ? 0 : h->options.lenIV;
  2073. for (fd = 0; fd < h->type1.cid.fdCount; fd++)
  2074. {
  2075. h->dict.localSubrs = h->type1.cid.localSubrs[fd];
  2076. h->dict.localSubrBias = h->type1.cid.localSubrBias[fd];
  2077. numberOfSubrs = unprocessed ? h->dict.localSubrs.count :
  2078. h->type1.subrOffsets.cnt - 1;
  2079. subrLength += (Card16)(lenIVextraBytes * numberOfSubrs);
  2080. for (i = 0; i < numberOfSubrs; ++i)
  2081. {
  2082. GetSubr(h, i, unprocessed, &pSubr, &len);
  2083. subrLength += len;
  2084. }
  2085. }
  2086. return subrLength;
  2087. }
  2088. /* Totals the number of local subrs in each font dictionary. */
  2089. static Card16 TotalLocalSubrCount(XCF_Handle h)
  2090. {
  2091. Card16 fd;
  2092. Card16 total = 0;
  2093. if (CIDFONT)
  2094. {
  2095. for (fd = 0; fd < h->type1.cid.fdCount; fd++)
  2096. total += (Card16)h->type1.cid.localSubrs[fd].count;
  2097. }
  2098. else
  2099. total = (Card16)h->dict.localSubrs.count;
  2100. return total;
  2101. }
  2102. /* Write the binary section for a VM resident CIDFont. In this case
  2103. the binary section only contains the SubrMap and subr data.
  2104. For now only the standard subrs are written out. */
  2105. void XT1_WriteCIDVMBinarySection(XCF_Handle h)
  2106. {
  2107. boolean unprocessed = (h->options.outputCharstrType == 2);
  2108. Card16 subrLength = CalculateTotalSubrLength(h, unprocessed);
  2109. Card16 subrMapLength;
  2110. Card16 fd;
  2111. Card32 totalLen;
  2112. char str[MAX_LINE_LENGTH];
  2113. /* The SubrMap length is the SDBytes value which currently is always 4. */
  2114. subrMapLength = (Card16)(unprocessed ? TotalLocalSubrCount(h) * 4 : ((h->type1.subrOffsets.cnt * 4) * h->type1.cid.fdCount));
  2115. totalLen = subrLength + subrMapLength;
  2116. PutString(h, "%%BeginData: ");
  2117. if (h->options.hexEncoding)
  2118. {
  2119. /* totalLen * 2 - double the data size because it's hex
  2120. 25 - to account for (Hex) ... StartData
  2121. 2 - for the > to end hex data and newline
  2122. */
  2123. h->callbacks.xcfSprintf(str, CCHOF(str), "%8ld Binary Bytes%s", (Card32)(totalLen * 2) + 25 + ((subrLength > 0) ? 2 : 0), XCF_NEW_LINE);
  2124. PutString(h, str);
  2125. h->callbacks.xcfSprintf(str, CCHOF(str), "(Hex) %8ld StartData%s", (Card32)totalLen, XCF_NEW_LINE);
  2126. PutString(h, str);
  2127. }
  2128. else /* binary */
  2129. {
  2130. /* The extra 28 bytes is to account for (Binary) ... StartData */
  2131. h->callbacks.xcfSprintf(str, CCHOF(str), "%8ld Binary Bytes", (Card32)totalLen + 28);
  2132. PutString(h, str);
  2133. PutString(h, XCF_NEW_LINE);
  2134. h->callbacks.xcfSprintf(str, CCHOF(str), "(Binary) %8ld StartData ", (Card32)totalLen);
  2135. PutString(h, str);
  2136. }
  2137. if (subrLength != 0)
  2138. {
  2139. h->type1.cid.flags |= WRITE_SUBR_FLAG;
  2140. for (fd = 0; fd < h->type1.cid.fdCount; ++fd)
  2141. XT1_CIDWriteSubrMap(h, fd);
  2142. for (fd = 0; fd < h->type1.cid.fdCount; ++fd)
  2143. XT1_CIDWriteSubrs(h, fd);
  2144. h->type1.cid.flags &= 0xFFFD; /* Reset WriteSubr flag */
  2145. }
  2146. if (h->options.hexEncoding && (subrLength > 0))
  2147. PutString(h, ">" XCF_NEW_LINE); /* indicate end of hex data */
  2148. PutString(h, "%%EndData" XCF_NEW_LINE "%%EndResource" XCF_NEW_LINE);
  2149. }
  2150. void XT1_CIDBeginBinarySection(XCF_Handle h)
  2151. {
  2152. Card16 i;
  2153. PutString(h, "%%BeginData: ");
  2154. h->type1.cid.replaceSD1 = XCF_OutputPos(h);
  2155. PutLine(h, "12345678 Binary Bytes");
  2156. if (h->options.hexEncoding)
  2157. PutString(h, "(Hex) ");
  2158. else
  2159. PutString(h, "(Binary) ");
  2160. h->type1.cid.replaceSD2 = XCF_OutputPos(h);
  2161. PutString(h, "12345678 StartData ");
  2162. h->type1.cid.charMapStart = XCF_OutputPos(h);
  2163. /* put placeholders for the charmap */
  2164. /* The +1 is for the final interval */
  2165. for (i = 0 ; i < h->type1.cid.cidCount + 1 ; ++i)
  2166. {
  2167. if (h->type1.cid.cidCount > 1)
  2168. XT1_PutT1Data(h, (Card8 *)"chars", 5); /* If GD or FDBytes changes this
  2169. can change. */
  2170. else
  2171. XT1_PutT1Data(h, (Card8 *)"char", 4);
  2172. }
  2173. h->type1.cid.subrMapStart = XCF_OutputPos(h);
  2174. /* before this was missing the offset of the start of the binary data */
  2175. h->type1.cid.subrDataStart += h->type1.cid.charMapStart;
  2176. }
  2177. void XT1_CIDEndBinarySection(XCF_Handle h)
  2178. {
  2179. char line[MAX_LINE_LENGTH];
  2180. Card32 charOffset = h->type1.cid.charDataStart - h->type1.cid.charMapStart;
  2181. XCF_SetOuputPosition(h, h->type1.cid.replaceSD1);
  2182. h->callbacks.xcfSprintf(line, CCHOF(line), "%8ld",
  2183. charOffset + h->type1.cid.charDataCount + h->type1.cid.replaceSD2 - h->type1.cid.replaceSD1);
  2184. PutString(h, line);
  2185. XCF_SetOuputPosition(h, h->type1.cid.replaceSD2);
  2186. h->callbacks.xcfSprintf(line, CCHOF(line), "%8ld", charOffset + h->type1.cid.charDataCount);
  2187. PutString(h, line);
  2188. XCF_SetOuputPosition(h, h->type1.cid.charDataEnd);
  2189. if (h->options.hexEncoding)
  2190. PutString(h, ">" XCF_NEW_LINE);
  2191. PutString(h, "%%EndData" XCF_NEW_LINE "%%EndResource" XCF_NEW_LINE);
  2192. }
  2193. void XT1_CIDWriteCharMap(XCF_Handle h)
  2194. {
  2195. Card16 i;
  2196. Card32 charOffset = h->type1.cid.charDataStart - h->type1.cid.charMapStart;
  2197. CardX interval;
  2198. StringID *charset = h->type1.pCharset;
  2199. char fdBytes = (h->type1.cid.fdCount > 1 ? 1 : 0);
  2200. XCF_SetOuputPosition(h, h->type1.cid.charMapStart);
  2201. /* Output the notdef character, which is always required. */
  2202. if (fdBytes)
  2203. PutSizedNumber(h, XCF_GetFDIndex(h, 0), 1); /* xxx will change if FDBytes changes! */
  2204. PutSizedNumber(h, charOffset, 4); /* xxx will change if GDBytes changes! */
  2205. /* Write out any empty intervals between 0 and charset[0]. */
  2206. for (i = 1; i < charset[0]; i++)
  2207. {
  2208. if (fdBytes)
  2209. PutSizedNumber(h, 255, 1);
  2210. PutSizedNumber(h, charOffset + h->type1.charStrOffsets.array[0], 4);
  2211. }
  2212. /* The charset array does not include the notdef character, but the
  2213. FDIndex array does include the notdef character. */
  2214. for (i = 0; i < h->type1.charsetSize; i++)
  2215. {
  2216. if (fdBytes)
  2217. PutSizedNumber(h, XCF_GetFDIndex(h, i+1), 1);
  2218. PutSizedNumber(h, charOffset + h->type1.charStrOffsets.array[i], 4);
  2219. if (i + 1 < h->type1.charsetSize)
  2220. for (interval = charset[i] + 1; interval < charset[i+1]; interval++)
  2221. { /* Write empty interval */
  2222. if (fdBytes)
  2223. PutSizedNumber(h, 255, 1);
  2224. PutSizedNumber(h, charOffset + h->type1.charStrOffsets.array[i+1], 4);
  2225. }
  2226. }
  2227. /* Put ending location, and fill out to end of table. */
  2228. for (interval = charset[i-1]; interval < h->type1.cid.cidCount; interval++)
  2229. {
  2230. if (fdBytes)
  2231. PutSizedNumber(h, 255, 1);
  2232. PutSizedNumber(h, charOffset + h->type1.charStrOffsets.array[i], 4);
  2233. }
  2234. }
  2235. /* Write the prolog for a CIDFont in VM when the initial font is created. */
  2236. static void WriteCIDBaseFontProlog(XCF_Handle h)
  2237. {
  2238. #if HAS_COOLTYPE_UFL == 1
  2239. /* In CoolType the GlyphDirectory procedures are stored in a dictionary,
  2240. ct_GlyphDirProcs, that is downloaded once by the client in a procset.
  2241. */
  2242. PutString(h, "ct_GlyphDirProcs begin" XCF_NEW_LINE);
  2243. #endif
  2244. PutString(h, "GlyphDirectory" XCF_NEW_LINE);
  2245. #if HAS_COOLTYPE_UFL == 1
  2246. PutString(h, "+" XCF_NEW_LINE);
  2247. #else
  2248. PutString(h, "5 dict begin/$ exch def/? $ type/dicttype eq def/|{?{def}{$ 3 1 roll put}" XCF_NEW_LINE);
  2249. PutString(h, "ifelse}bind def/!{?{end}if end}bind def/:{string currentfile exch readstring" XCF_NEW_LINE);
  2250. PutString(h, "pop}executeonly def ?{$ begin}if" XCF_NEW_LINE);
  2251. #endif
  2252. }
  2253. /* Write the prolog for a CIDFont in VM when incrementally adding glyphs. */
  2254. static void WriteGlyphDictProlog(XCF_Handle h, short cGlyphs)
  2255. {
  2256. char str[MAX_LINE_LENGTH];
  2257. #if HAS_COOLTYPE_UFL == 1
  2258. /* Put these dicts on the stack so the correct findresource call is made and
  2259. the GlyphDirectory procedures are defined. */
  2260. PutString(h, "ct_Dict begin ct_MakeOCF begin ct_GlyphDirProcs begin" XCF_NEW_LINE);
  2261. #endif
  2262. PutString(h, "/");
  2263. PutFontName(h);
  2264. h->callbacks.xcfSprintf(str, CCHOF(str), " %ld%s", (long int)cGlyphs, XCF_NEW_LINE);
  2265. PutString(h, str);
  2266. #if HAS_COOLTYPE_UFL == 1
  2267. PutString(h, "GetGlyphDirectory" XCF_NEW_LINE);
  2268. #else
  2269. PutString(h, "systemdict/languagelevel known not{1 index/CIDFont findresource/GlyphDirectory" XCF_NEW_LINE);
  2270. PutString(h, "get dup type/dicttype eq{dup dup maxlength exch length sub 2 index lt{dup" XCF_NEW_LINE);
  2271. PutString(h, "length 2 index add dict copy 2 index/CIDFont findresource/GlyphDirectory 2" XCF_NEW_LINE);
  2272. PutString(h, "index put}if}if exch pop exch pop}{pop/CIDFont findresource/GlyphDirectory get" XCF_NEW_LINE);
  2273. PutString(h, "}ifelse 5 dict begin/$ exch def/? $ type/dicttype eq def/|{?{def}{$ 3 1 roll" XCF_NEW_LINE);
  2274. PutString(h, "put}ifelse}bind def/!{?{end}if end}bind def/:{string currentfile exch" XCF_NEW_LINE);
  2275. PutString(h, "readstring pop}executeonly def ?{$ begin}if" XCF_NEW_LINE);
  2276. #endif
  2277. }
  2278. static void WriteOneGlyphDictEntry(XCF_Handle h, XCFGlyphID glyphID, unsigned
  2279. long PTR_PREFIX *pCharStrLength)
  2280. {
  2281. char line[MAX_LINE_LENGTH];
  2282. Card8 fd = 0;
  2283. Card16 charStrLength = 0;
  2284. Card8 PTR_PREFIX *pCharStr;
  2285. Card16 fdIndexLen = (h->type1.cid.fdCount > 1) ? 1 : 0;
  2286. Card16 id;
  2287. Card16 lenIVextraBytes = (h->options.lenIV == -1) ? 0 : h->options.lenIV;
  2288. if (h->callbacks.getCharStr == 0)
  2289. {
  2290. if (h->options.outputCharstrType != 2)
  2291. ProcessOneCharString(h, (unsigned int)glyphID);
  2292. else
  2293. /* So GetCIDCharString gets the string from the charstr table. */
  2294. h->type1.charStrs.cnt = glyphID;
  2295. GetCIDCharString(h, &pCharStr, &charStrLength);
  2296. id = glyphID ? h->type1.pCharset[glyphID-1] : 0;
  2297. }
  2298. else
  2299. {
  2300. h->callbacks.getCharStr((XFhandle)h, glyphID, &pCharStr, &charStrLength,
  2301. &fd, h->callbacks.getCharStrHook);
  2302. id = (Card16) glyphID; /* In this case glyphID == cid. */
  2303. }
  2304. if (h->options.hexEncoding)
  2305. h->callbacks.xcfSprintf(line, CCHOF(line), "%d <", id);
  2306. else
  2307. /* If FDBytes is variable then the amt to add to charStrLength changes. */
  2308. h->callbacks.xcfSprintf(line, CCHOF(line), "%d %d : ", id, (charStrLength + fdIndexLen + lenIVextraBytes));
  2309. XCF_PutData(h, (Card8 PTR_PREFIX *)line, h->callbacks.strlen(line));
  2310. /* If there is more than one value in the FDArray then the first
  2311. byte in the charstring must be the FD index. */
  2312. if (h->type1.cid.fdCount > 1)
  2313. {
  2314. /* According to the spec the index byte must not be encrypted. */
  2315. if (h->callbacks.getCharStr == 0)
  2316. fd = XCF_GetFDIndex(h, glyphID);
  2317. if (h->options.hexEncoding)
  2318. h->callbacks.xcfSprintf(line, CCHOF(line), "%02X", (int)fd);
  2319. else
  2320. h->callbacks.xcfSprintf(line, CCHOF(line), "%c", fd);
  2321. XCF_PutData(h, (Card8 PTR_PREFIX *)line, h->callbacks.strlen(line));
  2322. }
  2323. PutType1CharString(h, pCharStr, charStrLength);
  2324. if (h->options.hexEncoding)
  2325. PutString(h, ">");
  2326. PutString(h, " |" XCF_NEW_LINE);
  2327. SET_GLYPH_SENT_STATUS(h->dl.glyphs, glyphID);
  2328. if (pCharStrLength)
  2329. *pCharStrLength += (unsigned long)charStrLength;
  2330. }
  2331. /* Creates the GlyphDirectory dictionary for VM resident CIDFonts.
  2332. Hex and binary encoding is supported. The client is responsible
  2333. for knowing whether the download channel supports binary data. */
  2334. void XT1_WriteGlyphDictEntries(XCF_Handle h, short cGlyphs,
  2335. XCFGlyphID PTR_PREFIX *pGlyphID,
  2336. unsigned long PTR_PREFIX *pCharStrLength)
  2337. {
  2338. IntX i;
  2339. char line[MAX_LINE_LENGTH];
  2340. short totalGlyphs;
  2341. long glyphID;
  2342. boolean dlEntireFont = cGlyphs == -1 ? 1 : 0;
  2343. if (pCharStrLength)
  2344. *pCharStrLength = 0;
  2345. totalGlyphs = dlEntireFont ? h->fontSet.charStrings.count : cGlyphs;
  2346. if (h->dl.state == XCF_DL_INIT)
  2347. {
  2348. /* Add one to the total to make sure the .notdef character is included. */
  2349. h->callbacks.xcfSprintf(line, CCHOF(line), "/GlyphDirectory %d dict def", dlEntireFont ?
  2350. totalGlyphs : totalGlyphs + 1);
  2351. PutLine(h, line);
  2352. WriteCIDBaseFontProlog(h);
  2353. /* Ensure the .notdef character is included. */
  2354. if (!dlEntireFont)
  2355. WriteOneGlyphDictEntry(h, 0, pCharStrLength);
  2356. }
  2357. for (i = 0; i < totalGlyphs; i++)
  2358. {
  2359. glyphID = dlEntireFont ? i : *pGlyphID;
  2360. if (glyphID > (long)h->fontSet.charStrings.count)
  2361. XCF_FATAL_ERROR(h, XCF_InvalidGID, "bad Glyph ID", glyphID);
  2362. if (!IS_GLYPH_SENT(h->dl.glyphs, glyphID))
  2363. WriteOneGlyphDictEntry(h, glyphID, pCharStrLength);
  2364. if (!dlEntireFont)
  2365. pGlyphID++;
  2366. }
  2367. PutString(h, "!" XCF_NEW_LINE); /* ! is the name of the cleanup proc. */
  2368. #if HAS_COOLTYPE_UFL == 1
  2369. if (h->dl.state != XCF_DL_INIT)
  2370. PutString(h, "end end end" XCF_NEW_LINE); /* end for ct_Dict, ct_MakeOCF, ct_GlyphDirProcs */
  2371. else
  2372. PutString(h, "end" XCF_NEW_LINE); /* end for ct_GlyphDirProcs */
  2373. #endif
  2374. }
  2375. void XT1_WriteAdditionalGlyphDictEntries(XCF_Handle h,
  2376. short cGlyphs, XCFGlyphID PTR_PREFIX *pGlyphID,
  2377. unsigned long PTR_PREFIX *pCharStrLength)
  2378. {
  2379. WriteGlyphDictProlog(h, cGlyphs);
  2380. XT1_WriteGlyphDictEntries(h, cGlyphs, pGlyphID, pCharStrLength);
  2381. }
  2382. void XT1_WriteT1Font(XCF_Handle h)
  2383. {
  2384. IntX i;
  2385. T1Init(h);
  2386. WriteFontDict(h);
  2387. if (h->options.eexecEncryption)
  2388. StartEexec(h);
  2389. WritePrivateDict(h, -1, 0, 0, 0);
  2390. PutString(h, "end" XCF_NEW_LINE "end" XCF_NEW_LINE T1_READONLY "put" XCF_NEW_LINE T1_NOACCESS "put" XCF_NEW_LINE "dup/FontName get exch definefont pop" XCF_NEW_LINE);
  2391. if (h->options.eexecEncryption)
  2392. {
  2393. PutString(h, "mark currentfile closefile\n"); /* must be terminated with line feed (\n) only */
  2394. StopEexec(h);
  2395. PutString(h, XCF_NEW_LINE);
  2396. for (i=1;i<=8;++i)
  2397. PutString(h, "0000000000000000000000000000000000000000000000000000000000000000" XCF_NEW_LINE);
  2398. PutString(h,"cleartomark" XCF_NEW_LINE);
  2399. }
  2400. }
  2401. void XT1_WriteFontSubset(XCF_Handle h, short cGlyphs,
  2402. XCFGlyphID PTR_PREFIX *pGlyphID,
  2403. unsigned char PTR_PREFIX **pGlyphName,
  2404. unsigned long PTR_PREFIX *pCharStrLength)
  2405. {
  2406. IntX i;
  2407. T1Init(h);
  2408. WriteFontDict(h);
  2409. if (h->options.eexecEncryption)
  2410. StartEexec(h);
  2411. else
  2412. PutString(h, "systemdict begin" XCF_NEW_LINE);
  2413. WritePrivateDict(h, cGlyphs, pGlyphID, pGlyphName, pCharStrLength);
  2414. PutString(h, "end" XCF_NEW_LINE "end" XCF_NEW_LINE T1_READONLY "put" XCF_NEW_LINE T1_NOACCESS "put" XCF_NEW_LINE "dup/FontName get exch definefont pop" XCF_NEW_LINE);
  2415. if (h->options.eexecEncryption)
  2416. {
  2417. PutString(h, "mark currentfile closefile\n"); /* must be terminated with line feed only */
  2418. StopEexec(h);
  2419. PutString(h, XCF_NEW_LINE);
  2420. for (i=1;i<=8;++i)
  2421. PutString(h, "0000000000000000000000000000000000000000000000000000000000000000" XCF_NEW_LINE);
  2422. PutString(h,"cleartomark" XCF_NEW_LINE);
  2423. }
  2424. else
  2425. PutString(h, "end" XCF_NEW_LINE); /* "end" for systemdict begin */
  2426. }
  2427. static void WriteAdditionalProlog(XCF_Handle h)
  2428. {
  2429. if (h->options.eexecEncryption)
  2430. StopEexec(h);
  2431. PutString(h, "" XCF_NEW_LINE);
  2432. PutString(h, "" XCF_NEW_LINE);
  2433. if (h->options.eexecEncryption)
  2434. StartEexec(h);
  2435. else /* eexec makes the systemdict current. When encryption is off this
  2436. must be done explicitly. */
  2437. PutString(h, "systemdict begin" XCF_NEW_LINE);
  2438. PutString(h, "/");
  2439. PutFontName(h);
  2440. PutString(h, " findfont dup" XCF_NEW_LINE);
  2441. PutString(h, "/Private get dup rcheck" XCF_NEW_LINE);
  2442. PutString(h, "{begin true}{pop false}ifelse exch" XCF_NEW_LINE);
  2443. PutString(h, "/CharStrings get begin" XCF_NEW_LINE);
  2444. }
  2445. static void WriteAdditionalEpilog(XCF_Handle h)
  2446. {
  2447. int i;
  2448. PutString(h, "end {end}if" XCF_NEW_LINE); /* end of the charstrings */
  2449. if (h->options.eexecEncryption)
  2450. {
  2451. PutString(h, "mark currentfile closefile\n"); /* must be terminated with
  2452. line feed only */
  2453. StopEexec(h);
  2454. PutString(h, ""XCF_NEW_LINE);
  2455. for(i = 0;i < 8;i++)
  2456. PutString(h, "0000000000000000000000000000000000000000000000000000000000000000" XCF_NEW_LINE);
  2457. PutString(h, "cleartomark" XCF_NEW_LINE);
  2458. }
  2459. else
  2460. PutString(h, "end" XCF_NEW_LINE); /* "end" for systemdict begin */
  2461. }
  2462. void XT1_WriteAdditionalFontSubset(XCF_Handle h,
  2463. short cGlyphs, XCFGlyphID PTR_PREFIX *pGlyphID,
  2464. unsigned char PTR_PREFIX **pGlyphName,
  2465. unsigned long PTR_PREFIX *pCharStrLength)
  2466. {
  2467. WriteAdditionalProlog(h);
  2468. WriteCharstrings(h, 0, cGlyphs, pGlyphID, pGlyphName, pCharStrLength);
  2469. WriteAdditionalEpilog(h);
  2470. }
  2471. void XT1_ShowHexString(XCF_Handle h,
  2472. unsigned char PTR_PREFIX *hexString,
  2473. boolean showCtrlD)
  2474. {
  2475. short i, j;
  2476. char str[50];
  2477. boolean done = false;
  2478. PutString(h, "/inch {72 mul} def" XCF_NEW_LINE);
  2479. PutString(h, "/");
  2480. PutFontName(h);
  2481. PutString(h, " findfont" XCF_NEW_LINE);
  2482. PutString(h, "0.5 inch scalefont" XCF_NEW_LINE);
  2483. PutString(h, "setfont" XCF_NEW_LINE);
  2484. for ( i = 0; !done; i++)
  2485. {
  2486. h->callbacks.xcfSprintf(str, CCHOF(str), "%s0.5 inch %d inch moveto%s", XCF_NEW_LINE,
  2487. 10 - i, XCF_NEW_LINE );
  2488. PutString(h, str);
  2489. PutString(h, "<");
  2490. for (j = 0; j <= 40;)
  2491. {
  2492. str[j++] = *hexString++;
  2493. str[j++] = *hexString++;
  2494. if (*hexString == '\0')
  2495. {
  2496. done = true;
  2497. break;
  2498. }
  2499. }
  2500. str[j] = '\0';
  2501. PutString(h, str);
  2502. PutString(h, "> show " XCF_NEW_LINE);
  2503. if (i > 9)
  2504. {
  2505. i = -1;
  2506. PutString(h, "showpage" XCF_NEW_LINE);
  2507. }
  2508. }
  2509. PutString(h, "showpage" XCF_NEW_LINE);
  2510. if (showCtrlD)
  2511. PutString(h, "\004");
  2512. }
  2513. #ifdef __cplusplus
  2514. }
  2515. #endif