gstype2.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /* Copyright (C) 1996, 2000 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gstype2.c,v 1.36 2004/10/28 08:39:21 igor Exp $ */
  14. /* Adobe Type 2 charstring interpreter */
  15. #include "math_.h"
  16. #include "memory_.h"
  17. #include "gx.h"
  18. #include "gserrors.h"
  19. #include "gsstruct.h"
  20. #include "gxarith.h"
  21. #include "gxfixed.h"
  22. #include "gxmatrix.h"
  23. #include "gxcoord.h"
  24. #include "gxistate.h"
  25. #include "gxpath.h"
  26. #include "gxfont.h"
  27. #include "gxfont1.h"
  28. #include "gxtype1.h"
  29. #include "gxhintn.h"
  30. /* NOTE: The following are not yet implemented:
  31. * Registry items other than 0
  32. * Counter masks (but they are parsed correctly)
  33. * 'random' operator
  34. */
  35. /* ------ Internal routines ------ */
  36. /*
  37. * Set the character width. This is provided as an optional extra operand
  38. * on the stack for the first operator. After setting the width, we remove
  39. * the extra operand, and back up the interpreter pointer so we will
  40. * re-execute the operator when control re-enters the interpreter.
  41. */
  42. #define check_first_operator(explicit_width)\
  43. BEGIN\
  44. if ( pcis->init_done < 0 )\
  45. { ipsp->ip = cip, ipsp->dstate = state;\
  46. return type2_sbw(pcis, csp, cstack, ipsp, explicit_width);\
  47. }\
  48. END
  49. private int
  50. type2_sbw(gs_type1_state * pcis, cs_ptr csp, cs_ptr cstack, ip_state_t * ipsp,
  51. bool explicit_width)
  52. {
  53. t1_hinter *h = &pcis->h;
  54. fixed sbx = fixed_0, sby = fixed_0, wx, wy = fixed_0;
  55. int code;
  56. if (explicit_width) {
  57. wx = cstack[0] + pcis->pfont->data.nominalWidthX;
  58. memmove(cstack, cstack + 1, (csp - cstack) * sizeof(*cstack));
  59. --csp;
  60. } else
  61. wx = pcis->pfont->data.defaultWidthX;
  62. if (pcis->seac_accent < 0) {
  63. if (pcis->sb_set) {
  64. sbx = pcis->lsb.x;
  65. sby = pcis->lsb.y;
  66. }
  67. if (pcis->width_set) {
  68. wx = pcis->width.x;
  69. wy = pcis->width.y;
  70. }
  71. }
  72. code = t1_hinter__sbw(h, sbx, sby, wx, wy);
  73. if (code < 0)
  74. return code;
  75. gs_type1_sbw(pcis, fixed_0, fixed_0, wx, fixed_0);
  76. /* Back up the interpretation pointer. */
  77. ipsp->ip--;
  78. decrypt_skip_previous(*ipsp->ip, ipsp->dstate);
  79. /* Save the interpreter state. */
  80. pcis->os_count = csp + 1 - cstack;
  81. pcis->ips_count = ipsp - &pcis->ipstack[0] + 1;
  82. memcpy(pcis->ostack, cstack, pcis->os_count * sizeof(cstack[0]));
  83. if (pcis->init_done < 0) { /* Finish init when we return. */
  84. pcis->init_done = 0;
  85. }
  86. return type1_result_sbw;
  87. }
  88. private int
  89. type2_vstem(gs_type1_state * pcis, cs_ptr csp, cs_ptr cstack)
  90. {
  91. fixed x = 0;
  92. cs_ptr ap;
  93. t1_hinter *h = &pcis->h;
  94. int code;
  95. for (ap = cstack; ap + 1 <= csp; x += ap[1], ap += 2) {
  96. code = t1_hinter__vstem(h, x += ap[0], ap[1]);
  97. if (code < 0)
  98. return code;
  99. }
  100. pcis->num_hints += (csp + 1 - cstack) >> 1;
  101. return 0;
  102. }
  103. /* ------ Main interpreter ------ */
  104. /*
  105. * Continue interpreting a Type 2 charstring. If str != 0, it is taken as
  106. * the byte string to interpret. Return 0 on successful completion, <0 on
  107. * error, or >0 when client intervention is required (or allowed). The int*
  108. * argument is only for compatibility with the Type 1 charstring interpreter.
  109. */
  110. int
  111. gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd,
  112. int *ignore_pindex)
  113. {
  114. gs_font_type1 *pfont = pcis->pfont;
  115. gs_type1_data *pdata = &pfont->data;
  116. t1_hinter *h = &pcis->h;
  117. bool encrypted = pdata->lenIV >= 0;
  118. fixed cstack[ostack_size];
  119. cs_ptr csp;
  120. #define clear CLEAR_CSTACK(cstack, csp)
  121. ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
  122. register const byte *cip;
  123. register crypt_state state;
  124. register int c;
  125. cs_ptr ap;
  126. bool vertical;
  127. int code = 0;
  128. /****** FAKE THE REGISTRY ******/
  129. struct {
  130. float *values;
  131. uint size;
  132. } Registry[1];
  133. Registry[0].values = pcis->pfont->data.WeightVector.values;
  134. switch (pcis->init_done) {
  135. case -1:
  136. t1_hinter__init(h, pcis->path);
  137. break;
  138. case 0:
  139. gs_type1_finish_init(pcis); /* sets origin */
  140. code = t1_hinter__set_mapping(h, &pcis->pis->ctm,
  141. &pfont->FontMatrix, &pfont->base->FontMatrix,
  142. pcis->scale.x.log2_unit, pcis->scale.x.log2_unit,
  143. pcis->scale.x.log2_unit - pcis->log2_subpixels.x,
  144. pcis->scale.y.log2_unit - pcis->log2_subpixels.y,
  145. pcis->origin.x, pcis->origin.y,
  146. gs_currentaligntopixels(pfont->dir));
  147. if (code < 0)
  148. return code;
  149. code = t1_hinter__set_font_data(h, 2, pdata, pcis->no_grid_fitting);
  150. if (code < 0)
  151. return code;
  152. break;
  153. default /*case 1 */ :
  154. break;
  155. }
  156. INIT_CSTACK(cstack, csp, pcis);
  157. if (pgd == 0)
  158. goto cont;
  159. ipsp->cs_data = *pgd;
  160. cip = pgd->bits.data;
  161. call:state = crypt_charstring_seed;
  162. if (encrypted) {
  163. int skip = pdata->lenIV;
  164. /* Skip initial random bytes */
  165. for (; skip > 0; ++cip, --skip)
  166. decrypt_skip_next(*cip, state);
  167. }
  168. goto top;
  169. cont:cip = ipsp->ip;
  170. state = ipsp->dstate;
  171. top:for (;;) {
  172. uint c0 = *cip++;
  173. charstring_next(c0, state, c, encrypted);
  174. if (c >= c_num1) {
  175. /* This is a number, decode it and push it on the stack. */
  176. if (c < c_pos2_0) { /* 1-byte number */
  177. decode_push_num1(csp, cstack, c);
  178. } else if (c < cx_num4) { /* 2-byte number */
  179. decode_push_num2(csp, cstack, c, cip, state, encrypted);
  180. } else if (c == cx_num4) { /* 4-byte number */
  181. long lw;
  182. decode_num4(lw, cip, state, encrypted);
  183. /* 32-bit numbers are 16:16. */
  184. CS_CHECK_PUSH(csp, cstack);
  185. *++csp = arith_rshift(lw, 16 - _fixed_shift);
  186. } else /* not possible */
  187. return_error(gs_error_invalidfont);
  188. pushed:if_debug3('1', "[1]%d: (%d) %f\n",
  189. (int)(csp - cstack), c, fixed2float(*csp));
  190. continue;
  191. }
  192. #ifdef DEBUG
  193. if (gs_debug['1']) {
  194. static const char *const c2names[] =
  195. {char2_command_names};
  196. if (c2names[c] == 0)
  197. dlprintf2("[1]0x%lx: %02x??\n", (ulong) (cip - 1), c);
  198. else
  199. dlprintf3("[1]0x%lx: %02x %s\n", (ulong) (cip - 1), c,
  200. c2names[c]);
  201. }
  202. #endif
  203. switch ((char_command) c) {
  204. #define cnext clear; goto top
  205. /* Commands with identical functions in Type 1 and Type 2, */
  206. /* except for 'escape'. */
  207. case c_undef0:
  208. case c_undef2:
  209. case c_undef17:
  210. return_error(gs_error_invalidfont);
  211. case c_callsubr:
  212. c = fixed2int_var(*csp) + pdata->subroutineNumberBias;
  213. code = pdata->procs.subr_data
  214. (pfont, c, false, &ipsp[1].cs_data);
  215. subr:if (code < 0) {
  216. /* Calling a Subr with an out-of-range index is clearly a error:
  217. * the Adobe documentation says the results of doing this are
  218. * undefined. However, we have seen a PDF file produced by Adobe
  219. * PDF Library 4.16 that included a Type 2 font that called an
  220. * out-of-range Subr, and Acrobat Reader did not signal an error.
  221. * Therefore, we ignore such calls.
  222. */
  223. cip++;
  224. goto top;
  225. }
  226. --csp;
  227. ipsp->ip = cip, ipsp->dstate = state;
  228. ++ipsp;
  229. cip = ipsp->cs_data.bits.data;
  230. goto call;
  231. case c_return:
  232. gs_glyph_data_free(&ipsp->cs_data, "gs_type2_interpret");
  233. --ipsp;
  234. goto cont;
  235. case c_undoc15:
  236. /* See gstype1.h for information on this opcode. */
  237. cnext;
  238. /* Commands with similar but not identical functions */
  239. /* in Type 1 and Type 2 charstrings. */
  240. case cx_hstem:
  241. goto hstem;
  242. case cx_vstem:
  243. goto vstem;
  244. case cx_vmoveto:
  245. check_first_operator(csp > cstack);
  246. code = t1_hinter__rmoveto(h, 0, *csp);
  247. move:
  248. cc:
  249. if (code < 0)
  250. return code;
  251. goto pp;
  252. case cx_rlineto:
  253. for (ap = cstack; ap + 1 <= csp; ap += 2) {
  254. code = t1_hinter__rlineto(h, ap[0], ap[1]);
  255. if (code < 0)
  256. return code;
  257. }
  258. pp:
  259. cnext;
  260. case cx_hlineto:
  261. vertical = false;
  262. goto hvl;
  263. case cx_vlineto:
  264. vertical = true;
  265. hvl:for (ap = cstack; ap <= csp; vertical = !vertical, ++ap) {
  266. if (vertical) {
  267. code = t1_hinter__rlineto(h, 0, ap[0]);
  268. } else {
  269. code = t1_hinter__rlineto(h, ap[0], 0);
  270. }
  271. if (code < 0)
  272. return code;
  273. }
  274. goto pp;
  275. case cx_rrcurveto:
  276. for (ap = cstack; ap + 5 <= csp; ap += 6) {
  277. code = t1_hinter__rcurveto(h, ap[0], ap[1], ap[2],
  278. ap[3], ap[4], ap[5]);
  279. if (code < 0)
  280. return code;
  281. }
  282. goto pp;
  283. case cx_endchar:
  284. /*
  285. * It is a feature of Type 2 CharStrings that if endchar is
  286. * invoked with 4 or 5 operands, it is equivalent to the
  287. * Type 1 seac operator. In this case, the asb operand of
  288. * seac is missing: we assume it is the same as the
  289. * l.s.b. of the accented character. This feature was
  290. * undocumented until the 16 March 2000 version of the Type
  291. * 2 Charstring Format specification, but, thankfully, is
  292. * described in that revision.
  293. */
  294. if (csp >= cstack + 3) {
  295. check_first_operator(csp > cstack + 3);
  296. code = gs_type1_seac(pcis, cstack, 0, ipsp);
  297. if (code < 0)
  298. return code;
  299. clear;
  300. cip = ipsp->cs_data.bits.data;
  301. goto call;
  302. }
  303. /*
  304. * This might be the only operator in the charstring.
  305. * In this case, there might be a width on the stack.
  306. */
  307. check_first_operator(csp >= cstack);
  308. code = t1_hinter__endchar(h, (pcis->seac_accent >= 0));
  309. if (code < 0)
  310. return code;
  311. if (pcis->seac_accent < 0) {
  312. code = t1_hinter__endglyph(h);
  313. if (code < 0)
  314. return code;
  315. code = gx_setcurrentpoint_from_path(pcis->pis, pcis->path);
  316. if (code < 0)
  317. return code;
  318. } else
  319. t1_hinter__setcurrentpoint(h, pcis->save_adxy.x, pcis->save_adxy.y);
  320. code = gs_type1_endchar(pcis);
  321. if (code == 1) {
  322. /*
  323. * Reset the total hint count so that hintmask will
  324. * parse its following data correctly.
  325. * (gs_type1_endchar already reset the actual hint
  326. * tables.)
  327. */
  328. pcis->num_hints = 0;
  329. /* do accent of seac */
  330. ipsp = &pcis->ipstack[pcis->ips_count - 1];
  331. cip = ipsp->cs_data.bits.data;
  332. goto call;
  333. }
  334. return code;
  335. case cx_rmoveto:
  336. /* See vmoveto above re closing the subpath. */
  337. check_first_operator(!((csp - cstack) & 1));
  338. if (csp > cstack + 1) {
  339. /* Some Type 2 charstrings omit the vstemhm operator before rmoveto,
  340. even though this is only allowed before hintmask and cntrmask.
  341. Thanks to Felix Pahl.
  342. */
  343. type2_vstem(pcis, csp - 2, cstack);
  344. cstack [0] = csp [-1];
  345. cstack [1] = csp [ 0];
  346. csp = cstack + 1;
  347. }
  348. code = t1_hinter__rmoveto(h, csp[-1], *csp);
  349. goto move;
  350. case cx_hmoveto:
  351. /* See vmoveto above re closing the subpath. */
  352. check_first_operator(csp > cstack);
  353. code = t1_hinter__rmoveto(h, *csp, 0);
  354. goto move;
  355. case cx_vhcurveto:
  356. vertical = true;
  357. goto hvc;
  358. case cx_hvcurveto:
  359. vertical = false;
  360. hvc:for (ap = cstack; ap + 3 <= csp; vertical = !vertical, ap += 4) {
  361. gs_fixed_point pt[2] = {{0, 0}, {0, 0}};
  362. if (vertical) {
  363. pt[0].y = ap[0];
  364. pt[1].x = ap[3];
  365. if (ap + 4 == csp)
  366. pt[1].y = ap[4];
  367. } else {
  368. pt[0].x = ap[0];
  369. if (ap + 4 == csp)
  370. pt[1].x = ap[4];
  371. pt[1].y = ap[3];
  372. }
  373. code = t1_hinter__rcurveto(h, pt[0].x, pt[0].y, ap[1], ap[2], pt[1].x, pt[1].y);
  374. if (code < 0)
  375. return code;
  376. }
  377. goto pp;
  378. /***********************
  379. * New Type 2 commands *
  380. ***********************/
  381. case c2_blend:
  382. {
  383. int n = fixed2int_var(*csp);
  384. int num_values = csp - cstack;
  385. gs_font_type1 *pfont = pcis->pfont;
  386. int k = pfont->data.WeightVector.count;
  387. int i, j;
  388. cs_ptr base, deltas;
  389. base = csp - 1 - num_values;
  390. deltas = base + n - 1;
  391. for (j = 0; j < n; j++, base++, deltas += k - 1)
  392. for (i = 1; i < k; i++)
  393. *base += (fixed)(deltas[i] *
  394. pfont->data.WeightVector.values[i]);
  395. }
  396. cnext;
  397. case c2_hstemhm:
  398. hstem:check_first_operator(!((csp - cstack) & 1));
  399. {
  400. fixed x = 0;
  401. for (ap = cstack; ap + 1 <= csp; x += ap[1], ap += 2) {
  402. code = t1_hinter__hstem(h, x += ap[0], ap[1]);
  403. if (code < 0)
  404. return code;
  405. }
  406. }
  407. pcis->num_hints += (csp + 1 - cstack) >> 1;
  408. cnext;
  409. case c2_hintmask:
  410. /*
  411. * A hintmask at the beginning of the CharString is
  412. * equivalent to vstemhm + hintmask. For simplicity, we use
  413. * this interpretation everywhere.
  414. */
  415. case c2_cntrmask:
  416. check_first_operator(!((csp - cstack) & 1));
  417. type2_vstem(pcis, csp, cstack);
  418. /*
  419. * We should clear the stack here only if this is the
  420. * initial mask operator that includes the implicit
  421. * vstemhm, but currently this is too much trouble to
  422. * detect.
  423. */
  424. clear;
  425. {
  426. byte mask[max_total_stem_hints / 8];
  427. int i;
  428. for (i = 0; i < pcis->num_hints; ++cip, i += 8) {
  429. charstring_next(*cip, state, mask[i >> 3], encrypted);
  430. if_debug1('1', " 0x%02x", mask[i >> 3]);
  431. }
  432. if_debug0('1', "\n");
  433. ipsp->ip = cip;
  434. ipsp->dstate = state;
  435. if (c == c2_cntrmask) {
  436. /****** NYI ******/
  437. } else { /* hintmask or equivalent */
  438. if_debug0('1', "[1]hstem hints:\n");
  439. if_debug0('1', "[1]vstem hints:\n");
  440. code = t1_hinter__hint_mask(h, mask);
  441. if (code < 0)
  442. return code;
  443. }
  444. }
  445. break;
  446. case c2_vstemhm:
  447. vstem:check_first_operator(!((csp - cstack) & 1));
  448. type2_vstem(pcis, csp, cstack);
  449. cnext;
  450. case c2_rcurveline:
  451. for (ap = cstack; ap + 5 <= csp; ap += 6) {
  452. code = t1_hinter__rcurveto(h, ap[0], ap[1], ap[2], ap[3],
  453. ap[4], ap[5]);
  454. if (code < 0)
  455. return code;
  456. }
  457. code = t1_hinter__rlineto(h, ap[0], ap[1]);
  458. goto cc;
  459. case c2_rlinecurve:
  460. for (ap = cstack; ap + 7 <= csp; ap += 2) {
  461. code = t1_hinter__rlineto(h, ap[0], ap[1]);
  462. if (code < 0)
  463. return code;
  464. }
  465. code = t1_hinter__rcurveto(h, ap[0], ap[1], ap[2], ap[3],
  466. ap[4], ap[5]);
  467. goto cc;
  468. case c2_vvcurveto:
  469. ap = cstack;
  470. {
  471. int n = csp + 1 - cstack;
  472. fixed dxa = (n & 1 ? *ap++ : 0);
  473. for (; ap + 3 <= csp; ap += 4) {
  474. code = t1_hinter__rcurveto(h, dxa, ap[0], ap[1], ap[2],
  475. fixed_0, ap[3]);
  476. if (code < 0)
  477. return code;
  478. dxa = 0;
  479. }
  480. }
  481. goto pp;
  482. case c2_hhcurveto:
  483. ap = cstack;
  484. {
  485. int n = csp + 1 - cstack;
  486. fixed dya = (n & 1 ? *ap++ : 0);
  487. for (; ap + 3 <= csp; ap += 4) {
  488. code = t1_hinter__rcurveto(h, ap[0], dya, ap[1], ap[2],
  489. ap[3], fixed_0);
  490. if (code < 0)
  491. return code;
  492. dya = 0;
  493. }
  494. }
  495. goto pp;
  496. case c2_shortint:
  497. {
  498. int c1, c2;
  499. charstring_next(*cip, state, c1, encrypted);
  500. ++cip;
  501. charstring_next(*cip, state, c2, encrypted);
  502. ++cip;
  503. CS_CHECK_PUSH(csp, cstack);
  504. *++csp = int2fixed((((c1 ^ 0x80) - 0x80) << 8) + c2);
  505. }
  506. goto pushed;
  507. case c2_callgsubr:
  508. c = fixed2int_var(*csp) + pdata->gsubrNumberBias;
  509. code = pdata->procs.subr_data
  510. (pfont, c, true, &ipsp[1].cs_data);
  511. goto subr;
  512. case cx_escape:
  513. charstring_next(*cip, state, c, encrypted);
  514. ++cip;
  515. #ifdef DEBUG
  516. if (gs_debug['1'] && c < char2_extended_command_count) {
  517. static const char *const ce2names[] =
  518. {char2_extended_command_names};
  519. if (ce2names[c] == 0)
  520. dlprintf2("[1]0x%lx: %02x??\n", (ulong) (cip - 1), c);
  521. else
  522. dlprintf3("[1]0x%lx: %02x %s\n", (ulong) (cip - 1), c,
  523. ce2names[c]);
  524. }
  525. #endif
  526. switch ((char2_extended_command) c) {
  527. case ce2_and:
  528. csp[-1] = ((csp[-1] != 0) & (*csp != 0) ? fixed_1 : 0);
  529. --csp;
  530. break;
  531. case ce2_or:
  532. csp[-1] = (csp[-1] | *csp ? fixed_1 : 0);
  533. --csp;
  534. break;
  535. case ce2_not:
  536. *csp = (*csp ? 0 : fixed_1);
  537. break;
  538. case ce2_store:
  539. {
  540. int i, n = fixed2int_var(*csp);
  541. float *to = Registry[fixed2int_var(csp[-3])].values +
  542. fixed2int_var(csp[-2]);
  543. const fixed *from =
  544. pcis->transient_array + fixed2int_var(csp[-1]);
  545. for (i = 0; i < n; ++i)
  546. to[i] = fixed2float(from[i]);
  547. }
  548. csp -= 4;
  549. break;
  550. case ce2_abs:
  551. if (*csp < 0)
  552. *csp = -*csp;
  553. break;
  554. case ce2_add:
  555. csp[-1] += *csp;
  556. --csp;
  557. break;
  558. case ce2_sub:
  559. csp[-1] -= *csp;
  560. --csp;
  561. break;
  562. case ce2_div:
  563. csp[-1] = float2fixed((double)csp[-1] / *csp);
  564. --csp;
  565. break;
  566. case ce2_load:
  567. /* The specification says there is no j (starting index */
  568. /* in registry array) argument.... */
  569. {
  570. int i, n = fixed2int_var(*csp);
  571. const float *from = Registry[fixed2int_var(csp[-2])].values;
  572. fixed *to =
  573. pcis->transient_array + fixed2int_var(csp[-1]);
  574. for (i = 0; i < n; ++i)
  575. to[i] = float2fixed(from[i]);
  576. }
  577. csp -= 3;
  578. break;
  579. case ce2_neg:
  580. *csp = -*csp;
  581. break;
  582. case ce2_eq:
  583. csp[-1] = (csp[-1] == *csp ? fixed_1 : 0);
  584. --csp;
  585. break;
  586. case ce2_drop:
  587. --csp;
  588. break;
  589. case ce2_put:
  590. pcis->transient_array[fixed2int_var(*csp)] = csp[-1];
  591. csp -= 2;
  592. break;
  593. case ce2_get:
  594. *csp = pcis->transient_array[fixed2int_var(*csp)];
  595. break;
  596. case ce2_ifelse:
  597. if (csp[-1] > *csp)
  598. csp[-3] = csp[-2];
  599. csp -= 3;
  600. break;
  601. case ce2_random:
  602. CS_CHECK_PUSH(csp, cstack);
  603. ++csp;
  604. /****** NYI ******/
  605. break;
  606. case ce2_mul:
  607. {
  608. double prod = fixed2float(csp[-1]) * *csp;
  609. csp[-1] =
  610. (prod > max_fixed ? max_fixed :
  611. prod < min_fixed ? min_fixed : (fixed)prod);
  612. }
  613. --csp;
  614. break;
  615. case ce2_sqrt:
  616. if (*csp >= 0)
  617. *csp = float2fixed(sqrt(fixed2float(*csp)));
  618. break;
  619. case ce2_dup:
  620. CS_CHECK_PUSH(csp, cstack);
  621. csp[1] = *csp;
  622. ++csp;
  623. break;
  624. case ce2_exch:
  625. {
  626. fixed top = *csp;
  627. *csp = csp[-1], csp[-1] = top;
  628. }
  629. break;
  630. case ce2_index:
  631. *csp =
  632. (*csp < 0 ? csp[-1] : csp[-1 - fixed2int_var(csp[-1])]);
  633. break;
  634. case ce2_roll:
  635. {
  636. int distance = fixed2int_var(*csp);
  637. int count = fixed2int_var(csp[-1]);
  638. cs_ptr bot;
  639. csp -= 2;
  640. if (count < 0 || count > csp + 1 - cstack)
  641. return_error(gs_error_invalidfont);
  642. if (count == 0)
  643. break;
  644. if (distance < 0)
  645. distance = count - (-distance % count);
  646. bot = csp + 1 - count;
  647. while (--distance >= 0) {
  648. fixed top = *csp;
  649. memmove(bot + 1, bot,
  650. (count - 1) * sizeof(fixed));
  651. *bot = top;
  652. }
  653. }
  654. break;
  655. case ce2_hflex:
  656. csp[6] = fixed_half; /* fd/100 */
  657. csp[4] = *csp, csp[5] = 0; /* dx6, dy6 */
  658. csp[2] = csp[-1], csp[3] = -csp[-4]; /* dx5, dy5 */
  659. *csp = csp[-2], csp[1] = 0; /* dx4, dy4 */
  660. csp[-2] = csp[-3], csp[-1] = 0; /* dx3, dy3 */
  661. csp[-3] = csp[-4], csp[-4] = csp[-5]; /* dx2, dy2 */
  662. csp[-5] = 0; /* dy1 */
  663. csp += 6;
  664. goto flex;
  665. case ce2_flex:
  666. *csp /= 100; /* fd/100 */
  667. flex: {
  668. fixed x_join = csp[-12] + csp[-10] + csp[-8];
  669. fixed y_join = csp[-11] + csp[-9] + csp[-7];
  670. fixed x_end = x_join + csp[-6] + csp[-4] + csp[-2];
  671. fixed y_end = y_join + csp[-5] + csp[-3] + csp[-1];
  672. gs_point join, end;
  673. double flex_depth;
  674. if ((code =
  675. gs_distance_transform(fixed2float(x_join),
  676. fixed2float(y_join),
  677. &ctm_only(pcis->pis),
  678. &join)) < 0 ||
  679. (code =
  680. gs_distance_transform(fixed2float(x_end),
  681. fixed2float(y_end),
  682. &ctm_only(pcis->pis),
  683. &end)) < 0
  684. )
  685. return code;
  686. /*
  687. * Use the X or Y distance depending on whether
  688. * the curve is more horizontal or more
  689. * vertical.
  690. */
  691. if (any_abs(end.y) > any_abs(end.x))
  692. flex_depth = join.x;
  693. else
  694. flex_depth = join.y;
  695. if (fabs(flex_depth) < fixed2float(*csp)) {
  696. /* Do flex as line. */
  697. code = t1_hinter__rlineto(h, x_end, y_end);
  698. } else {
  699. /*
  700. * Do flex as curve. We can't jump to rrc,
  701. * because the flex operators don't clear
  702. * the stack (!).
  703. */
  704. code = t1_hinter__rcurveto(h,
  705. csp[-12], csp[-11], csp[-10],
  706. csp[-9], csp[-8], csp[-7]);
  707. if (code < 0)
  708. return code;
  709. code = t1_hinter__rcurveto(h,
  710. csp[-6], csp[-5], csp[-4],
  711. csp[-3], csp[-2], csp[-1]);
  712. }
  713. if (code < 0)
  714. return code;
  715. csp -= 13;
  716. }
  717. cnext;
  718. case ce2_hflex1:
  719. csp[4] = fixed_half; /* fd/100 */
  720. csp[2] = *csp; /* dx6 */
  721. csp[3] = -(csp[-7] + csp[-5] + csp[-1]); /* dy6 */
  722. *csp = csp[-2], csp[1] = csp[-1]; /* dx5, dy5 */
  723. csp[-2] = csp[-3], csp[-1] = 0; /* dx4, dy4 */
  724. csp[-3] = 0; /* dy3 */
  725. csp += 4;
  726. goto flex;
  727. case ce2_flex1:
  728. {
  729. fixed dx = csp[-10] + csp[-8] + csp[-6] + csp[-4] + csp[-2];
  730. fixed dy = csp[-9] + csp[-7] + csp[-5] + csp[-3] + csp[-1];
  731. if (any_abs(dx) > any_abs(dy))
  732. csp[1] = -dy; /* d6 is dx6 */
  733. else
  734. csp[1] = *csp, *csp = -dx; /* d6 is dy6 */
  735. }
  736. csp[2] = fixed_half; /* fd/100 */
  737. csp += 2;
  738. goto flex;
  739. }
  740. break;
  741. /* Fill up the dispatch up to 32. */
  742. case_c2_undefs:
  743. default: /* pacify compiler */
  744. return_error(gs_error_invalidfont);
  745. }
  746. }
  747. }