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.

2777 lines
76 KiB

  1. /* @(#)CM_VerSion xcf_cstr.c atm09 1.2 16499.eco sum= 34614 atm09.002 */
  2. /* @(#)CM_VerSion xcf_cstr.c atm08 1.6 16345.eco sum= 33712 atm08.005 */
  3. /***********************************************************************/
  4. /* */
  5. /* Copyright 1990-1995 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. /* If Init fails you are done. If any other function fails you must call clean up */
  24. #ifndef XCF_DUMP
  25. #include "xcf_priv.h"
  26. #else
  27. #include <stdio.h>
  28. #ifndef _SIZE_T
  29. #define _SIZE_T /* so size_t isn't redefined here */
  30. #include "xcf_priv.h"
  31. #undef _SIZE_T
  32. #else
  33. #include "xcf_priv.h"
  34. #endif
  35. #endif
  36. #ifdef T13
  37. #include "xcf_t13.h"
  38. #endif
  39. #ifdef __cplusplus
  40. extern "C" {
  41. #endif
  42. typedef struct /* Individual charstring record */
  43. {
  44. unsigned short length;
  45. char *cstr;
  46. } Charstring;
  47. typedef struct /* Transitional char record */
  48. {
  49. StringID sid;
  50. Charstring cstr;
  51. } TransChar;
  52. static void FlattenSubr(XCF_Handle h, unsigned int depth, boolean PTR_PREFIX
  53. *endcharFound, boolean localSubr);
  54. static void WriteT1Data(XCF_Handle h, Card8 *pData, CardX length, boolean subr)
  55. {
  56. CardX i;
  57. if (subr)
  58. for (i=0;i<length;++i)
  59. *da_NEXT(h->type1.subrs) = *pData++;
  60. else
  61. for (i=0;i<length;++i)
  62. *da_NEXT(h->type1.charStrs) = *pData++;
  63. }
  64. void XC_WriteT1OpCode(XCF_Handle h, Card16 opCode, boolean subr)
  65. {
  66. Card8 output[2] = {tx_escape};
  67. output[1] = (Card8) OpCode(opCode);
  68. if (IsEscOp(opCode))
  69. WriteT1Data(h, output, 2, subr);
  70. else
  71. WriteT1Data(h, output + 1, 1, subr);
  72. }
  73. static void NewT1CharStr(XCF_Handle h)
  74. {
  75. if (CIDFONT)
  76. {
  77. if ((h->options.outputCharstrType != 2) && (h->dict.fontType != 1))
  78. h->type1.charStrs.cnt = 0;
  79. }
  80. else
  81. {
  82. *da_NEXT(h->type1.charStrOffsets) = h->type1.charStrs.cnt;
  83. }
  84. }
  85. static void FreeT1CharStr(XCF_Handle h)
  86. {
  87. h->type1.charStrs.cnt = 0;
  88. h->type1.charStrOffsets.cnt = 0;
  89. *da_NEXT(h->type1.charStrOffsets) = 0;
  90. }
  91. #if 0
  92. static void FreeT1Subr(XCF_Handle h)
  93. {
  94. h->type1.subrs.cnt = 0;
  95. h->type1.subrOffsets.cnt = 0;
  96. *da_NEXT(h->type1.subrOffsets) = 0;
  97. }
  98. #endif
  99. static void NewT1Subr(XCF_Handle h)
  100. {
  101. if (h->type1.subrs.cnt)
  102. XC_WriteT1OpCode(h, tx_return, true);
  103. *da_NEXT(h->type1.subrOffsets) = h->type1.subrs.cnt;
  104. }
  105. /* Encode Int32 number and return length */
  106. static Card16 IntToCharstr(Int32 i, Card8 PTR_PREFIX *t)
  107. {
  108. if (-107 <= i && i <= 107)
  109. {
  110. /* Single byte number */
  111. t[0] = (Card8)(i + 139);
  112. t[1] = '\0';
  113. return 1;
  114. }
  115. else if (108 <= i && i <= 1131)
  116. {
  117. /* +ve 2-byte number */
  118. i -= 108;
  119. t[0] = (Card8)((i>>8) + 247);
  120. t[1] = (Card8) i;
  121. t[2] = '\0';
  122. return 2;
  123. }
  124. else if (-1131 <= i && i <= -108)
  125. {
  126. /* -ve 2-byte number */
  127. i += 108;
  128. t[0] = (Card8)((-i>>8) + 251);
  129. t[1] = (Card8) -i;
  130. t[2] = '\0';
  131. return 2;
  132. }
  133. else
  134. {
  135. /* 5-byte fixed point */
  136. t[0] = 255;
  137. t[1] = (Card8) (i>>24 & 0x0ff);
  138. t[2] = (Card8) (i>>16 & 0x0ff);
  139. t[3] = (Card8) (i>>8 & 0x0ff);
  140. t[4] = (Card8) (i & 0x0ff);
  141. t[5] = '\0';
  142. return 5;
  143. }
  144. }
  145. /*
  146. Convert a fixed point number into a charstring of the form "int int div".
  147. The second int in the charstring passed in is the "denominator".
  148. */
  149. static Card16 ConvertFixedDiv(Fixed f, Card8 PTR_PREFIX *t, Int32 denominator)
  150. {
  151. Int32 numerator;
  152. Card16 length;
  153. boolean negative = false;
  154. if (f < 0)
  155. {
  156. negative = true;
  157. f = -f;
  158. }
  159. /*
  160. Multiply by denominator and round to nearest integer.
  161. Process upper and lower 16 bits seperately to avoid overflow.
  162. */
  163. numerator = (f >> 16) * denominator;
  164. numerator += (((f & 0x0000ffff) * denominator) + 0x08000) >> 16;
  165. if (negative)
  166. numerator = -numerator;
  167. length = IntToCharstr(numerator, t);
  168. length += IntToCharstr(denominator, t+length);
  169. t[length] = (Card8) tx_escape;
  170. t[length+1] = (Card8) OpCode(tx_div);
  171. t[length+2] = '\0';
  172. return length+2;
  173. }
  174. /*
  175. Calculates how close to zero or one the fractional part of
  176. a fixed point number is after it is multiplied by the integer
  177. passed in "denominator".
  178. */
  179. static Card32 CalculateTolerance(Fixed f, Card32 denominator)
  180. {
  181. Card32 tolerance;
  182. if (f < 0) /* Force number to be positive */
  183. f = -f;
  184. /* multiply and truncate integer part (leaving fractional part) */
  185. tolerance = (f * denominator) & 0x0000ffff;
  186. if (tolerance > 0x08000) /* If greater than 0.5 then use 1 - tolerance */
  187. tolerance = 0x10000 - tolerance;
  188. return (tolerance);
  189. }
  190. #define DIV_MIN_TOLERANCE 64 /* 64/65536 = ~0.001 */
  191. /* Encode 16.16 fixed point number and return length */
  192. static Card16 FixedToCharstr(Fixed f, Card8 PTR_PREFIX *t)
  193. {
  194. Int32 denominator, bestDenominator;
  195. Int32 tolerance, bestTolerance;
  196. /* If integer then convert to "int" format and return */
  197. if (!(f & 0x0000ffff))
  198. return IntToCharstr(f>>16, t);
  199. /* Otherwise it's a fraction so convert to "int int div" format */
  200. /* Try common cases 10 and 100 first */
  201. if (CalculateTolerance(f, 10) < DIV_MIN_TOLERANCE)
  202. return (ConvertFixedDiv(f, t, 10));
  203. else if (CalculateTolerance(f, 100) < DIV_MIN_TOLERANCE)
  204. return (ConvertFixedDiv(f, t, 100));
  205. /*
  206. Try all cases between 2 and 199. This can be slow
  207. but it should only run all the way through if no
  208. close match is found. This will never happen for
  209. known fonts. If it does happen then the closest
  210. match between 2 and 199 will be used.
  211. */
  212. bestDenominator = 1;
  213. bestTolerance = 0x0ffff;
  214. for (denominator=2; denominator < 200; ++denominator)
  215. {
  216. tolerance = CalculateTolerance(f, denominator);
  217. if (tolerance < DIV_MIN_TOLERANCE)
  218. return (ConvertFixedDiv(f, t, denominator));
  219. else if (tolerance < bestTolerance)
  220. {
  221. bestTolerance = tolerance;
  222. bestDenominator = denominator;
  223. }
  224. }
  225. return (ConvertFixedDiv(f, t, bestDenominator));
  226. }
  227. static void WriteFixed(XCF_Handle h, Fixed f, boolean subr)
  228. {
  229. Card8 str[30];
  230. Card16 length;
  231. length = FixedToCharstr(f, str);
  232. if (length == 0)
  233. XCF_FATAL_ERROR(h, XCF_InvalidNumber, "FixedToCharstr failed.", 0 );
  234. else
  235. WriteT1Data(h, str, length, subr);
  236. }
  237. void XC_WriteT1PStackValue(XCF_Handle h, PStackValue psv, boolean subr)
  238. {
  239. IntX i;
  240. Fixed initialValue = INT_TO_FIXED(0);
  241. if (!psv->blend)
  242. {
  243. WriteFixed(h, psv->value[0], subr);
  244. }
  245. else
  246. {
  247. WriteFixed(h, psv->value[0], subr);
  248. initialValue = psv->value[0];
  249. for (i=1; i<h->dict.numberOfMasters; ++i)
  250. {
  251. WriteFixed(h, psv->value[i] - initialValue, subr);
  252. }
  253. WriteFixed(h, INT_TO_FIXED(6), subr);
  254. XC_WriteT1OpCode(h, tx_callsubr, subr);
  255. }
  256. }
  257. /* StackValue Manipulation Routines */
  258. #define NEXTSTACKVALUE(p, offset, svSize) (PStackValue)(p+offset); \
  259. offset += svSize;
  260. static void NewStackValues(XCF_Handle h, void PTR_PREFIX * PTR_PREFIX *p,
  261. Card32 cStackValues, Card16 PTR_PREFIX *svSize)
  262. {
  263. Card16 totalSize;
  264. /* Allocate the data space for all the stack values that we need */
  265. *svSize = SIZEOF_STACK_VALUES((h->dict.numberOfMasters) ? h->dict.numberOfMasters : 1);
  266. totalSize = (Card16)(*svSize * cStackValues);
  267. *p = 0;
  268. if (!h->callbacks.allocate(p, totalSize, h->callbacks.allocateHook))
  269. XCF_FATAL_ERROR(h, XCF_MemoryAllocationError, "StackValue Allocation Failure.", totalSize);
  270. h->callbacks.memset((void PTR_PREFIX *)*p, 0, totalSize);
  271. }
  272. static PStackValue IntToPSV(void PTR_PREFIX *psv, Int32 i)
  273. {
  274. ((PShortStackValue)psv)->blend = false;
  275. ((PShortStackValue)psv)->value = INT_TO_FIXED(i);
  276. return (PStackValue)psv;
  277. }
  278. static void FixedToPSV(void PTR_PREFIX *psv, Fixed f)
  279. {
  280. ((PShortStackValue)psv)->blend = false;
  281. ((PShortStackValue)psv)->value = f;
  282. }
  283. static void PSVFixedAdd(XCF_Handle h, PStackValue psv, Fixed f)
  284. {
  285. IntX i;
  286. if (psv->blend)
  287. for (i = 0; i < h->dict.numberOfMasters; ++i)
  288. psv->value[i] += f;
  289. else
  290. psv->value[0] += f;
  291. }
  292. static void PSVCopy(XCF_Handle h, PStackValue pdest, PStackValue psrc)
  293. {
  294. IntX i;
  295. if (pdest != psrc)
  296. {
  297. pdest->blend = psrc->blend;
  298. if (psrc->blend)
  299. for (i=0; i < h->dict.numberOfMasters; ++i)
  300. pdest->value[i] = psrc->value[i];
  301. else
  302. pdest->value[0] = psrc->value[0];
  303. }
  304. }
  305. static void PSVFixedSubtract(XCF_Handle h, PStackValue psv, Fixed f)
  306. {
  307. IntX i;
  308. if (psv->blend)
  309. for (i = 0; i < h->dict.numberOfMasters; ++i)
  310. psv->value[i] -= f;
  311. else
  312. psv->value[0] -= f;
  313. }
  314. static void FixedPSVSubtract(XCF_Handle h, PStackValue psv, Fixed f)
  315. {
  316. IntX i;
  317. if (psv->blend)
  318. for (i = 0; i < h->dict.numberOfMasters; ++i)
  319. psv->value[i] = f - psv->value[i];
  320. else
  321. psv->value[0] = f - psv->value[0];
  322. }
  323. static void PSVRealAdd(XCF_Handle h, PStackValue psv, Fixed d)
  324. {
  325. IntX i;
  326. if (psv->blend)
  327. for (i = 0; i < h->dict.numberOfMasters; ++i)
  328. psv->value[i] += d;
  329. else
  330. psv->value[0] += d;
  331. }
  332. /* psvDest cannot equal psv1 or psv2! */
  333. static void PStackValueAdd(XCF_Handle h, PStackValue psvDest, PStackValue psv1, PStackValue psv2)
  334. {
  335. IntX i;
  336. if (!psv1->blend)
  337. {
  338. PSVCopy(h,psvDest, psv2);
  339. PSVFixedAdd(h, psvDest, psv1->value[0]);
  340. }
  341. else if (!psv2->blend)
  342. {
  343. PSVCopy(h,psvDest, psv1);
  344. PSVFixedAdd(h, psvDest, psv2->value[0]);
  345. }
  346. else
  347. {
  348. PSVCopy(h,psvDest, psv1);
  349. for (i = 0; i < h->dict.numberOfMasters; ++i)
  350. psvDest->value[i] += psv2->value[i];
  351. }
  352. }
  353. #define PSVAdd(h, psvDest, psv1, psv2) ((!h->dict.numberOfMasters)?FixedToPSV(psvDest, (psv1)->value[0]+(psv2)->value[0]): PStackValueAdd(h, psvDest, psv1, psv2))
  354. /* psvDest cannot equal psv1 or psv2! */
  355. static void PSVSubtract(XCF_Handle h, PStackValue psvDest, PStackValue psv1, PStackValue psv2)
  356. {
  357. IntX i;
  358. if (!psv1->blend)
  359. {
  360. PSVCopy(h,psvDest, psv2);
  361. FixedPSVSubtract(h, psvDest, psv1->value[0]);
  362. }
  363. else if (!psv2->blend)
  364. {
  365. PSVCopy(h,psvDest, psv1);
  366. PSVFixedSubtract(h, psvDest, psv2->value[0]);
  367. }
  368. else
  369. {
  370. PSVCopy(h,psvDest, psv1);
  371. for (i = 0; i < h->dict.numberOfMasters; ++i)
  372. psvDest->value[i] -= psv2->value[i];
  373. }
  374. }
  375. static void PStackValueAdd4(XCF_Handle h, PStackValue psvDest, PStackValue psv1, PStackValue psv2, PStackValue psv3, PStackValue psv4)
  376. {
  377. StackValue temp1, temp2;
  378. PStackValueAdd(h, &temp1, psv1, psv2);
  379. PStackValueAdd(h, &temp2, &temp1, psv3);
  380. PStackValueAdd(h, psvDest, &temp2, psv4);
  381. }
  382. #define PSVAdd4(h, psvDest, psv1, psv2, psv3, psv4) ((!h->dict.numberOfMasters)?FixedToPSV(psvDest, (psv1)->value[0]+(psv2)->value[0]+(psv3)->value[0]+(psv4)->value[0]): PStackValueAdd4(h, psvDest, psv1, psv2, psv3, psv4))
  383. static void PSVAdd5(XCF_Handle h, PStackValue psvDest, PStackValue psv1, PStackValue psv2, PStackValue psv3, PStackValue psv4, PStackValue psv5)
  384. {
  385. StackValue temp;
  386. PSVAdd4(h,&temp,psv1,psv2,psv3,psv4);
  387. PStackValueAdd(h,psvDest,&temp,psv5);
  388. }
  389. static void PSVAdd7(XCF_Handle h, PStackValue psvDest, PStackValue psv1, PStackValue psv2, PStackValue psv3, PStackValue psv4, PStackValue psv5, PStackValue psv6, PStackValue psv7)
  390. {
  391. StackValue temp;
  392. PSVAdd4(h,&temp,psv1,psv2,psv3,psv4);
  393. PSVAdd4(h,psvDest,&temp,psv5,psv6,psv7);
  394. }
  395. /***************************************************/
  396. /************************** Basic Operations ******************************/
  397. static void Hsbw(XCF_Handle h, PStackValue psbx, PStackValue pwx, boolean subr)
  398. {
  399. XC_WriteT1PStackValue(h, psbx, subr);
  400. XC_WriteT1PStackValue(h, pwx, subr);
  401. XC_WriteT1OpCode(h, t1_hsbw, subr);
  402. #ifdef XCF_DUMP
  403. printf("%g %g <hsbw> ", FIXED_TO_REAL(psbx->value[0]), FIXED_TO_REAL(pwx->value[0]));
  404. #endif
  405. }
  406. static void RMoveTo(XCF_Handle h, PStackValue pdx, PStackValue pdy, boolean subr)
  407. {
  408. StackValue temp;
  409. if ((!pdx->blend) && (pdx->value[0] == 0))
  410. {
  411. XC_WriteT1PStackValue(h, pdy, subr);
  412. XC_WriteT1OpCode(h, tx_vmoveto, subr);
  413. }
  414. else if ((!pdy->blend) && (pdy->value[0] == 0))
  415. {
  416. XC_WriteT1PStackValue(h, pdx, subr);
  417. XC_WriteT1OpCode(h, tx_hmoveto, subr);
  418. }
  419. else
  420. {
  421. XC_WriteT1PStackValue(h, pdx, subr);
  422. XC_WriteT1PStackValue(h, pdy, subr);
  423. XC_WriteT1OpCode(h, tx_rmoveto, subr);
  424. }
  425. PSVCopy(h, &temp, h->cstr.x);
  426. PSVAdd(h, h->cstr.x, &temp, pdx);
  427. PSVCopy(h, &temp, h->cstr.y);
  428. PSVAdd(h, h->cstr.y, &temp, pdy);
  429. #ifdef XCF_DUMP
  430. printf("%g %g <rmoveto> ", FIXED_TO_REAL(pdx->value[0]), FIXED_TO_REAL(pdy->value[0]));
  431. #endif
  432. }
  433. static void RLineTo(XCF_Handle h, PStackValue pdx, PStackValue pdy, boolean subr)
  434. {
  435. StackValue temp;
  436. if ((!pdx->blend) && (pdx->value[0] == 0))
  437. {
  438. XC_WriteT1PStackValue(h, pdy, subr);
  439. XC_WriteT1OpCode(h, tx_vlineto, subr);
  440. }
  441. else if ((!pdy->blend) && (pdy->value[0] == 0))
  442. {
  443. XC_WriteT1PStackValue(h, pdx, subr);
  444. XC_WriteT1OpCode(h, tx_hlineto, subr);
  445. }
  446. else
  447. {
  448. XC_WriteT1PStackValue(h, pdx, subr);
  449. XC_WriteT1PStackValue(h, pdy, subr);
  450. XC_WriteT1OpCode(h, tx_rlineto, subr);
  451. }
  452. PSVCopy(h, &temp, h->cstr.x);
  453. PSVAdd(h, h->cstr.x, &temp, pdx);
  454. PSVCopy(h, &temp, h->cstr.y);
  455. PSVAdd(h, h->cstr.y, &temp, pdy);
  456. #ifdef XCF_DUMP
  457. printf("%g %g <rlineto> ", FIXED_TO_REAL(pdx->value[0]), FIXED_TO_REAL(pdy->value[0]));
  458. #endif
  459. }
  460. static void RRCurveTo(XCF_Handle h, PStackValue pdx1, PStackValue pdy1,
  461. PStackValue pdx2, PStackValue pdy2, PStackValue pdx3,
  462. PStackValue pdy3, boolean subr)
  463. {
  464. StackValue temp;
  465. if ( ((!pdy1->blend) && (pdy1->value[0] == 0)) && ((!pdx3->blend) && (pdx3->value[0] == 0)))
  466. {
  467. XC_WriteT1PStackValue(h, pdx1, subr);
  468. XC_WriteT1PStackValue(h, pdx2, subr);
  469. XC_WriteT1PStackValue(h, pdy2, subr);
  470. XC_WriteT1PStackValue(h, pdy3, subr);
  471. XC_WriteT1OpCode(h, tx_hvcurveto, subr);
  472. }
  473. else if ( ((!pdx1->blend) && (pdx1->value[0] == 0)) && ((!pdy3->blend) && (pdy3->value[0] == 0)))
  474. {
  475. XC_WriteT1PStackValue(h, pdy1, subr);
  476. XC_WriteT1PStackValue(h, pdx2, subr);
  477. XC_WriteT1PStackValue(h, pdy2, subr);
  478. XC_WriteT1PStackValue(h, pdx3, subr);
  479. XC_WriteT1OpCode(h, tx_vhcurveto, subr);
  480. }
  481. else
  482. {
  483. XC_WriteT1PStackValue(h, pdx1, subr);
  484. XC_WriteT1PStackValue(h, pdy1, subr);
  485. XC_WriteT1PStackValue(h, pdx2, subr);
  486. XC_WriteT1PStackValue(h, pdy2, subr);
  487. XC_WriteT1PStackValue(h, pdx3, subr);
  488. XC_WriteT1PStackValue(h, pdy3, subr);
  489. XC_WriteT1OpCode(h, tx_rrcurveto, subr);
  490. }
  491. PSVCopy(h, &temp, h->cstr.x);
  492. PSVAdd4(h, h->cstr.x, &temp, pdx1, pdx2, pdx3);
  493. PSVCopy(h, &temp, h->cstr.y);
  494. PSVAdd4(h, h->cstr.y, &temp, pdy1, pdy2, pdy3);
  495. #ifdef XCF_DUMP
  496. printf("%g %g %g %g %g %g <rrcurveto> ", FIXED_TO_REAL(pdx1->value[0]), FIXED_TO_REAL(pdy1->value[0]), FIXED_TO_REAL(pdx2->value[0]), FIXED_TO_REAL(pdy2->value[0]), FIXED_TO_REAL(pdx3->value[0]), FIXED_TO_REAL(pdy3->value[0]));
  497. #endif
  498. }
  499. static void Seac(XCF_Handle h, PStackValue pasb, PStackValue padx, PStackValue
  500. pady, PStackValue pbchar, PStackValue pachar, boolean subr)
  501. {
  502. h->cstr.baseSeac = FIXED_TO_INT(pbchar->value[0]);
  503. h->cstr.accentSeac = FIXED_TO_INT(pachar->value[0]);
  504. XC_WriteT1PStackValue(h, pasb, subr);
  505. XC_WriteT1PStackValue(h, padx, subr);
  506. XC_WriteT1PStackValue(h, pady, subr);
  507. XC_WriteT1PStackValue(h, pbchar, subr);
  508. XC_WriteT1PStackValue(h, pachar, subr);
  509. XC_WriteT1OpCode(h, t1_seac, subr);
  510. }
  511. static void DotSection(XCF_Handle h, boolean subr)
  512. {
  513. XC_WriteT1OpCode(h, tx_dotsection, subr);
  514. #ifdef XCF_DUMP
  515. printf("<dotsection> ");
  516. #endif
  517. }
  518. static void WriteFlexCoordinate(XCF_Handle h, PStackValue pdx, PStackValue pdy,
  519. boolean subr)
  520. {
  521. ShortStackValue temp;
  522. if ((!pdx->blend) && (pdx->value[0] == 0))
  523. {
  524. XC_WriteT1PStackValue(h, pdy, subr);
  525. XC_WriteT1OpCode(h, tx_vmoveto, subr);
  526. }
  527. else if ((!pdy->blend) && (pdy->value[0] == 0))
  528. {
  529. XC_WriteT1PStackValue(h, pdx, subr);
  530. XC_WriteT1OpCode(h, tx_hmoveto, subr);
  531. }
  532. else
  533. {
  534. XC_WriteT1PStackValue(h, pdx, subr);
  535. XC_WriteT1PStackValue(h, pdy, subr);
  536. XC_WriteT1OpCode(h, tx_rmoveto, subr);
  537. }
  538. XC_WriteT1PStackValue(h, IntToPSV(&temp, 2), subr);
  539. XC_WriteT1OpCode(h, tx_callsubr, subr);
  540. }
  541. static void Flex(
  542. XCF_Handle h,
  543. PStackValue pdx1,
  544. PStackValue pdy1,
  545. PStackValue pdx2,
  546. PStackValue pdy2,
  547. PStackValue pdx3,
  548. PStackValue pdy3,
  549. PStackValue pdx4,
  550. PStackValue pdy4,
  551. PStackValue pdx5,
  552. PStackValue pdy5,
  553. PStackValue pdx6,
  554. PStackValue pdy6,
  555. PStackValue pdx7,
  556. PStackValue pdy7,
  557. PStackValue pflexHeight,
  558. PStackValue pendpointX,
  559. PStackValue pendpointY,
  560. boolean subr)
  561. {
  562. ShortStackValue temp;
  563. XC_WriteT1PStackValue(h, IntToPSV(&temp, 1), subr);
  564. XC_WriteT1OpCode(h, tx_callsubr, subr);
  565. WriteFlexCoordinate(h, pdx1, pdy1, subr);
  566. WriteFlexCoordinate(h, pdx2, pdy2, subr);
  567. WriteFlexCoordinate(h, pdx3, pdy3, subr);
  568. WriteFlexCoordinate(h, pdx4, pdy4, subr);
  569. WriteFlexCoordinate(h, pdx5, pdy5, subr);
  570. WriteFlexCoordinate(h, pdx6, pdy6, subr);
  571. WriteFlexCoordinate(h, pdx7, pdy7, subr);
  572. XC_WriteT1PStackValue(h, pflexHeight, subr);
  573. XC_WriteT1PStackValue(h, pendpointX, subr);
  574. XC_WriteT1PStackValue(h, pendpointY, subr);
  575. XC_WriteT1PStackValue(h, PSTACKVALUE(h, SV0), subr);
  576. XC_WriteT1OpCode(h, tx_callsubr, subr);
  577. PSVCopy(h, h->cstr.x, pendpointX);
  578. PSVCopy(h, h->cstr.y, pendpointY);
  579. #ifdef XCF_DUMP
  580. printf("<flex> ");
  581. #endif
  582. }
  583. static void HStem(XCF_Handle h, PStackValue py, PStackValue pdy, boolean subr)
  584. {
  585. boolean hintSub = ((!CIDFONT) && (h->cstr.subrFlatten == 0) &&
  586. (h->cstr.hints == SubrHints)) || subr;
  587. XC_WriteT1PStackValue(h, py, hintSub);
  588. XC_WriteT1PStackValue(h, pdy, hintSub);
  589. XC_WriteT1OpCode(h, tx_hstem, hintSub);
  590. h->cstr.waitingForFirstHint = false;
  591. #ifdef XCF_DUMP
  592. printf("%g %g <hstem> ", FIXED_TO_REAL(py->value[0]), FIXED_TO_REAL(pdy->value[0]));
  593. #endif
  594. }
  595. static void VStem(XCF_Handle h, PStackValue px, PStackValue pdx, boolean subr)
  596. {
  597. boolean hintSub = ((!CIDFONT) && (h->cstr.subrFlatten == 0) &&
  598. (h->cstr.hints == SubrHints)) || subr;
  599. XC_WriteT1PStackValue(h, px, hintSub);
  600. XC_WriteT1PStackValue(h, pdx, hintSub);
  601. XC_WriteT1OpCode(h, tx_vstem, hintSub);
  602. h->cstr.waitingForFirstHint = false;
  603. #ifdef XCF_DUMP
  604. printf("%g %g <vstem> ", FIXED_TO_REAL(px->value[0]), FIXED_TO_REAL(pdx->value[0]));
  605. #endif
  606. }
  607. static void HStem3(XCF_Handle h, PStackValue py0, PStackValue pdy0, PStackValue
  608. py1, PStackValue pdy1, PStackValue py2, PStackValue pdy2,
  609. boolean subr)
  610. {
  611. boolean hintSub = ((!CIDFONT) && (h->cstr.subrFlatten == 0) &&
  612. (h->cstr.hints == SubrHints)) || subr;
  613. XC_WriteT1PStackValue(h, py0, hintSub);
  614. XC_WriteT1PStackValue(h, pdy0, hintSub);
  615. XC_WriteT1PStackValue(h, py1, hintSub);
  616. XC_WriteT1PStackValue(h, pdy1, hintSub);
  617. XC_WriteT1PStackValue(h, py2, hintSub);
  618. XC_WriteT1PStackValue(h, pdy2, hintSub);
  619. XC_WriteT1OpCode(h, t1_hstem3, hintSub);
  620. h->cstr.waitingForFirstHint = false;
  621. #ifdef XCF_DUMP
  622. printf("%g %g %g %g %g %g <hstem3> ", FIXED_TO_REAL(py0->value[0]), FIXED_TO_REAL(pdy0->value[0]), FIXED_TO_REAL(py1->value[0]), FIXED_TO_REAL(pdy1->value[0]), FIXED_TO_REAL(py2->value[0]), FIXED_TO_REAL(pdy2->value[0]));
  623. #endif
  624. }
  625. static void VStem3(XCF_Handle h, PStackValue px0, PStackValue pdx0, PStackValue
  626. px1, PStackValue pdx1, PStackValue px2, PStackValue pdx2,
  627. boolean subr)
  628. {
  629. boolean hintSub = ((!CIDFONT) && (h->cstr.subrFlatten == 0) &&
  630. (h->cstr.hints == SubrHints)) || subr;
  631. XC_WriteT1PStackValue(h, px0, hintSub);
  632. XC_WriteT1PStackValue(h, pdx0, hintSub);
  633. XC_WriteT1PStackValue(h, px1, hintSub);
  634. XC_WriteT1PStackValue(h, pdx1, hintSub);
  635. XC_WriteT1PStackValue(h, px2, hintSub);
  636. XC_WriteT1PStackValue(h, pdx2, hintSub);
  637. XC_WriteT1OpCode(h, t1_vstem3, hintSub);
  638. h->cstr.waitingForFirstHint = false;
  639. #ifdef XCF_DUMP
  640. printf("%g %g %g %g %g %g <vstem3> ", FIXED_TO_REAL(px0->value[0]), FIXED_TO_REAL(pdx0->value[0]), FIXED_TO_REAL(px1->value[0]), FIXED_TO_REAL(pdx1->value[0]), FIXED_TO_REAL(px2->value[0]), FIXED_TO_REAL(pdx2->value[0]));
  641. #endif
  642. }
  643. static void ClosePath(XCF_Handle h, boolean subr)
  644. {
  645. XC_WriteT1OpCode(h, t1_closepath, subr);
  646. #ifdef XCF_DUMP
  647. printf("<closepath> ");
  648. #endif
  649. }
  650. static void EndChar(XCF_Handle h, boolean subr)
  651. {
  652. XC_WriteT1OpCode(h, tx_endchar, subr);
  653. #ifdef XCF_DUMP
  654. printf("<endchar> \n\n");
  655. #endif
  656. }
  657. static void StartHintSub(XCF_Handle h, boolean subr)
  658. {
  659. ShortStackValue temp;
  660. if (CIDFONT)
  661. {
  662. XC_WriteT1PStackValue(h, IntToPSV(&temp, 4), subr);
  663. XC_WriteT1OpCode(h, tx_callsubr, subr);
  664. }
  665. else
  666. {
  667. if (!h->cstr.subrFlatten)
  668. XC_WriteT1PStackValue(h, IntToPSV(&temp, h->type1.subrOffsets.cnt), subr);
  669. XC_WriteT1PStackValue(h, IntToPSV(&temp, 4), subr);
  670. XC_WriteT1OpCode(h, tx_callsubr, subr);
  671. if (!h->cstr.subrFlatten)
  672. NewT1Subr(h);
  673. }
  674. #ifdef XCF_DUMP
  675. printf("[HINT SUB] ");
  676. #endif
  677. }
  678. /*************************** End Basic Operations **************************/
  679. static void WriteReversedCounterArg(XCF_Handle h, PStackValue parg, boolean subr)
  680. {
  681. IntX argIndex;
  682. ShortStackValue temp;
  683. if (h->cstr.counterBufferCount < 22)
  684. PSVCopy(h, h->cstr.counterBuffer[h->cstr.counterBufferCount++], parg);
  685. else
  686. {
  687. for (argIndex = 21; argIndex >= 0; --argIndex)
  688. XC_WriteT1PStackValue(h, h->cstr.counterBuffer[argIndex], subr);
  689. XC_WriteT1PStackValue(h, IntToPSV(&temp, 22), subr);
  690. XC_WriteT1PStackValue(h, IntToPSV(&temp, 12), subr);
  691. XC_WriteT1OpCode(h, t1_callother, subr);
  692. PSVCopy(h, h->cstr.counterBuffer[0], parg);
  693. h->cstr.counterBufferCount = 1;
  694. }
  695. }
  696. static void FlushReversedCounterArgs(XCF_Handle h, boolean subr)
  697. {
  698. IntX argIndex;
  699. ShortStackValue temp;
  700. if (!h->cstr.counterBufferCount)
  701. return;
  702. for (argIndex = h->cstr.counterBufferCount-1; argIndex >= 0; --argIndex)
  703. XC_WriteT1PStackValue(h, h->cstr.counterBuffer[argIndex], subr);
  704. XC_WriteT1PStackValue(h, IntToPSV(&temp, h->cstr.counterBufferCount), subr);
  705. XC_WriteT1PStackValue(h, IntToPSV(&temp, 13), subr);
  706. XC_WriteT1OpCode(h, t1_callother, subr);
  707. }
  708. /* This structure is defined to store the temporary counterGroup info. */
  709. typedef struct {
  710. StackValue edge;
  711. StackValue delta;
  712. Card16 opCode;
  713. Card32 counterGroups;
  714. } CounterValue;
  715. static void NewCounterValues(XCF_Handle h, void PTR_PREFIX * PTR_PREFIX *p)
  716. {
  717. if ( *p == 0 )
  718. {
  719. Card16 totalSize;
  720. /* Allocate the data space for all the counter values that we need */
  721. totalSize = (Card16)(sizeof(CounterValue) * MAX_HINTS);
  722. if (!h->callbacks.allocate(p, totalSize, h->callbacks.allocateHook))
  723. XCF_FATAL_ERROR(h, XCF_MemoryAllocationError, "CounterValue Allocation Failure.", totalSize);
  724. h->callbacks.memset((void PTR_PREFIX *)*p, 0, totalSize);
  725. }
  726. }
  727. static void WriteHorVCounters(XCF_Handle h, Card16 opCode, CardX groupCount,
  728. boolean subr)
  729. {
  730. CardX hintIndex;
  731. CardX groupIndex;
  732. IntX argIndex;
  733. CounterValue *counterGroup;
  734. CardX counterGroupCount;
  735. StackValue currentEdge;
  736. StackValue nextEdge;
  737. StackValue temp;
  738. boolean firstStem;
  739. /* Make sure that we allocate memory for our temp CounterValue. */
  740. NewCounterValues(h, (void PTR_PREFIX * PTR_PREFIX *)&h->cstr.pCounterVal);
  741. counterGroup = (CounterValue *)h->cstr.pCounterVal;
  742. for (groupIndex = groupCount; groupIndex > 0; --groupIndex)
  743. { /* loop backwards through groups */
  744. IntToPSV(&currentEdge, 0);
  745. counterGroupCount = 0;
  746. /* Gather stems into array */
  747. for (hintIndex=0;hintIndex<h->cstr.hintCount;++hintIndex)
  748. {
  749. if ((h->cstr.hintMap[hintIndex].opCode == opCode) && (h->cstr.hintMap[hintIndex].counterGroups & (1 << (groupIndex - 1))))
  750. {
  751. /* Copy stem */
  752. PSVCopy(h, &counterGroup[counterGroupCount].edge,
  753. h->cstr.hintMap[hintIndex].edge);
  754. PSVCopy(h, &counterGroup[counterGroupCount].delta,
  755. h->cstr.hintMap[hintIndex].delta);
  756. counterGroup[counterGroupCount].opCode =
  757. h->cstr.hintMap[hintIndex].opCode;
  758. counterGroup[counterGroupCount].counterGroups =
  759. h->cstr.hintMap[hintIndex].counterGroups;
  760. /* Find trailing edge for next delta. */
  761. PSVAdd(h, &nextEdge, &counterGroup[counterGroupCount].edge,
  762. &counterGroup[counterGroupCount].delta);
  763. PSVCopy(h, &temp, &counterGroup[counterGroupCount].edge);
  764. PSVSubtract(h, &counterGroup[counterGroupCount].edge, &temp, &currentEdge); /* turn leading edge into delta */
  765. PSVCopy(h, &currentEdge, &nextEdge); /* save trailing edge calculate delta for next stem */
  766. ++counterGroupCount;
  767. }
  768. }
  769. /* write out stems backwards */
  770. firstStem = true;
  771. for (argIndex = counterGroupCount-1; argIndex >= 0; --argIndex)
  772. {
  773. if (firstStem)
  774. {
  775. IntToPSV(&temp, 0);
  776. PSVSubtract(h, &currentEdge, &temp, &counterGroup[argIndex].delta);
  777. WriteReversedCounterArg(h, &currentEdge, subr);
  778. PSVAdd(h, &currentEdge, &counterGroup[argIndex].edge, &counterGroup[argIndex].delta);
  779. WriteReversedCounterArg(h, &currentEdge, subr);
  780. firstStem = false;
  781. }
  782. else
  783. {
  784. WriteReversedCounterArg(h, &counterGroup[argIndex].delta, subr);
  785. WriteReversedCounterArg(h, &counterGroup[argIndex].edge, subr);
  786. }
  787. }
  788. }
  789. WriteReversedCounterArg(h, IntToPSV(&currentEdge, groupCount), subr);
  790. }
  791. static void WriteCounters(XCF_Handle h, boolean subr)
  792. {
  793. h->cstr.counterBufferCount = 0; /* Clear counter buffer */
  794. WriteHorVCounters(h, tx_vstem, h->cstr.counterGroupVCount, subr);
  795. WriteHorVCounters(h, tx_hstem, h->cstr.counterGroupHCount, subr);
  796. FlushReversedCounterArgs(h, subr);
  797. }
  798. static void WriteHints(XCF_Handle h, boolean all, boolean subr)
  799. {
  800. Card16 hintIndex;
  801. Card8 currentByte;
  802. Card8 currentBit = 0;
  803. HintValue hstem3Args[3];
  804. HintValue vstem3Args[3];
  805. Card8 hstem3ArgCount = 0;
  806. Card8 vstem3ArgCount = 0;
  807. for (hintIndex=0;hintIndex<h->cstr.hintCount;++hintIndex)
  808. {
  809. if ((!all) && (!currentBit))
  810. {
  811. currentByte = *h->inBuffer.pos++;
  812. currentBit = 0x080;
  813. }
  814. if ((all) || (currentByte & currentBit))
  815. {
  816. /* cstr.languageGroup is set for each charstring in xcf_cff.c/ProcessCharStrings. */
  817. if ((h->cstr.hintMap[hintIndex].counterGroups) && (h->cstr.languageGroup == 0))
  818. {
  819. if (h->cstr.hintMap[hintIndex].opCode == tx_hstem)
  820. {
  821. if (hstem3ArgCount >= 3)
  822. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Too many counters for hstem3", hstem3ArgCount );
  823. hstem3Args[hstem3ArgCount++] = h->cstr.hintMap[hintIndex];
  824. }
  825. else
  826. {
  827. if (vstem3ArgCount >= 3)
  828. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Too many counters for vstem3", vstem3ArgCount );
  829. vstem3Args[vstem3ArgCount++] = h->cstr.hintMap[hintIndex];
  830. }
  831. }
  832. else
  833. {
  834. if (h->cstr.hintMap[hintIndex].opCode == tx_hstem)
  835. HStem(h, h->cstr.hintMap[hintIndex].edge,
  836. h->cstr.hintMap[hintIndex].delta, subr);
  837. else
  838. VStem(h, h->cstr.hintMap[hintIndex].edge,
  839. h->cstr.hintMap[hintIndex].delta, subr);
  840. }
  841. }
  842. currentBit = currentBit>>1;
  843. }
  844. if (hstem3ArgCount == 3)
  845. HStem3(h, hstem3Args[0].edge, hstem3Args[0].delta, hstem3Args[1].edge,
  846. hstem3Args[1].delta, hstem3Args[2].edge, hstem3Args[2].delta, subr);
  847. else if (hstem3ArgCount == 1)
  848. HStem(h, hstem3Args[0].edge, hstem3Args[0].delta, subr);
  849. else if (hstem3ArgCount == 2)
  850. {
  851. HStem(h, hstem3Args[0].edge, hstem3Args[0].delta, subr);
  852. HStem(h, hstem3Args[1].edge, hstem3Args[1].delta, subr);
  853. }
  854. else if (hstem3ArgCount > 3)
  855. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "hstem3 argument count is greater than 3", hstem3ArgCount );
  856. if (vstem3ArgCount == 3)
  857. VStem3(h, vstem3Args[0].edge, vstem3Args[0].delta, vstem3Args[1].edge,
  858. vstem3Args[1].delta, vstem3Args[2].edge, vstem3Args[2].delta, subr);
  859. else if (vstem3ArgCount == 1)
  860. VStem(h, vstem3Args[0].edge, vstem3Args[0].delta, subr);
  861. else if (vstem3ArgCount == 2)
  862. {
  863. VStem(h, vstem3Args[0].edge, vstem3Args[0].delta, subr);
  864. VStem(h, vstem3Args[1].edge, vstem3Args[1].delta, subr);
  865. }
  866. else if (vstem3ArgCount > 3)
  867. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "vstem3 argument count is greater than 3", vstem3ArgCount );
  868. }
  869. static void StateChange(XCF_Handle h,
  870. enum PenStateTransition penTran,
  871. enum HintStateTransition hintTran,
  872. boolean triggerHsbw,
  873. unsigned int expectedArgumentCount,
  874. boolean subr)
  875. {
  876. Card16 stackIndex;
  877. StackValue svx;
  878. switch (penTran)
  879. {
  880. case ToPenUp :
  881. if (h->cstr.pen == PenDown)
  882. ClosePath(h, subr);
  883. h->cstr.pen = PenUp;
  884. break;
  885. case ToPenDown :
  886. if (h->cstr.pen == PenNull)
  887. {
  888. /* Make sure all contours start with a move */
  889. RMoveTo(h, PSTACKVALUE(h, SV0), PSTACKVALUE(h, SV0), subr);
  890. }
  891. h->cstr.pen = PenDown;
  892. break;
  893. case NoPenEffect :
  894. break;
  895. }
  896. switch (hintTran)
  897. {
  898. case ToNotInHints :
  899. if (h->cstr.hints == InitialHints)
  900. {
  901. if ((h->cstr.languageGroup != 0) && (h->cstr.counterGroupCount))
  902. WriteCounters(h, subr);
  903. WriteHints(h, true, subr);
  904. }
  905. h->cstr.hints = NotInHints;
  906. break;
  907. case ToInitialHints :
  908. h->cstr.hints = InitialHints;
  909. break;
  910. case ToSubrHints :
  911. h->cstr.hints = SubrHints;
  912. break;
  913. case NoHintEffect :
  914. break;
  915. }
  916. if (h->cstr.waitingForHsbw && triggerHsbw)
  917. {
  918. h->cstr.waitingForHsbw = false;
  919. if (h->cstr.stackTop <= expectedArgumentCount)
  920. {
  921. /* Currently, subr is true only when processing a transitional
  922. design character. These characters have the hsbw defined in
  923. their charstring and therefore hsbw should not be included
  924. in the subr definition.
  925. */
  926. if (!subr)
  927. {
  928. FixedToPSV(&svx, h->dict.defaultWidthX);
  929. Hsbw(h, PSTACKVALUE(h, SV0), &svx, subr);
  930. }
  931. }
  932. else
  933. {
  934. PSVCopy(h, &svx, h->cstr.stack[0]);
  935. PSVRealAdd(h, &svx, h->dict.nominalWidthX);
  936. Hsbw(h, PSTACKVALUE(h, SV0), &svx, subr);
  937. if (h->cstr.stackTop < 1)
  938. XCF_FATAL_ERROR(h, XCF_StackUnderflow, "Stack Underflow In hsbw ", h->cstr.stackTop );
  939. for (stackIndex = 0; stackIndex<h->cstr.stackTop-1; ++stackIndex)
  940. /* remove first item and shift stack */
  941. PSVCopy(h, h->cstr.stack[stackIndex], h->cstr.stack[stackIndex+1]);
  942. --h->cstr.stackTop;
  943. }
  944. }
  945. }
  946. static void AddToHintMap(XCF_Handle h, Card16 opCode)
  947. {
  948. StackValue y;
  949. StackValue dy;
  950. StackValue temp;
  951. Card16 opIndex;
  952. Card16 index = 0;
  953. IntToPSV(&temp, 0);
  954. for (opIndex=1;opIndex<=h->cstr.stackTop/2;++opIndex)
  955. {
  956. if (h->cstr.hintCount == MAX_HINTS)
  957. XCF_FATAL_ERROR(h, XCF_HintOverflow, "Hint Overflow", h->cstr.hintCount);
  958. PSVAdd(h, &y, &temp, h->cstr.stack[index++]);
  959. PSVCopy(h, &dy, h->cstr.stack[index++]);
  960. PSVCopy(h, h->cstr.hintMap[h->cstr.hintCount].edge, &y);
  961. PSVCopy(h, h->cstr.hintMap[h->cstr.hintCount].delta, &dy);
  962. h->cstr.hintMap[h->cstr.hintCount].opCode = opCode;
  963. h->cstr.hintMap[h->cstr.hintCount].counterGroups = 0;
  964. PSVCopy(h, &temp, &y);
  965. PSVAdd(h, &y, &temp, &dy);
  966. PSVCopy(h, &temp, &y);
  967. ++h->cstr.hintCount;
  968. }
  969. }
  970. void XC_WriteHMoveTo(XCF_Handle h, boolean subr)
  971. {
  972. StateChange(h, ToPenUp, ToNotInHints, true, 1, subr);
  973. RMoveTo(h, h->cstr.stack[0], PSTACKVALUE(h, SV0), subr);
  974. }
  975. void XC_WriteVMoveTo(XCF_Handle h, boolean subr)
  976. {
  977. StateChange(h, ToPenUp, ToNotInHints, true, 1, subr);
  978. RMoveTo(h, PSTACKVALUE(h,SV0), h->cstr.stack[0], subr);
  979. }
  980. void XC_WriteRMoveTo(XCF_Handle h, boolean subr)
  981. {
  982. StateChange(h, ToPenUp, ToNotInHints, true, 2, subr);
  983. RMoveTo(h, h->cstr.stack[0], h->cstr.stack[1], subr);
  984. }
  985. void XC_WriteRLineTo(XCF_Handle h, boolean subr)
  986. {
  987. Card16 stackIndex = 0;
  988. Card16 opIndex;
  989. Card16 repeatCount = h->cstr.stackTop/2;
  990. StateChange(h, ToPenDown, ToNotInHints, false, 0, subr);
  991. for (opIndex=1;opIndex<=repeatCount;++opIndex)
  992. {
  993. RLineTo(h, h->cstr.stack[stackIndex], h->cstr.stack[stackIndex+1], subr);
  994. stackIndex += 2;
  995. }
  996. }
  997. void XC_WriteHLineToAndVLineTo(XCF_Handle h, boolean hLine, boolean subr)
  998. {
  999. Card16 opIndex;
  1000. StateChange(h, ToPenDown, ToNotInHints, false, 0, subr);
  1001. for (opIndex=1;opIndex<=h->cstr.stackTop;++opIndex)
  1002. {
  1003. if (hLine)
  1004. RLineTo(h, h->cstr.stack[opIndex-1], PSTACKVALUE(h, SV0), subr);
  1005. else
  1006. RLineTo(h, PSTACKVALUE(h, SV0), h->cstr.stack[opIndex-1], subr);
  1007. hLine = !hLine;
  1008. }
  1009. }
  1010. static void WriteSingleRRCurveTo(XCF_Handle h,
  1011. PStackValue pdx1,
  1012. PStackValue pdy1,
  1013. PStackValue pdx2,
  1014. PStackValue pdy2,
  1015. PStackValue pdx3,
  1016. PStackValue pdy3,
  1017. boolean subr)
  1018. {
  1019. StateChange(h, ToPenDown, ToNotInHints, false, 0, subr);
  1020. RRCurveTo(h, pdx1, pdy1, pdx2, pdy2, pdx3, pdy3, subr);
  1021. }
  1022. void XC_WriteRRCurveTo(XCF_Handle h, boolean subr)
  1023. {
  1024. Card16 stackIndex = 0;
  1025. Card16 opIndex;
  1026. Card16 repeatCount = h->cstr.stackTop/6;
  1027. for (opIndex=1;opIndex<=repeatCount;++opIndex)
  1028. {
  1029. WriteSingleRRCurveTo(h,
  1030. h->cstr.stack[stackIndex],
  1031. h->cstr.stack[stackIndex+1],
  1032. h->cstr.stack[stackIndex+2],
  1033. h->cstr.stack[stackIndex+3],
  1034. h->cstr.stack[stackIndex+4],
  1035. h->cstr.stack[stackIndex+5],
  1036. subr);
  1037. stackIndex+=6;
  1038. }
  1039. }
  1040. void XC_WriteEndChar(XCF_Handle h, boolean subr)
  1041. {
  1042. if (h->cstr.stackTop >= 4)
  1043. {
  1044. StateChange(h, NoPenEffect, NoHintEffect, true, 4, subr);
  1045. Seac(h,
  1046. PSTACKVALUE(h, SV0),
  1047. h->cstr.stack[0],
  1048. h->cstr.stack[1],
  1049. h->cstr.stack[2],
  1050. h->cstr.stack[3],
  1051. subr);
  1052. }
  1053. else
  1054. {
  1055. StateChange(h, ToPenUp, ToNotInHints, true, 0, subr);
  1056. if (h->cstr.stackTop == 0)
  1057. EndChar(h, subr);
  1058. else
  1059. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Arguments Left On Stack At endchar ", h->cstr.stackTop );
  1060. }
  1061. }
  1062. void XC_WriteRCurveLine(XCF_Handle h, boolean subr)
  1063. {
  1064. Card16 stackIndex = 0;
  1065. while (stackIndex + 2 < h->cstr.stackTop)
  1066. {
  1067. WriteSingleRRCurveTo(h,
  1068. h->cstr.stack[stackIndex],
  1069. h->cstr.stack[stackIndex+1],
  1070. h->cstr.stack[stackIndex+2],
  1071. h->cstr.stack[stackIndex+3],
  1072. h->cstr.stack[stackIndex+4],
  1073. h->cstr.stack[stackIndex+5],
  1074. subr);
  1075. stackIndex+=6;
  1076. }
  1077. if (stackIndex + 2 <= h->cstr.stackTop)
  1078. {
  1079. RLineTo(h, h->cstr.stack[stackIndex], h->cstr.stack[stackIndex+1], subr);
  1080. }
  1081. }
  1082. void XC_WriteRLineCurve(XCF_Handle h, boolean subr)
  1083. {
  1084. Card16 stackIndex = 0;
  1085. StateChange(h, ToPenDown, ToNotInHints, false, 0, subr);
  1086. while (stackIndex + 6 < h->cstr.stackTop)
  1087. {
  1088. RLineTo(h, h->cstr.stack[stackIndex], h->cstr.stack[stackIndex+1], subr);
  1089. stackIndex += 2;
  1090. }
  1091. if (stackIndex + 6 <= h->cstr.stackTop)
  1092. WriteSingleRRCurveTo(h,
  1093. h->cstr.stack[stackIndex],
  1094. h->cstr.stack[stackIndex+1],
  1095. h->cstr.stack[stackIndex+2],
  1096. h->cstr.stack[stackIndex+3],
  1097. h->cstr.stack[stackIndex+4],
  1098. h->cstr.stack[stackIndex+5],
  1099. subr);
  1100. }
  1101. void XC_WriteVVCurveTo(XCF_Handle h, boolean subr)
  1102. {
  1103. Card16 stackIndex = 0;
  1104. if (h->cstr.stackTop & 0x01) /* If odd number of arguments */
  1105. {
  1106. WriteSingleRRCurveTo(h,
  1107. h->cstr.stack[0],
  1108. h->cstr.stack[1],
  1109. h->cstr.stack[2],
  1110. h->cstr.stack[3],
  1111. PSTACKVALUE(h, SV0),
  1112. h->cstr.stack[4],
  1113. subr);
  1114. stackIndex = 5;
  1115. }
  1116. while (stackIndex + 4 <= h->cstr.stackTop)
  1117. {
  1118. WriteSingleRRCurveTo(h,
  1119. PSTACKVALUE(h, SV0),
  1120. h->cstr.stack[stackIndex],
  1121. h->cstr.stack[stackIndex+1],
  1122. h->cstr.stack[stackIndex+2],
  1123. PSTACKVALUE(h, SV0),
  1124. h->cstr.stack[stackIndex+3],
  1125. subr);
  1126. stackIndex+=4;
  1127. }
  1128. }
  1129. void XC_WriteHHCurveTo(XCF_Handle h, boolean subr)
  1130. {
  1131. Card16 stackIndex = 0;
  1132. if (h->cstr.stackTop & 0x01) /* If odd number of arguments */
  1133. {
  1134. WriteSingleRRCurveTo(h,
  1135. h->cstr.stack[1],
  1136. h->cstr.stack[0],
  1137. h->cstr.stack[2],
  1138. h->cstr.stack[3],
  1139. h->cstr.stack[4],
  1140. PSTACKVALUE(h, SV0),
  1141. subr);
  1142. stackIndex = 5;
  1143. }
  1144. while (stackIndex + 4 <= h->cstr.stackTop)
  1145. {
  1146. WriteSingleRRCurveTo(h,
  1147. h->cstr.stack[stackIndex],
  1148. PSTACKVALUE(h, SV0),
  1149. h->cstr.stack[stackIndex+1],
  1150. h->cstr.stack[stackIndex+2],
  1151. h->cstr.stack[stackIndex+3],
  1152. PSTACKVALUE(h, SV0),
  1153. subr);
  1154. stackIndex+=4;
  1155. }
  1156. }
  1157. void XC_WriteHVorVHCurveTo(XCF_Handle h, boolean hvCurve, boolean subr)
  1158. {
  1159. Card16 stackIndex = 0;
  1160. while (stackIndex + 4 <= h->cstr.stackTop)
  1161. {
  1162. if (stackIndex + 5 == h->cstr.stackTop)
  1163. {
  1164. if (hvCurve)
  1165. WriteSingleRRCurveTo(h,
  1166. h->cstr.stack[stackIndex],
  1167. PSTACKVALUE(h, SV0),
  1168. h->cstr.stack[stackIndex+1],
  1169. h->cstr.stack[stackIndex+2],
  1170. h->cstr.stack[stackIndex+4],
  1171. h->cstr.stack[stackIndex+3],
  1172. subr);
  1173. else
  1174. WriteSingleRRCurveTo(h,
  1175. PSTACKVALUE(h, SV0),
  1176. h->cstr.stack[stackIndex],
  1177. h->cstr.stack[stackIndex+1],
  1178. h->cstr.stack[stackIndex+2],
  1179. h->cstr.stack[stackIndex+3],
  1180. h->cstr.stack[stackIndex+4],
  1181. subr);
  1182. stackIndex+=5;
  1183. }
  1184. else
  1185. {
  1186. StateChange(h, ToPenDown, ToNotInHints, false, 0, subr);
  1187. if (hvCurve)
  1188. {
  1189. RRCurveTo(h,
  1190. h->cstr.stack[stackIndex],
  1191. PSTACKVALUE(h, SV0),
  1192. h->cstr.stack[stackIndex+1],
  1193. h->cstr.stack[stackIndex+2],
  1194. PSTACKVALUE(h, SV0),
  1195. h->cstr.stack[stackIndex+3],
  1196. subr);
  1197. }
  1198. else
  1199. {
  1200. RRCurveTo(h,
  1201. PSTACKVALUE(h, SV0),
  1202. h->cstr.stack[stackIndex],
  1203. h->cstr.stack[stackIndex+1],
  1204. h->cstr.stack[stackIndex+2],
  1205. h->cstr.stack[stackIndex+3],
  1206. PSTACKVALUE(h, SV0),
  1207. subr);
  1208. }
  1209. hvCurve = !hvCurve;
  1210. stackIndex+=4;
  1211. }
  1212. }
  1213. }
  1214. static Fixed AbsoluteValue(Fixed f)
  1215. {
  1216. if (f < 0)
  1217. return -f;
  1218. else
  1219. return f;
  1220. }
  1221. static void WriteExpandedFlexCurveTo(XCF_Handle h,
  1222. PStackValue pdx2,
  1223. PStackValue pdy2,
  1224. PStackValue pdx3,
  1225. PStackValue pdy3,
  1226. PStackValue pdx4,
  1227. PStackValue pdy4,
  1228. PStackValue pdx5,
  1229. PStackValue pdy5,
  1230. PStackValue pdx6,
  1231. PStackValue pdy6,
  1232. PStackValue pdx7,
  1233. PStackValue pdy7,
  1234. PStackValue pflexHeight,
  1235. boolean subr)
  1236. {
  1237. StackValue endpointX;
  1238. StackValue endpointY;
  1239. StackValue refX, refY; /* reference point */
  1240. StackValue dx1, dy1; /* first two arguments passed to flex */
  1241. StackValue temp, temp1;
  1242. PSVAdd7(h,&endpointX,h->cstr.x,pdx2,pdx3,pdx4,pdx5,pdx6,pdx7);
  1243. PSVAdd7(h,&endpointY,h->cstr.y,pdy2,pdy3,pdy4,pdy5,pdy6,pdy7);
  1244. h->cstr.flexUsed = true;
  1245. if (AbsoluteValue(endpointX.value[0] - h->cstr.x->value[0]) > AbsoluteValue(endpointY.value[0] - h->cstr.y->value[0])) /* horizontal */
  1246. {
  1247. PSVAdd4(h,&refX,h->cstr.x,pdx2,pdx3,pdx4);
  1248. PSVAdd7(h,&refY,h->cstr.y,pdy2,pdy3,pdy4,pdy5,pdy6,pdy7);
  1249. }
  1250. else
  1251. {
  1252. PSVAdd7(h,&refX,h->cstr.x,pdx2,pdx3,pdx4,pdx5,pdx6,pdx7);
  1253. PSVAdd4(h,&refY,h->cstr.y,pdy2,pdy3,pdy4);
  1254. }
  1255. PSVSubtract(h, &dx1, &refX, h->cstr.x);
  1256. PSVSubtract(h, &dy1, &refY, h->cstr.y);
  1257. PSVSubtract(h, &temp, h->cstr.x, &refX);
  1258. PSVCopy(h, &temp1, pdx2);
  1259. PStackValueAdd(h, pdx2, &temp1, &temp);
  1260. PSVSubtract(h, &temp, h->cstr.y, &refY);
  1261. PSVCopy(h, &temp1, pdy2);
  1262. PStackValueAdd(h, pdy2, &temp1, &temp);
  1263. StateChange(h, ToPenDown, ToNotInHints, false, 0, subr);
  1264. Flex(h, &dx1, &dy1, pdx2, pdy2, pdx3, pdy3, pdx4, pdy4, pdx5, pdy5, pdx6,
  1265. pdy6, pdx7, pdy7, pflexHeight, &endpointX, &endpointY, subr);
  1266. }
  1267. void XC_WriteFlex(XCF_Handle h, boolean subr)
  1268. {
  1269. if (h->cstr.stackTop == 13)
  1270. {
  1271. WriteExpandedFlexCurveTo(h,
  1272. h->cstr.stack[0],
  1273. h->cstr.stack[1],
  1274. h->cstr.stack[2],
  1275. h->cstr.stack[3],
  1276. h->cstr.stack[4],
  1277. h->cstr.stack[5],
  1278. h->cstr.stack[6],
  1279. h->cstr.stack[7],
  1280. h->cstr.stack[8],
  1281. h->cstr.stack[9],
  1282. h->cstr.stack[10],
  1283. h->cstr.stack[11],
  1284. h->cstr.stack[12],
  1285. subr);
  1286. }
  1287. else
  1288. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Incorrect Argument Count For flex ", h->cstr.stackTop );
  1289. }
  1290. void XC_WriteFlex1(XCF_Handle h, boolean subr)
  1291. {
  1292. StackValue lastControlPointX, lastControlPointY;
  1293. StackValue dx, dy;
  1294. StackValue lastCtrlDx, lastCtrlDy;
  1295. if (h->cstr.stackTop != 11)
  1296. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Incorrect Argument Count For flex1 ", h->cstr.stackTop );
  1297. PSVAdd5(h,&lastCtrlDx,h->cstr.stack[0],h->cstr.stack[2],h->cstr.stack[4],h->cstr.stack[6],h->cstr.stack[8]);
  1298. PSVAdd5(h,&lastCtrlDy,h->cstr.stack[1],h->cstr.stack[3],h->cstr.stack[5],h->cstr.stack[7],h->cstr.stack[9]);
  1299. PSVAdd(h,&lastControlPointX,h->cstr.x, &lastCtrlDx);
  1300. PSVAdd(h,&lastControlPointY, h->cstr.y, &lastCtrlDy);
  1301. if (AbsoluteValue(lastCtrlDx.value[0]) > AbsoluteValue(lastCtrlDy.value[0]))
  1302. {
  1303. PSVCopy(h, &dx, h->cstr.stack[10]);
  1304. PSVSubtract(h, &dy, PSTACKVALUE(h, SV0), &lastCtrlDy);
  1305. }
  1306. else
  1307. {
  1308. PSVSubtract(h, &dx, PSTACKVALUE(h, SV0), &lastCtrlDx);
  1309. PSVCopy(h, &dy, h->cstr.stack[10]);
  1310. }
  1311. WriteExpandedFlexCurveTo(h,
  1312. h->cstr.stack[0],
  1313. h->cstr.stack[1],
  1314. h->cstr.stack[2],
  1315. h->cstr.stack[3],
  1316. h->cstr.stack[4],
  1317. h->cstr.stack[5],
  1318. h->cstr.stack[6],
  1319. h->cstr.stack[7],
  1320. h->cstr.stack[8],
  1321. h->cstr.stack[9],
  1322. &dx,
  1323. &dy,
  1324. PSTACKVALUE(h, SV50),
  1325. subr);
  1326. }
  1327. void XC_WriteHFlex(XCF_Handle h, boolean subr)
  1328. {
  1329. if (h->cstr.stackTop == 7)
  1330. {
  1331. PSVSubtract(h, PSTACKVALUE(h, SVTEMP), PSTACKVALUE(h, SV0),
  1332. h->cstr.stack[2]);
  1333. WriteExpandedFlexCurveTo(h,
  1334. h->cstr.stack[0],
  1335. PSTACKVALUE(h, SV0),
  1336. h->cstr.stack[1],
  1337. h->cstr.stack[2],
  1338. h->cstr.stack[3],
  1339. PSTACKVALUE(h, SV0),
  1340. h->cstr.stack[4],
  1341. PSTACKVALUE(h, SV0),
  1342. h->cstr.stack[5],
  1343. PSTACKVALUE(h, SVTEMP),
  1344. h->cstr.stack[6],
  1345. PSTACKVALUE(h, SV0),
  1346. PSTACKVALUE(h, SV50),
  1347. subr);
  1348. }
  1349. else
  1350. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Incorrect Argument Count For hflex ", h->cstr.stackTop );
  1351. }
  1352. void XC_WriteHFlex1(XCF_Handle h, boolean subr)
  1353. {
  1354. StackValue temp, temp1;
  1355. if (h->cstr.stackTop == 9)
  1356. {
  1357. PSVSubtract(h, &temp, PSTACKVALUE(h, SV0), h->cstr.stack[1]);
  1358. PSVSubtract(h, &temp1, &temp, h->cstr.stack[3]);
  1359. PSVSubtract(h, PSTACKVALUE(h, SVTEMP), &temp1, h->cstr.stack[7]);
  1360. WriteExpandedFlexCurveTo(h,
  1361. h->cstr.stack[0],
  1362. h->cstr.stack[1],
  1363. h->cstr.stack[2],
  1364. h->cstr.stack[3],
  1365. h->cstr.stack[4],
  1366. PSTACKVALUE(h, SV0),
  1367. h->cstr.stack[5],
  1368. PSTACKVALUE(h, SV0),
  1369. h->cstr.stack[6],
  1370. h->cstr.stack[7],
  1371. h->cstr.stack[8],
  1372. PSTACKVALUE(h, SVTEMP),
  1373. PSTACKVALUE(h, SV50),
  1374. subr);
  1375. }
  1376. else
  1377. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Incorrect Argument Count For hflex1 ", h->cstr.stackTop );
  1378. }
  1379. void XC_WriteDotSection(XCF_Handle h, boolean subr)
  1380. {
  1381. if (h->cstr.stackTop != 0)
  1382. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Arguments On Stack For dotsection ", h->cstr.stackTop );
  1383. StateChange(h, ToPenUp, ToNotInHints, false, 0, subr);
  1384. DotSection(h, subr);
  1385. }
  1386. void XC_WriteVStem(XCF_Handle h, boolean subr)
  1387. {
  1388. StateChange(h, NoPenEffect, NoHintEffect, true,
  1389. h->cstr.stackTop-(h->cstr.stackTop & 0x01), subr);
  1390. AddToHintMap(h, tx_vstem);
  1391. }
  1392. void XC_WriteHStem(XCF_Handle h, boolean subr)
  1393. {
  1394. StateChange(h, NoPenEffect, NoHintEffect, true,
  1395. h->cstr.stackTop-(h->cstr.stackTop & 0x01), subr);
  1396. AddToHintMap(h, tx_hstem);
  1397. }
  1398. void XC_WriteHintMask(XCF_Handle h, boolean subr)
  1399. {
  1400. if (h->cstr.stackTop > 0) /* If stack is not empty then implied VStem */
  1401. XC_WriteVStem(h, subr);
  1402. if ((h->cstr.hints == InitialHints) && (h->cstr.languageGroup != 0) && (h->cstr.counterGroupCount))
  1403. WriteCounters(h, subr);
  1404. if (h->cstr.waitingForFirstHint) /* In case inital hints aren't at beginning of char string */
  1405. h->cstr.hints = InitialHints;
  1406. else
  1407. {
  1408. h->cstr.hints = SubrHints;
  1409. StartHintSub(h, subr);
  1410. }
  1411. WriteHints(h, false, subr);
  1412. h->cstr.hints = SubrHints;
  1413. }
  1414. void XC_SetCounters(XCF_Handle h, boolean subr)
  1415. {
  1416. Card16 hintIndex;
  1417. Card8 currentByte;
  1418. Card8 currentBit = 0;
  1419. if (h->cstr.stackTop > 0) /* If stack is not empty then implied VStem */
  1420. XC_WriteVStem(h, subr);
  1421. for (hintIndex=0;hintIndex<h->cstr.hintCount;++hintIndex)
  1422. {
  1423. if (!currentBit)
  1424. {
  1425. currentByte = *h->inBuffer.pos++;
  1426. currentBit = 0x080;
  1427. }
  1428. if (currentByte & currentBit)
  1429. {
  1430. if (h->cstr.counterGroupCount >= MAX_COUNTER_GROUPS)
  1431. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Too many counter groups ", h->cstr.counterGroupCount );
  1432. h->cstr.hintMap[hintIndex].counterGroups |= 1 << h->cstr.counterGroupCount;
  1433. if (h->cstr.hintMap[hintIndex].opCode == tx_hstem)
  1434. h->cstr.counterGroupHCount = h->cstr.counterGroupCount+1;
  1435. else /* tx_vstem */
  1436. h->cstr.counterGroupVCount = h->cstr.counterGroupCount+1;
  1437. }
  1438. currentBit = currentBit>>1;
  1439. }
  1440. ++h->cstr.counterGroupCount;
  1441. }
  1442. #if JUDY
  1443. static void Blend(XCF_Handle h)
  1444. {
  1445. CardX numberOfValues;
  1446. CardX numberOfBlends;
  1447. CardX stackIndex;
  1448. CardX blendStackIndex;
  1449. CardX i,j;
  1450. if (h->cstr.stackTop == 0)
  1451. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Stack empty during blend operation ", h->cstr.stackTop );
  1452. --h->cstr.stackTop;
  1453. numberOfBlends = h->cstr.stack[h->cstr.stackTop].value[0];
  1454. numberOfValues = h->dict.numberOfMasters * numberOfBlends;
  1455. if (h->cstr.stackTop < numberOfValues)
  1456. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Stack underflow during blend operation ", h->cstr.stackTop );
  1457. stackIndex = h->cstr.stackTop - numberOfValues;
  1458. blendStackIndex = stackIndex;
  1459. for (i=0; i<numberOfBlends; ++i)
  1460. {
  1461. for (j=0; j< (CardX)h->dict.numberOfMasters; ++j)
  1462. h->cstr.stack[blendStackIndex].value[j] = h->cstr.stack[stackIndex++].value[0];
  1463. h->cstr.stack[blendStackIndex].blend = true;
  1464. ++blendStackIndex;
  1465. }
  1466. h->cstr.stackTop = blendStackIndex;
  1467. }
  1468. #endif /* JUDY */
  1469. static void Translate(XCF_Handle h, boolean subr)
  1470. {
  1471. switch (h->cstr.opCode)
  1472. {
  1473. case tx_hstem :
  1474. case t2_hstemhm : XC_WriteHStem(h, subr);
  1475. break;
  1476. case tx_vstem :
  1477. case t2_vstemhm : XC_WriteVStem(h, subr);
  1478. break;
  1479. case tx_hmoveto : XC_WriteHMoveTo(h, subr);
  1480. break;
  1481. case tx_vmoveto : XC_WriteVMoveTo(h, subr);
  1482. break;
  1483. case tx_rlineto : XC_WriteRLineTo(h, subr);
  1484. break;
  1485. case tx_hlineto : XC_WriteHLineToAndVLineTo(h, true, subr);
  1486. break;
  1487. case tx_vlineto : XC_WriteHLineToAndVLineTo(h, false, subr);
  1488. break;
  1489. case tx_rrcurveto : XC_WriteRRCurveTo(h, subr);
  1490. break;
  1491. case tx_endchar : XC_WriteEndChar(h, subr);
  1492. break;
  1493. case tx_rmoveto : XC_WriteRMoveTo(h, subr);
  1494. break;
  1495. case t2_rcurveline : XC_WriteRCurveLine(h, subr);
  1496. break;
  1497. case t2_rlinecurve : XC_WriteRLineCurve(h, subr);
  1498. break;
  1499. case t2_vvcurveto : XC_WriteVVCurveTo(h, subr);
  1500. break;
  1501. case t2_hhcurveto : XC_WriteHHCurveTo(h, subr);
  1502. break;
  1503. case tx_vhcurveto : XC_WriteHVorVHCurveTo(h, false, subr);
  1504. break;
  1505. case tx_hvcurveto : XC_WriteHVorVHCurveTo(h, true, subr);
  1506. break;
  1507. case tx_dotsection : XC_WriteDotSection(h, subr);
  1508. break;
  1509. case t2_flex : XC_WriteFlex(h, subr);
  1510. break;
  1511. case t2_flex1 : XC_WriteFlex1(h, subr);
  1512. break;
  1513. case t2_hflex : XC_WriteHFlex(h, subr);
  1514. break;
  1515. case t2_hflex1 : XC_WriteHFlex1(h, subr);
  1516. break;
  1517. case t2_hintmask : XC_WriteHintMask(h, subr);
  1518. break;
  1519. case t2_cntrmask : XC_SetCounters(h, subr);
  1520. break;
  1521. /* The following opcodes can be found in certain mmfonts. */
  1522. case tx_add:
  1523. case tx_sub:
  1524. case tx_load:
  1525. case tx_get:
  1526. case tx_put:
  1527. case tx_store:
  1528. case tx_ifelse:
  1529. {
  1530. Card16 j;
  1531. for (j = 0; j < h->cstr.stackTop; j++)
  1532. XC_WriteT1PStackValue(h, h->cstr.stack[j], subr);
  1533. XC_WriteT1OpCode(h, h->cstr.opCode, subr);
  1534. }
  1535. break;
  1536. default :
  1537. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Unrecognized Operator",
  1538. h->cstr.opCode );
  1539. break;
  1540. }
  1541. h->cstr.stackTop = 0;
  1542. }
  1543. static void CopyArgumentsToStack(XCF_Handle h, Card8 PTR_PREFIX *pArgList, IntX argCount, boolean blend)
  1544. {
  1545. IntX stackIndex;
  1546. IntX blendArg;
  1547. IntX deltaIndex;
  1548. IntX i;
  1549. IntX j;
  1550. for (stackIndex= (IntX)h->cstr.stackTop; stackIndex < (IntX)h->cstr.stackTop + argCount; ++stackIndex)
  1551. {
  1552. h->cstr.stack[stackIndex]->value[0] = XCF_ArgPtrToFixed(h, &pArgList, false);
  1553. h->cstr.stack[stackIndex]->blend = false;
  1554. }
  1555. h->cstr.stackTop += (Card16)argCount;
  1556. if (blend)
  1557. {
  1558. --h->cstr.stackTop;
  1559. blendArg = FIXED_TO_INT(h->cstr.stack[h->cstr.stackTop]->value[0]);
  1560. stackIndex = h->cstr.stackTop - (blendArg * h->dict.numberOfMasters);
  1561. deltaIndex = stackIndex + blendArg;
  1562. for (i=stackIndex;i<stackIndex+blendArg;++i)
  1563. {
  1564. h->cstr.stack[i]->blend = true;
  1565. for (j=1;j<h->dict.numberOfMasters;++j)
  1566. h->cstr.stack[i]->value[j] = h->cstr.stack[deltaIndex++]->value[0] + h->cstr.stack[i]->value[0];
  1567. }
  1568. h->cstr.stackTop = stackIndex + blendArg;
  1569. }
  1570. }
  1571. static void ProcessCharstr(XCF_Handle h, unsigned int depth, boolean PTR_PREFIX
  1572. *endcharFound, boolean subr)
  1573. {
  1574. Card8 PTR_PREFIX *argList;
  1575. IntX argCount;
  1576. if (depth == 0)
  1577. {
  1578. h->cstr.stackTop = 0;
  1579. h->cstr.pen = PenNull;
  1580. }
  1581. if (depth > TX_MAX_CALL_STACK)
  1582. XCF_FATAL_ERROR(h, XCF_SubrDepthOverflow, "Maximum Subr Depth Exceeded", depth );
  1583. while (h->inBuffer.pos < h->inBuffer.end)
  1584. {
  1585. argList = h->inBuffer.pos;
  1586. argCount = XCF_FindNextOperator(h, &h->cstr.opCode, false);
  1587. if ((h->cstr.stackTop + argCount) > MAX_OPERAND_STACK)
  1588. XCF_FATAL_ERROR(h, XCF_StackOverflow, "Charstring Stack Overflow", h->cstr.stackTop + argCount );
  1589. CopyArgumentsToStack(h, argList, argCount, (h->cstr.opCode == t2_blend));
  1590. switch (h->cstr.opCode)
  1591. {
  1592. case tx_return:
  1593. if (depth == 0)
  1594. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Subr Return Encountered While Not In Subr", tx_return );
  1595. return;
  1596. break;
  1597. case tx_callsubr:
  1598. /* Make sure the stack isn't empty then flatten the subroutine. */
  1599. if (h->cstr.stackTop == 0)
  1600. XCF_FATAL_ERROR(h, XCF_StackUnderflow, "No subr number associated with subr call", 0);
  1601. else /* flatten the subroutine */
  1602. FlattenSubr(h, depth + 1, endcharFound, true);
  1603. break;
  1604. case t2_callgsubr:
  1605. if (h->cstr.stackTop == 0)
  1606. XCF_FATAL_ERROR(h, XCF_StackUnderflow, "No subr number associated with subr call", 0);
  1607. else
  1608. FlattenSubr(h, depth + 1, endcharFound, false);
  1609. break;
  1610. case t2_blend : /* Do Nothing and loop again */
  1611. break;
  1612. default:
  1613. Translate(h, subr);
  1614. break;
  1615. } /* end case */
  1616. if (h->cstr.opCode == tx_endchar)
  1617. {
  1618. *endcharFound = true;
  1619. return;
  1620. }
  1621. } /* end while */
  1622. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Charstring Not Terminated With endchar", 0 );
  1623. }
  1624. /* This is called recursively from ProcessCharstr to flatten subroutines. */
  1625. static void FlattenSubr(XCF_Handle h, unsigned int depth, boolean PTR_PREFIX
  1626. *endcharFound, boolean localSubr)
  1627. {
  1628. Card16 subrNum;
  1629. Card16 pos;
  1630. InBufferStruct inBuffer;
  1631. if ((localSubr && h->dict.localSubrs.count == 0) ||
  1632. (!localSubr && h->fontSet.globalSubrs.count == 0))
  1633. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "No subrs defined but subr called in charstring", 0);
  1634. /* Save value of inBuffer. */
  1635. h->callbacks.memcpy(&inBuffer, (Card8 PTR_PREFIX *)&h->inBuffer, (Card16)
  1636. sizeof(InBufferStruct));
  1637. pos = (Card16)(h->inBuffer.pos - h->inBuffer.start); /* position relative to start */
  1638. subrNum = FIXED_TO_INT(h->cstr.stack[h->cstr.stackTop-1]->value[0]) + (localSubr ? h->dict.localSubrBias : h->fontSet.globalSubrBias);
  1639. XCF_LookUpTableEntry(h, (localSubr ? &h->dict.localSubrs : &h->fontSet.globalSubrs), subrNum);
  1640. --h->cstr.stackTop; /* Remove subr number from stack. */
  1641. ProcessCharstr(h, depth, endcharFound, false);
  1642. /* Restore value of inBuffer. */
  1643. XCF_ReadBlock(h, inBuffer.blockOffset, inBuffer.blockLength);
  1644. h->inBuffer.pos = h->inBuffer.start + pos;
  1645. }
  1646. void XC_SetUpStandardSubrs(XCF_Handle h)
  1647. {
  1648. ShortStackValue temp;
  1649. /* dup 0 ## -| { 3 0 callother pop pop setcurrentpoint return } */
  1650. NewT1Subr(h);
  1651. XC_WriteT1PStackValue(h, IntToPSV(&temp, 3), true);
  1652. XC_WriteT1PStackValue(h, PSTACKVALUE(h, SV0), true);
  1653. XC_WriteT1OpCode(h, t1_callother, true);
  1654. XC_WriteT1OpCode(h, t1_pop, true);
  1655. XC_WriteT1OpCode(h, t1_pop, true);
  1656. XC_WriteT1OpCode(h, t1_setcurrentpt, true);
  1657. /* dup 1 ## -| { 0 1 callother return } | */
  1658. NewT1Subr(h);
  1659. XC_WriteT1PStackValue(h, PSTACKVALUE(h, SV0), true);
  1660. XC_WriteT1PStackValue(h, IntToPSV(&temp, 1), true);
  1661. XC_WriteT1OpCode(h, t1_callother, true);
  1662. /* dup 2 ## -| { 0 2 callother return } | */
  1663. NewT1Subr(h);
  1664. XC_WriteT1PStackValue(h, PSTACKVALUE(h, SV0), true);
  1665. XC_WriteT1PStackValue(h, IntToPSV(&temp, 2), true);
  1666. XC_WriteT1OpCode(h, t1_callother, true);
  1667. /* dup 3 ## -| { return } | */
  1668. NewT1Subr(h);
  1669. /* dup 4 ## -| { <<3>> 1 3 callother pop callsubr return } */
  1670. NewT1Subr(h);
  1671. if (CIDFONT || h->options.subrFlatten)
  1672. XC_WriteT1PStackValue(h, IntToPSV(&temp, 3), true);
  1673. XC_WriteT1PStackValue(h, IntToPSV(&temp, 1), true);
  1674. XC_WriteT1PStackValue(h, IntToPSV(&temp, 3), true);
  1675. XC_WriteT1OpCode(h, t1_callother, true);
  1676. XC_WriteT1OpCode(h, t1_pop, true);
  1677. XC_WriteT1OpCode(h, tx_callsubr, true);
  1678. /* dup 5 ## -| { return } | */
  1679. NewT1Subr(h);
  1680. /* Last subr in a CIDFont is 4; the call to NewT1Subr above closes out the DA. */
  1681. if (CIDFONT || !h->dict.numberOfMasters)
  1682. return;
  1683. /* dup 6 ## -| { 2 14 callother pop return } | */
  1684. NewT1Subr(h);
  1685. XC_WriteT1PStackValue(h, IntToPSV(&temp, h->dict.numberOfMasters), true);
  1686. XC_WriteT1PStackValue(h, IntToPSV(&temp, 14), true);
  1687. XC_WriteT1OpCode(h, t1_callother, true);
  1688. XC_WriteT1OpCode(h, t1_pop, true);
  1689. }
  1690. static void InitStackVal(XCF_Handle h)
  1691. {
  1692. Card16 i;
  1693. Card16 svSize;
  1694. Card8 *p;
  1695. Card16 offset;
  1696. NewStackValues(h, (void PTR_PREFIX * PTR_PREFIX *)&p, NUM_STACK_VALUES, &svSize);
  1697. h->cstr.pstackVal = (PStackValue)p;
  1698. offset = 0;
  1699. h->cstr.x = NEXTSTACKVALUE(p, offset, svSize);
  1700. h->cstr.y = NEXTSTACKVALUE(p, offset, svSize);
  1701. for (i=0; i < MAX_OPERAND_STACK; i++)
  1702. {
  1703. h->cstr.stack[i] = NEXTSTACKVALUE(p, offset, svSize);
  1704. }
  1705. for (i=0; i < MAX_COUNTER_BUFFER; i++)
  1706. {
  1707. h->cstr.counterBuffer[i] = NEXTSTACKVALUE(p, offset, svSize);
  1708. }
  1709. for (i=0; i < MAX_HINTS; i++)
  1710. {
  1711. h->cstr.hintMap[i].delta = NEXTSTACKVALUE(p, offset, svSize);
  1712. h->cstr.hintMap[i].edge = NEXTSTACKVALUE(p, offset, svSize);
  1713. }
  1714. for (i=0; i < MAX_SVTEMP; i++)
  1715. {
  1716. h->cstr.psvTemp[i] = NEXTSTACKVALUE(p, offset, svSize);
  1717. }
  1718. IntToPSV(PSTACKVALUE(h, SV0), 0);
  1719. IntToPSV(PSTACKVALUE(h, SV50), 50);
  1720. }
  1721. void XC_Init(XCF_Handle h)
  1722. {
  1723. h->cstr.flexUsed = false;
  1724. InitStackVal(h);
  1725. h->cstr.pCounterVal = 0;
  1726. if (CIDFONT)
  1727. h->type1.cid.charDataCount = 0;
  1728. }
  1729. static void InitCharstr(XCF_Handle h)
  1730. {
  1731. h->cstr.pen = PenNull;
  1732. h->cstr.hints = InitialHints;
  1733. h->cstr.waitingForHsbw = true;
  1734. h->cstr.waitingForFirstHint = true;
  1735. h->cstr.stackTop = 0;
  1736. h->cstr.hintCount = 0;
  1737. h->cstr.counterGroupCount = 0;
  1738. h->cstr.counterGroupVCount = 0;
  1739. h->cstr.counterGroupHCount = 0;
  1740. IntToPSV(h->cstr.x, 0);
  1741. IntToPSV(h->cstr.y, 0);
  1742. h->cstr.subrFlatten = h->options.subrFlatten;
  1743. /* Initialize the seac characters */
  1744. h->cstr.baseSeac = 0;
  1745. h->cstr.accentSeac = 0;
  1746. }
  1747. void XC_ProcessCharstr(XCF_Handle h)
  1748. {
  1749. boolean endCharFound = false;
  1750. InitCharstr(h);
  1751. if (!CIDFONT && h->options.subrFlatten)
  1752. FreeT1CharStr(h);
  1753. else
  1754. NewT1CharStr(h);
  1755. #ifdef T13
  1756. if (h->dict.fontType == 13)
  1757. XT13_ProcessCharstr(h, 0, &endCharFound, false);
  1758. else
  1759. #endif
  1760. if ((h->options.outputCharstrType != 2) && (h->dict.fontType != 1))
  1761. ProcessCharstr(h, 0, &endCharFound, false);
  1762. }
  1763. void XC_CleanUp(XCF_Handle h)
  1764. {
  1765. if (!CIDFONT)
  1766. {
  1767. NewT1Subr(h);
  1768. NewT1CharStr(h);
  1769. }
  1770. }
  1771. void CheckSeacCharString(XCF_Handle h, CardX index)
  1772. {
  1773. Card8 PTR_PREFIX *argList;
  1774. IntX argCount;
  1775. XCF_LookUpTableEntry(h, &h->fontSet.charStrings, index);
  1776. h->cstr.pen = PenNull;
  1777. h->cstr.hints = InitialHints;
  1778. h->cstr.waitingForHsbw = true;
  1779. h->cstr.waitingForFirstHint = true;
  1780. h->cstr.stackTop = 0;
  1781. h->cstr.hintCount = 0;
  1782. h->cstr.counterGroupCount = 0;
  1783. h->cstr.counterGroupVCount = 0;
  1784. h->cstr.counterGroupHCount = 0;
  1785. IntToPSV(h->cstr.x, 0);
  1786. IntToPSV(h->cstr.y, 0);
  1787. h->cstr.baseSeac = 0;
  1788. h->cstr.accentSeac = 0;
  1789. h->cstr.stackTop = 0;
  1790. argList = h->inBuffer.pos;
  1791. argCount = XCF_FindNextOperator(h, &h->cstr.opCode, false);
  1792. if ((h->cstr.stackTop + argCount) > MAX_OPERAND_STACK)
  1793. XCF_FATAL_ERROR(h, XCF_StackOverflow, "Charstring Stack Overflow", h->cstr.stackTop + argCount );
  1794. CopyArgumentsToStack(h, argList, argCount, (h->cstr.opCode == t2_blend));
  1795. if (h->cstr.opCode == tx_endchar && h->cstr.stackTop >= 4)
  1796. {
  1797. h->cstr.baseSeac = FIXED_TO_INT(h->cstr.stack[2]->value[0]);
  1798. h->cstr.accentSeac = FIXED_TO_INT(h->cstr.stack[3]->value[0]);
  1799. }
  1800. }
  1801. /* All charstring stack operations are performed using the fixed point type.
  1802. The following functions deal with storing and retrieving values from
  1803. the stack. */
  1804. /* Push fixed point number on stack (as fixed) */
  1805. static void PushFix(XCF_Handle h, Fixed f)
  1806. {
  1807. if (h->cstr.stackTop >= MAX_OPERAND_STACK)
  1808. XCF_FATAL_ERROR(h, XCF_StackOverflow, "Charstring Stack Overflow",
  1809. h->cstr.stackTop);
  1810. h->cstr.stack[h->cstr.stackTop]->value[0] = f;
  1811. h->cstr.stack[h->cstr.stackTop++]->blend = false;
  1812. }
  1813. /* Push integer number on stack (as fixed) */
  1814. static void PushInt(XCF_Handle h, long l)
  1815. {
  1816. if (h->cstr.stackTop >= MAX_OPERAND_STACK)
  1817. XCF_FATAL_ERROR(h, XCF_StackOverflow, "Charstring Stack Overflow",
  1818. h->cstr.stackTop);
  1819. h->cstr.stack[h->cstr.stackTop]->value[0] = INT_TO_FIXED(l);
  1820. h->cstr.stack[h->cstr.stackTop++]->blend = false;
  1821. }
  1822. /* Pop number from stack (return fixed) */
  1823. static Fixed PopFix(XCF_Handle h)
  1824. {
  1825. if (h->cstr.stackTop < 1)
  1826. XCF_FATAL_ERROR(h, XCF_StackUnderflow, "Charstring Stack Underflow",
  1827. h->cstr.stackTop);
  1828. h->cstr.stackTop -= 1;
  1829. return h->cstr.stack[h->cstr.stackTop]->value[0];
  1830. }
  1831. /* Pop number from stack (return long) */
  1832. static long PopInt(XCF_Handle h)
  1833. {
  1834. if (h->cstr.stackTop < 1)
  1835. XCF_FATAL_ERROR(h, XCF_StackUnderflow, "Charstring Stack Underflow",
  1836. h->cstr.stackTop);
  1837. h->cstr.stackTop -= 1;
  1838. return (FIXED_TO_INT(h->cstr.stack[h->cstr.stackTop]->value[0]));
  1839. }
  1840. /* Select registry item. */
  1841. static Fixed *SelRegItem(XCF_Handle h, int reg, int *regSize)
  1842. {
  1843. switch (reg)
  1844. {
  1845. case TX_REG_WV:
  1846. *regSize = TX_MAX_MASTERS;
  1847. return h->dict.weightVector;
  1848. case TX_REG_NDV:
  1849. *regSize = TX_MAX_AXES;
  1850. return h->dict.normDesignVector;
  1851. case TX_REG_UDV:
  1852. *regSize = TX_MAX_AXES;
  1853. return h->dict.userDesignVector;
  1854. default:
  1855. XCF_FATAL_ERROR(h, XCF_InternalError, "unknown registry item", reg);
  1856. }
  1857. return 0; /* Suppress compiler warning */
  1858. }
  1859. /* Parse and execute the given charstring. This is used specifically for
  1860. multiple master fonts when converting a user design vector to a
  1861. weight vector. It can be used more generally when functionality is
  1862. added for more operators. */
  1863. int XC_ParseCharStr(XCF_Handle h, unsigned char PTR_PREFIX *cstr, int init)
  1864. {
  1865. int i;
  1866. Fixed PTR_PREFIX *bcArray = NULL;
  1867. if (!h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&bcArray,
  1868. h->dict.lenBuildCharArray * sizeof(Fixed), h->callbacks.allocateHook))
  1869. XCF_FATAL_ERROR(h, XCF_MemoryAllocationError,
  1870. "Failure to allocate memory for buildchar array", h->dict.lenBuildCharArray);
  1871. switch (init)
  1872. {
  1873. case 1:
  1874. break;
  1875. case 2:
  1876. InitCharstr(h);
  1877. break;
  1878. }
  1879. i = 0;
  1880. for (;;)
  1881. switch (cstr[i])
  1882. {
  1883. case tx_endchar:
  1884. if (bcArray != NULL)
  1885. h->callbacks.allocate((void PTR_PREFIX * PTR_PREFIX *)&bcArray, 0,
  1886. h->callbacks.allocateHook);
  1887. return i + 1; /* Return charstring length */
  1888. case tx_reserved0:
  1889. case t2_reserved2:
  1890. case t2_reserved9:
  1891. case t2_reserved13:
  1892. case t2_reserved15:
  1893. case t2_reserved17:
  1894. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Reserved Charstring Operator",
  1895. cstr[i]);
  1896. case tx_rlineto:
  1897. case tx_hlineto:
  1898. case tx_vlineto:
  1899. case tx_rrcurveto:
  1900. case tx_callsubr:
  1901. case tx_return:
  1902. case t2_rcurveline:
  1903. case t2_rlinecurve:
  1904. case t2_vvcurveto:
  1905. case t2_hhcurveto:
  1906. case t2_callgsubr:
  1907. case tx_vhcurveto:
  1908. case tx_hvcurveto:
  1909. case tx_rmoveto:
  1910. case tx_hmoveto:
  1911. case tx_vmoveto:
  1912. case tx_hstem:
  1913. case tx_vstem:
  1914. case t2_hstemhm:
  1915. case t2_vstemhm:
  1916. case t2_hintmask:
  1917. case t2_cntrmask:
  1918. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Unsupported Charstring Operator", cstr[i]);
  1919. break;
  1920. case tx_escape:
  1921. {
  1922. Fixed a;
  1923. Fixed b;
  1924. Fixed x;
  1925. Fixed y;
  1926. switch (cff_ESC(cstr[i + 1]))
  1927. {
  1928. case tx_dotsection:
  1929. break;
  1930. default:
  1931. case t2_reservedESC1:
  1932. case t2_reservedESC2:
  1933. case t2_reservedESC6:
  1934. case t2_reservedESC7:
  1935. case t2_reservedESC16:
  1936. case t2_reservedESC17:
  1937. case tx_reservedESC25:
  1938. case tx_reservedESC31:
  1939. case tx_reservedESC32:
  1940. case t2_reservedESC33:
  1941. case t2_reservedESC19:
  1942. case t2_cntron:
  1943. XCF_FATAL_ERROR(h, XCF_InvalidCharString,
  1944. "Reserved Charstring Operator", cstr[i+1]);
  1945. case tx_and:
  1946. b = PopFix(h);
  1947. a = PopFix(h);
  1948. PushInt(h, a || b);
  1949. break;
  1950. case tx_not:
  1951. a = PopFix(h);
  1952. PushInt(h, !a);
  1953. break;
  1954. case tx_store:
  1955. {
  1956. Int32 count = PopInt(h);
  1957. Int32 i = PopInt(h);
  1958. Int32 j = PopInt(h);
  1959. Int32 iReg = PopInt(h);
  1960. int regSize;
  1961. Fixed *reg = SelRegItem(h, (int)iReg, &regSize);
  1962. if (i < 0 || i + count - 1 >= h->dict.lenBuildCharArray ||
  1963. j < 0 || j + count - 1 >= regSize)
  1964. XCF_FATAL_ERROR(h, XCF_IndexOutOfRange, "bounds check (store)", 0);
  1965. h->callbacks.memcpy(&reg[j], &bcArray[i], (unsigned short int)(sizeof(Fixed) * count));
  1966. }
  1967. break;
  1968. case tx_abs:
  1969. a = PopFix(h);
  1970. PushFix(h, (a < 0) ? -a : a);
  1971. break;
  1972. case tx_add:
  1973. b = PopFix(h);
  1974. a = PopFix(h);
  1975. PushFix(h, a + b);
  1976. break;
  1977. case tx_sub:
  1978. b = PopFix(h);
  1979. a = PopFix(h);
  1980. PushFix(h, a - b);
  1981. break;
  1982. case tx_div:
  1983. y = PopFix(h);
  1984. x = PopFix(h);
  1985. if (y == 0)
  1986. XCF_FATAL_ERROR(h, XCF_InvalidNumber, "divide by zero (div)", 0);
  1987. PushFix(h, XCF_FixDiv(x, y));
  1988. break;
  1989. case tx_load:
  1990. {
  1991. int regSize;
  1992. Int32 count = PopInt(h);
  1993. Int32 i = PopInt(h);
  1994. Int32 iReg = PopInt(h);
  1995. Fixed *reg = SelRegItem(h, (int)iReg, &regSize);
  1996. if (i < 0 || i + count - 1 >= h->dict.lenBuildCharArray || count >
  1997. regSize)
  1998. XCF_FATAL_ERROR(h, XCF_IndexOutOfRange, "bounds check (load)", i);
  1999. h->callbacks.memcpy(&bcArray[i], &reg[0], (unsigned short int)(sizeof(Fixed) * count));
  2000. }
  2001. break;
  2002. case tx_neg:
  2003. a = PopFix(h);
  2004. PushFix(h, -a);
  2005. break;
  2006. case tx_eq:
  2007. b = PopFix(h);
  2008. a = PopFix(h);
  2009. PushInt(h, a == b);
  2010. break;
  2011. case tx_drop:
  2012. (void)PopFix(h);
  2013. break;
  2014. case tx_put:
  2015. {
  2016. Int32 i = PopInt(h);
  2017. if (i < 0 || i >= h->dict.lenBuildCharArray)
  2018. XCF_FATAL_ERROR(h, XCF_IndexOutOfRange, "bounds check (put)", i);
  2019. bcArray[i] = PopFix(h);
  2020. }
  2021. break;
  2022. case tx_get:
  2023. {
  2024. Int32 i = PopInt(h);
  2025. if (i < 0 || i >= h->dict.lenBuildCharArray)
  2026. XCF_FATAL_ERROR(h, XCF_IndexOutOfRange, "bounds check (get)", i);
  2027. PushFix(h, bcArray[i]);
  2028. }
  2029. break;
  2030. case tx_ifelse:
  2031. {
  2032. Fixed v2 = PopFix(h);
  2033. Fixed v1 = PopFix(h);
  2034. Fixed s2 = PopFix(h);
  2035. Fixed s1 = PopFix(h);
  2036. PushFix(h, (v1 > v2) ? s2 : s1);
  2037. }
  2038. break;
  2039. case tx_random:
  2040. /* For generators that aren't very random in the low order bits
  2041. (a common problem) the following is a good example of what
  2042. not to do. However, obtaining good randomness is not very
  2043. important in this application so I opted for simplicity */
  2044. /* PushFix(h, rand() % FIXEDONE + 1); */
  2045. break;
  2046. case tx_mul:
  2047. y = PopFix(h);
  2048. x = PopFix(h);
  2049. PushFix(h, XCF_FixMul(x, y));
  2050. break;
  2051. case tx_dup:
  2052. PushFix(h, h->cstr.stack[h->cstr.stackTop - 1]->value[0]);
  2053. break;
  2054. case tx_exch:
  2055. b = PopFix(h);
  2056. a = PopFix(h);
  2057. PushFix(h, b);
  2058. PushFix(h, a);
  2059. break;
  2060. case tx_index:
  2061. {
  2062. Int32 i = PopInt(h);
  2063. if (i < 0)
  2064. i = 0; /* Duplicate top element */
  2065. if (i >= (int)h->cstr.stackTop)
  2066. XCF_FATAL_ERROR(h, XCF_IndexOutOfRange, "limit check (index)", i);
  2067. PushFix(h, h->cstr.stack[h->cstr.stackTop - 1 - i]->value[0]);
  2068. }
  2069. break;
  2070. case tx_roll:
  2071. {
  2072. int k;
  2073. int iSrc;
  2074. int iDst;
  2075. Fixed tmp[T2_MAX_OP_STACK];
  2076. int tmpSize = sizeof(tmp) / sizeof(Fixed);
  2077. Int32 j = PopInt(h);
  2078. Int32 n = PopInt(h);
  2079. int iBottom = h->cstr.stackTop - (int)n;
  2080. if (n < 0 || iBottom < 0)
  2081. XCF_FATAL_ERROR(h, XCF_IndexOutOfRange, "limit check (roll)", 0);
  2082. if (j < 0)
  2083. j += n; /* Convert to positive roll */
  2084. j %= n; /* Constrain j to (-n,n) */
  2085. if (j < 0)
  2086. j += n; /* Constrain j to [0,n) */
  2087. iSrc = iBottom;
  2088. iDst = iBottom + (int)j;
  2089. for (k = 0; (Int32)k < n - j; k++)
  2090. {
  2091. if (iDst >= tmpSize)
  2092. break;
  2093. tmp[iDst++] = h->cstr.stack[iSrc++]->value[0];
  2094. }
  2095. iSrc = iBottom + (int)n - (int)j;
  2096. iDst = iBottom;
  2097. for (k = 0; k < j; k++)
  2098. {
  2099. if (iDst >= tmpSize)
  2100. break;
  2101. tmp[iDst++] = h->cstr.stack[iSrc++]->value[0];
  2102. }
  2103. for (k = iBottom; k < (int)h->cstr.stackTop; k++)
  2104. {
  2105. if (k >= tmpSize)
  2106. break;
  2107. h->cstr.stack[k]->value[0] = tmp[k];
  2108. }
  2109. }
  2110. break;
  2111. case t2_hflex:
  2112. case t2_flex:
  2113. case t2_hflex1:
  2114. case t2_flex1:
  2115. case tx_sqrt:
  2116. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Unsupported Charstring Operator", cstr[i]);
  2117. break;
  2118. }
  2119. i += 2;
  2120. }
  2121. break;
  2122. case t2_blend:
  2123. /* Blend(h); */
  2124. i++;
  2125. break;
  2126. case t2_shortint:
  2127. PushInt(h, cstr[i + 1]<<8 | cstr[i + 2]);
  2128. i += 3;
  2129. break;
  2130. case 247: case 248: case 249: case 250:
  2131. /* Positive 2 byte number */
  2132. PushInt(h, 108 + 256 * (cstr[i] - 247) + cstr[i + 1]);
  2133. i += 2;
  2134. break;
  2135. case 251: case 252: case 253: case 254:
  2136. /* Negative 2 byte number */
  2137. PushInt(h, -108 - 256 * (cstr[i] - 251) - cstr[i + 1]);
  2138. i += 2;
  2139. break;
  2140. case 255:
  2141. /* 5 byte number */
  2142. PushFix(h, (long)cstr[i + 1]<<24 | (long)cstr[i + 2]<<16 |
  2143. cstr[i + 3]<<8 | cstr[i + 4]);
  2144. i += 5;
  2145. break;
  2146. default:
  2147. /* 1 byte number */
  2148. PushInt(h, cstr[i] - 139);
  2149. i++;
  2150. break;
  2151. }
  2152. }
  2153. /* Read the charstring and include as a subroutine. */
  2154. static int CharStrToSubr(XCF_Handle h, unsigned char PTR_PREFIX *cstr)
  2155. {
  2156. int i;
  2157. int j;
  2158. Card16 op;
  2159. NewT1Subr(h);
  2160. h->cstr.stackTop = 0;
  2161. i = 0;
  2162. for (;;)
  2163. switch (cstr[i])
  2164. {
  2165. case tx_endchar:
  2166. XC_WriteT1OpCode(h, tx_endchar, true);
  2167. return i + 1; /* Return charstring length */
  2168. case tx_reserved0:
  2169. case t2_reserved2:
  2170. case t2_reserved9:
  2171. case t2_reserved13:
  2172. case t2_reserved15:
  2173. case t2_reserved17:
  2174. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Reserved Charstring Operator",
  2175. cstr[i]);
  2176. case tx_rlineto:
  2177. case tx_hlineto:
  2178. case tx_vlineto:
  2179. case tx_rrcurveto:
  2180. case tx_callsubr:
  2181. case tx_return:
  2182. case t2_rcurveline:
  2183. case t2_rlinecurve:
  2184. case t2_vvcurveto:
  2185. case t2_hhcurveto:
  2186. case t2_callgsubr:
  2187. case tx_vhcurveto:
  2188. case tx_hvcurveto:
  2189. case tx_rmoveto:
  2190. case tx_hmoveto:
  2191. case tx_vmoveto:
  2192. case tx_hstem:
  2193. case tx_vstem:
  2194. case t2_hstemhm:
  2195. case t2_vstemhm:
  2196. case t2_hintmask:
  2197. case t2_cntrmask:
  2198. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Unsupported Charstring Operator in Design Vector subr", cstr[i]);
  2199. break;
  2200. case tx_escape:
  2201. {
  2202. switch (cff_ESC(cstr[i + 1]))
  2203. {
  2204. case tx_dotsection:
  2205. break;
  2206. default:
  2207. case t2_reservedESC1:
  2208. case t2_reservedESC2:
  2209. case t2_reservedESC6:
  2210. case t2_reservedESC7:
  2211. case t2_reservedESC16:
  2212. case t2_reservedESC17:
  2213. case tx_reservedESC25:
  2214. case tx_reservedESC31:
  2215. case tx_reservedESC32:
  2216. case t2_reservedESC33:
  2217. case t2_reservedESC19:
  2218. case t2_cntron:
  2219. XCF_FATAL_ERROR(h, XCF_InvalidCharString,
  2220. "Reserved Charstring Operator", cstr[i+1]);
  2221. case tx_and:
  2222. case tx_not:
  2223. case tx_store:
  2224. case tx_abs:
  2225. case tx_add:
  2226. case tx_sub:
  2227. case tx_div:
  2228. case tx_load:
  2229. case tx_neg:
  2230. case tx_eq:
  2231. case tx_drop:
  2232. case tx_put:
  2233. case tx_get:
  2234. case tx_ifelse:
  2235. case tx_random:
  2236. case tx_mul:
  2237. case tx_dup:
  2238. case tx_exch:
  2239. case tx_index:
  2240. case tx_roll:
  2241. for (j = 0; j < (int)h->cstr.stackTop; j++)
  2242. XC_WriteT1PStackValue(h, h->cstr.stack[j], true);
  2243. op = (cstr[i] << 8) | cstr[i+1];
  2244. XC_WriteT1OpCode(h, op, true);
  2245. h->cstr.stackTop = 0;
  2246. break;
  2247. case t2_hflex:
  2248. case t2_flex:
  2249. case t2_hflex1:
  2250. case t2_flex1:
  2251. case tx_sqrt:
  2252. XCF_FATAL_ERROR(h, XCF_InvalidCharString, "Unsupported Charstring Operator", cstr[i]);
  2253. break;
  2254. }
  2255. i += 2;
  2256. }
  2257. break;
  2258. case t2_blend:
  2259. /* Blend(h); */
  2260. i++;
  2261. break;
  2262. case t2_shortint:
  2263. PushInt(h, cstr[i + 1]<<8 | cstr[i + 2]);
  2264. i += 3;
  2265. break;
  2266. case 247: case 248: case 249: case 250:
  2267. /* Positive 2 byte number */
  2268. PushInt(h, 108 + 256 * (cstr[i] - 247) + cstr[i + 1]);
  2269. i += 2;
  2270. break;
  2271. case 251: case 252: case 253: case 254:
  2272. /* Negative 2 byte number */
  2273. PushInt(h, -108 - 256 * (cstr[i] - 251) - cstr[i + 1]);
  2274. i += 2;
  2275. break;
  2276. case 255:
  2277. /* 5 byte number */
  2278. PushFix(h, (long)cstr[i + 1]<<24 | (long)cstr[i + 2]<<16 |
  2279. cstr[i + 3]<<8 | cstr[i + 4]);
  2280. i += 5;
  2281. break;
  2282. default:
  2283. /* 1 byte number */
  2284. PushInt(h, cstr[i] - 139);
  2285. i++;
  2286. break;
  2287. }
  2288. }
  2289. /* Write out NDV and CDV as subroutines. */
  2290. void XC_DVToSubr(XCF_Handle h)
  2291. {
  2292. char PTR_PREFIX *str;
  2293. Card16 length;
  2294. XCF_LookUpString(h, h->dict.ndv, &str, &length);
  2295. CharStrToSubr(h, (unsigned char PTR_PREFIX *)str);
  2296. XCF_LookUpString(h, h->dict.cdv, &str, &length);
  2297. CharStrToSubr(h, (unsigned char PTR_PREFIX *)str);
  2298. NewT1Subr(h);
  2299. }
  2300. #if HAS_COOLTYPE_UFL == 1
  2301. /* Returns 1 if i is a character with transitional designs and has
  2302. already been processed. */
  2303. int XC_TransDesignChar(XCF_Handle h, CardX sid)
  2304. {
  2305. /* JimboMM transitional characters */
  2306. static unsigned char Jimbo0_cstr[] =
  2307. {
  2308. #include "xcf_jimbo0.h"
  2309. };
  2310. static unsigned char Jimbo1_cstr[] =
  2311. {
  2312. #include "xcf_jimbo1.h"
  2313. };
  2314. static unsigned char Jimbo2_cstr[] =
  2315. {
  2316. #include "xcf_jimbo2.h"
  2317. };
  2318. static TransChar Jimbo_chars[] =
  2319. {
  2320. {50, {sizeof(Jimbo0_cstr), (char *)Jimbo0_cstr}},
  2321. {56, {sizeof(Jimbo1_cstr), (char *)Jimbo1_cstr}},
  2322. {88, {sizeof(Jimbo2_cstr), (char *)Jimbo2_cstr}},
  2323. };
  2324. /* ITCGaramond Roman transitional characters */
  2325. static unsigned char GaraRm0_cstr[] =
  2326. {
  2327. #include "xcf_rgara0.h"
  2328. };
  2329. static unsigned char GaraRm1_cstr[] =
  2330. {
  2331. #include "xcf_rgara1.h"
  2332. };
  2333. static unsigned char GaraRm2_cstr[] =
  2334. {
  2335. #include "xcf_rgara2.h"
  2336. };
  2337. static unsigned char GaraRm3_cstr[] =
  2338. {
  2339. #include "xcf_rgara3.h"
  2340. };
  2341. static TransChar GaraRm_chars[] =
  2342. {
  2343. {56, {sizeof(GaraRm0_cstr), (char *)GaraRm0_cstr}},
  2344. {97, {sizeof(GaraRm1_cstr), (char *)GaraRm1_cstr}},
  2345. { 5, {sizeof(GaraRm2_cstr), (char *)GaraRm2_cstr}},
  2346. {88, {sizeof(GaraRm3_cstr), (char *)GaraRm3_cstr}},
  2347. };
  2348. /* ITCGaramond Italic transitional characters */
  2349. static unsigned char GaraIt0_cstr[] =
  2350. {
  2351. #include "xcf_igara0.h"
  2352. };
  2353. static unsigned char GaraIt1_cstr[] =
  2354. {
  2355. #include "xcf_igara1.h"
  2356. };
  2357. static unsigned char GaraIt2_cstr[] =
  2358. {
  2359. #include "xcf_igara2.h"
  2360. };
  2361. static unsigned char GaraIt3_cstr[] =
  2362. {
  2363. #include "xcf_igara3.h"
  2364. };
  2365. static unsigned char GaraIt4_cstr[] =
  2366. {
  2367. #include "xcf_igara4.h"
  2368. };
  2369. static TransChar GaraIt_chars[] =
  2370. {
  2371. { 56, {sizeof(GaraIt0_cstr), (char *)GaraIt0_cstr}},
  2372. { 97, {sizeof(GaraIt1_cstr), (char *)GaraIt1_cstr}},
  2373. { 5, {sizeof(GaraIt2_cstr), (char *)GaraIt2_cstr}},
  2374. { 32, {sizeof(GaraIt3_cstr), (char *)GaraIt3_cstr}},
  2375. {123, {sizeof(GaraIt4_cstr), (char *)GaraIt4_cstr}},
  2376. };
  2377. char fontName[512];
  2378. TransChar *transCharTbl = 0;
  2379. Card16 tblLen = 0;
  2380. Card16 i, j;
  2381. if (XCF_FontName(h, (unsigned short int)h->fontSet.fontIndex, fontName,
  2382. (unsigned short int)512) != XCF_Ok)
  2383. return 0;
  2384. if (h->callbacks.strcmp(fontName, "ITCGaramondMM") == 0)
  2385. {
  2386. transCharTbl = GaraRm_chars;
  2387. tblLen = sizeof(GaraRm_chars)/sizeof(GaraRm_chars[0]);
  2388. }
  2389. else if (h->callbacks.strcmp(fontName, "ITCGaramondMM-It") == 0)
  2390. {
  2391. transCharTbl = GaraIt_chars;
  2392. tblLen = sizeof(GaraIt_chars)/sizeof(GaraIt_chars[0]);
  2393. }
  2394. else if (h->callbacks.strcmp(fontName, "JimboMM") == 0)
  2395. {
  2396. transCharTbl = Jimbo_chars;
  2397. tblLen = sizeof(Jimbo_chars)/sizeof(Jimbo_chars[0]);
  2398. }
  2399. if (tblLen == 0) /* Not a font with transitional designs. */
  2400. return 0;
  2401. for (i = 0; i < tblLen; i++)
  2402. if (transCharTbl[i].sid == sid)
  2403. {
  2404. Card8 PTR_PREFIX *args;
  2405. IntX argCount;
  2406. InitCharstr(h);
  2407. if (h->options.subrFlatten)
  2408. FreeT1CharStr(h);
  2409. else
  2410. NewT1CharStr(h);
  2411. h->inBuffer.pos = (Card8 *)transCharTbl[i].cstr.cstr;
  2412. h->inBuffer.blockLength = transCharTbl[i].cstr.length;
  2413. h->inBuffer.end = h->inBuffer.pos + h->inBuffer.blockLength;
  2414. while (h->inBuffer.pos < h->inBuffer.end)
  2415. {
  2416. args = h->inBuffer.pos;
  2417. argCount = XCF_FindNextOperator(h, &h->cstr.opCode, false);
  2418. if ((h->cstr.stackTop + argCount) > MAX_OPERAND_STACK)
  2419. XCF_FATAL_ERROR(h, XCF_StackOverflow, "Charstring Stack Overflow", h->cstr.stackTop + argCount );
  2420. CopyArgumentsToStack(h, args, argCount, (h->cstr.opCode == t2_blend));
  2421. for (j = 0; j < h->cstr.stackTop; j++)
  2422. XC_WriteT1PStackValue(h, h->cstr.stack[j], false);
  2423. XC_WriteT1OpCode(h, h->cstr.opCode, false);
  2424. h->cstr.stackTop = 0;
  2425. }
  2426. return 1;
  2427. }
  2428. return 0;
  2429. }
  2430. /* Only processes the subroutines associated with transitional
  2431. design characters. */
  2432. void XC_ProcessTransDesignSubrs(XCF_Handle h)
  2433. {
  2434. Card16 i;
  2435. char fontName[512];
  2436. Card16 tblLen = 0;
  2437. short *subrTbl = 0;
  2438. boolean endCharFound = false;
  2439. static short Jimbo_subrs[] = {0, 1, 2, 3, 4, 5};
  2440. static short GaraRm_subrs[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
  2441. static short GaraIt_subrs[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  2442. if (XCF_FontName(h, (unsigned short int)h->fontSet.fontIndex, fontName,
  2443. (unsigned short int)512) != XCF_Ok)
  2444. return;
  2445. if (h->callbacks.strcmp(fontName, "ITCGaramondMM") == 0)
  2446. {
  2447. subrTbl = GaraRm_subrs;
  2448. tblLen = sizeof(GaraRm_subrs)/sizeof(GaraRm_subrs[0]);
  2449. }
  2450. else if (h->callbacks.strcmp(fontName, "ITCGaramondMM-It") == 0)
  2451. {
  2452. subrTbl = GaraIt_subrs;
  2453. tblLen = sizeof(GaraIt_subrs)/sizeof(GaraIt_subrs[0]);
  2454. }
  2455. else if (h->callbacks.strcmp(fontName, "JimboMM") == 0)
  2456. {
  2457. subrTbl = Jimbo_subrs;
  2458. tblLen = sizeof(Jimbo_subrs)/sizeof(Jimbo_subrs[0]);
  2459. }
  2460. if (tblLen == 0) /* Not a font with transitional designs. */
  2461. return;
  2462. for (i = 0; i < tblLen; i++)
  2463. {
  2464. InitCharstr(h);
  2465. NewT1Subr(h);
  2466. XCF_LookUpTableEntry(h, &h->dict.localSubrs, subrTbl[i]);
  2467. #ifdef T13
  2468. if (h->dict.fontType == 13)
  2469. XT13_ProcessCharstr(h, 0, &endCharFound, true);
  2470. else
  2471. #endif
  2472. ProcessCharstr(h, 0, &endCharFound, true);
  2473. }
  2474. }
  2475. #endif
  2476. #ifdef __cplusplus
  2477. }
  2478. #endif