PageRenderTime 79ms CodeModel.GetById 11ms RepoModel.GetById 11ms app.codeStats 1ms

/reportlab-2.5/src/rl_addons/renderPM/gt1/gt1-parset1.c

#
C | 3242 lines | 2767 code | 326 blank | 149 comment | 630 complexity | e4ecef74d647c9a9056d513636877363 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <math.h>
  5. #if defined(macintosh)
  6. # include <extras.h>
  7. # define strdup _strdup
  8. #endif
  9. #include "libart_lgpl/art_bpath.h"
  10. #include "gt1-misc.h"
  11. #include "gt1-region.h"
  12. #include "gt1-namecontext.h"
  13. #include "gt1-value.h"
  14. #include "gt1-dict.h"
  15. #include "gt1-parset1.h"
  16. #ifdef AFM
  17. # include "parseAFM.h"
  18. #endif
  19. /* a big-assed module to parse Adobe Type 1 fonts into meaningful
  20. info */
  21. #define noVERBOSE
  22. static int
  23. read_int32_lsb (const char *p)
  24. {
  25. const unsigned char *q = (unsigned char *)p;
  26. return q[0] + (q[1] << 8) + (q[2] << 16) + (q[3] << 24);
  27. }
  28. /* this is a pfb to pfa converter
  29. Reference: Adobe technical note 5040, "Supporting Downloadable PostScript
  30. Language Fonts", page 9 */
  31. static char *
  32. pfb_to_flat (const char *input, int input_size)
  33. {
  34. const unsigned char *in = (unsigned char *)input;
  35. char *flat;
  36. int flat_size, flat_size_max;
  37. int in_idx;
  38. int length;
  39. int i;
  40. const char hextab[16] = "0123456789abcdef";
  41. flat_size = 0;
  42. flat_size_max = 32768;
  43. flat = gt1_new (char, flat_size_max);
  44. for (in_idx = 0; in_idx < input_size;)
  45. {
  46. if (in[in_idx] != 128)
  47. {
  48. gt1_free (flat);
  49. return NULL;
  50. }
  51. switch (in[in_idx + 1])
  52. {
  53. case 1:
  54. length = read_int32_lsb (input + in_idx + 2);
  55. if (flat_size + length > flat_size_max)
  56. {
  57. do
  58. flat_size_max <<= 1;
  59. while (flat_size + length > flat_size_max);
  60. flat = gt1_renew (flat, char, flat_size_max);
  61. }
  62. in_idx += 6;
  63. memcpy (flat + flat_size, in + in_idx, length);
  64. flat_size += length;
  65. in_idx += length;
  66. break;
  67. case 2:
  68. length = read_int32_lsb (input + in_idx + 2);
  69. if (flat_size + length * 3 > flat_size_max)
  70. {
  71. do
  72. flat_size_max <<= 1;
  73. while (flat_size + length * 3 > flat_size_max);
  74. flat = gt1_renew (flat, char, flat_size_max);
  75. }
  76. in_idx += 6;
  77. for (i = 0; i < length; i++)
  78. {
  79. flat[flat_size++] = hextab[in[in_idx] >> 4];
  80. flat[flat_size++] = hextab[in[in_idx] & 15];
  81. in_idx++;
  82. if ((i & 31) == 31 || i == length - 1)
  83. flat[flat_size++] = '\n';
  84. }
  85. break;
  86. case 3:
  87. /* zero terminate the returned string */
  88. if (flat_size == flat_size_max)
  89. gt1_double (flat, char, flat_size_max);
  90. flat[flat_size] = 0;
  91. return flat;
  92. default:
  93. gt1_free (flat);
  94. return NULL;
  95. }
  96. }
  97. return flat;
  98. }
  99. struct _Gt1TokenContext {
  100. char *source;
  101. int index;
  102. int pos;
  103. };
  104. typedef enum {
  105. TOK_NUM,
  106. TOK_STR,
  107. TOK_NAME, /* initial / */
  108. TOK_IDENT,
  109. TOK_OPENBRACE,
  110. TOK_CLOSEBRACE,
  111. TOK_END
  112. } TokenType;
  113. /* we're phasing this out in favor of value.h's Gt1String */
  114. typedef struct _MyGt1String MyGt1String;
  115. struct _MyGt1String {
  116. char *start;
  117. char *fin;
  118. };
  119. static void
  120. tokenize_free (Gt1TokenContext *tc)
  121. {
  122. gt1_free (tc->source);
  123. gt1_free (tc);
  124. }
  125. static Gt1TokenContext *
  126. tokenize_new (const char *input)
  127. {
  128. Gt1TokenContext *tc;
  129. int length;
  130. tc = gt1_new (Gt1TokenContext, 1);
  131. length = strlen (input);
  132. tc->source = gt1_new (char, length + 1);
  133. memcpy (tc->source, input, length + 1);
  134. tc->index = 0;
  135. tc->pos = 0;
  136. return tc;
  137. }
  138. static Gt1TokenContext *
  139. tokenize_new_from_mystring (MyGt1String *input)
  140. {
  141. Gt1TokenContext *tc;
  142. int length;
  143. tc = gt1_new (Gt1TokenContext, 1);
  144. length = input->fin - input->start;
  145. tc->source = gt1_new (char, length + 1);
  146. memcpy (tc->source, input->start, length + 1);
  147. tc->index = 0;
  148. tc->pos = 0;
  149. return tc;
  150. }
  151. /* this returns a TokenType, and sets result to the token contents.
  152. Note: this strips delimiters, like the initial /, and the enclosing ().
  153. */
  154. static TokenType
  155. tokenize_get (Gt1TokenContext *tc, MyGt1String *result)
  156. {
  157. unsigned char *s = (unsigned char *)tc->source;
  158. int index = tc->index;
  159. int pos = tc->pos;
  160. unsigned char c;
  161. TokenType type;
  162. /* skip comments altogether (maybe later we want them, though) */
  163. while (c = s[index], isspace (c) || c == '%')
  164. {
  165. /* skip leading whitespace */
  166. while (isspace (s[index]))
  167. {
  168. if (s[index] == '\r' || s[index] == '\n')
  169. pos = 0;
  170. else
  171. pos++;
  172. index++;
  173. }
  174. if (s[index] == '%')
  175. {
  176. do
  177. /* skip past end-of-line */
  178. {
  179. while (c = s[index], c && c != '\r' && c != '\n')
  180. index++;
  181. if (s[index] != 0) index++;
  182. }
  183. while (s[index] == '%');
  184. }
  185. }
  186. /* skip leading whitespace */
  187. while (c = s[index], isspace (c))
  188. {
  189. if (c == '\r' || c == '\n')
  190. pos = 0;
  191. else
  192. pos++;
  193. index++;
  194. }
  195. /* ok, so now we're at the actual start of a token */
  196. result->start = (char*)s + index;
  197. c = s[index];
  198. if (c == 0)
  199. {
  200. result->fin = (char*)s + index;
  201. type = TOK_END;
  202. }
  203. /* note: GhostScript checks much more strenuously. Further, this
  204. predicate does not pass the valid number -.9 */
  205. else if (isdigit (c) || c == '.' || (c == '-' && isdigit (s[index + 1])))
  206. {
  207. /* numeric token */
  208. while (c = s[index], c && !isspace (c) && c != '{' && c != '/' &&
  209. c != '[' && c != ']' && c != '}')
  210. {
  211. index++;
  212. pos++;
  213. }
  214. result->fin = (char*)s + index;
  215. type = TOK_NUM;
  216. }
  217. else if (c == '/')
  218. {
  219. /* an atom, or whatever that's called */
  220. index++;
  221. result->start = (char*)s + index;
  222. while (c = s[index], c && !isspace (c) && c != '{' && c != '/' &&
  223. c != '[' && c != ']' && c != '}' && c != '(')
  224. {
  225. index++;
  226. pos++;
  227. }
  228. result->fin = (char*)s + index;
  229. type = TOK_NAME;
  230. }
  231. else if (c == '(')
  232. {
  233. int nest;
  234. int backslash;
  235. nest = 1;
  236. index++;
  237. backslash = 0;
  238. result->start = (char*)s + index;
  239. while (c = s[index], c && nest)
  240. {
  241. if (backslash)
  242. backslash = 0;
  243. else if (c == '(')
  244. nest++;
  245. else if (c == ')')
  246. nest--;
  247. else if (c == '\\')
  248. backslash = 1;
  249. index++;
  250. if (c == '\r' || c == '\n')
  251. pos = 0;
  252. else
  253. pos++;
  254. }
  255. /* we could have a c == 0 error case here */
  256. result->fin = (char*)s + index - 1;
  257. type = TOK_STR;
  258. }
  259. else if (c == '{')
  260. {
  261. index++;
  262. result->fin = (char*)s + index;
  263. type = TOK_OPENBRACE;
  264. }
  265. else if (c == '}')
  266. {
  267. index++;
  268. result->fin = (char*)s + index;
  269. type = TOK_CLOSEBRACE;
  270. }
  271. else if (c == '[' || c == ']')
  272. {
  273. index++;
  274. result->fin = (char*)s + index;
  275. type = TOK_IDENT;
  276. }
  277. else
  278. {
  279. /* treat everything else as an identifier */
  280. while (c = s[index], c && !isspace (c) && c != '{' && c != '/' &&
  281. c != '[' && c != ']' && c != '}' && c != '(')
  282. {
  283. index++;
  284. pos++;
  285. }
  286. result->fin = (char*)s + index;
  287. if (isspace(c))
  288. index++; /* skip single trailing whitespace char - this is
  289. useful for readstring */
  290. type = TOK_IDENT;
  291. }
  292. tc->index = index;
  293. tc->pos = pos;
  294. return type;
  295. }
  296. static int
  297. ascii_to_hex (unsigned char c)
  298. {
  299. if (c <= '9') return c - '0';
  300. else if (c >= 'a') return c + 10 - 'a';
  301. else return c + 10 - 'A';
  302. }
  303. /* return a hex byte, or -1 on error */
  304. /* we don't deal with comments here */
  305. static int
  306. tokenize_get_hex_byte (Gt1TokenContext *tc)
  307. {
  308. const unsigned char *s = (const unsigned char *)tc->source;
  309. int index = tc->index;
  310. int pos = tc->pos;
  311. int byte;
  312. /* skip leading whitespace */
  313. while (isspace (s[index]))
  314. {
  315. if (s[index] == '\r' || s[index] == '\n')
  316. pos = 0;
  317. else
  318. pos++;
  319. index++;
  320. }
  321. if (isxdigit (s[index]) && isxdigit (s[index + 1]))
  322. {
  323. byte = (ascii_to_hex (s[index]) << 4) | ascii_to_hex (s[index + 1]);
  324. index += 2;
  325. }
  326. else
  327. byte = -1;
  328. tc->index = index;
  329. tc->pos = pos;
  330. return byte;
  331. }
  332. /* careful, we're _not_ protected against buffer overruns here */
  333. /* todo: fix this, it's definitely a potential security violation.
  334. This almost certainly implies changing the Gt1TokenContext structure
  335. to incorporate a size field, and de-emphasizing the use of
  336. zero-termination */
  337. static void
  338. tokenize_get_raw (Gt1TokenContext *tc, char *buf, int buf_size)
  339. {
  340. memcpy (buf, tc->source + tc->index, buf_size);
  341. tc->index += buf_size;
  342. }
  343. #ifdef DEBUG
  344. static void
  345. print_token (TokenType type, MyGt1String *lexeme)
  346. {
  347. char *start, *fin;
  348. start = lexeme->start;
  349. fin = lexeme->fin;
  350. switch (type)
  351. {
  352. case TOK_NUM:
  353. printf ("number ");
  354. break;
  355. case TOK_IDENT:
  356. printf ("identifier ");
  357. break;
  358. case TOK_NAME:
  359. printf ("name ");
  360. break;
  361. case TOK_STR:
  362. printf ("string ");
  363. break;
  364. case TOK_OPENBRACE:
  365. printf ("open brace ");
  366. break;
  367. case TOK_CLOSEBRACE:
  368. printf ("close brace ");
  369. break;
  370. case TOK_END:
  371. printf ("end ");
  372. break;
  373. default:
  374. break;
  375. }
  376. while (start != fin)
  377. printf ("%c", *start++);
  378. printf ("\n");
  379. }
  380. static void
  381. test_token (const char *flat)
  382. {
  383. Gt1TokenContext *tc;
  384. TokenType type;
  385. MyGt1String lexeme;
  386. tc = tokenize_new (flat);
  387. while (1)
  388. {
  389. type = tokenize_get (tc, &lexeme);
  390. if (type == TOK_END) break;
  391. print_token (type, &lexeme);
  392. }
  393. }
  394. #endif
  395. /* basic PostScript language types */
  396. typedef struct _Gt1ProcStep {
  397. TokenType tok_type;
  398. MyGt1String lexeme;
  399. } Gt1ProcStep;
  400. struct _Gt1Proc {
  401. int n_steps;
  402. /* sooner or later, we'll want to replace proc steps with
  403. plain PostScript values. - probably sooner in fact, because that's
  404. the best way to implement nested procedures, which currently do
  405. not work. */
  406. Gt1Value steps[1];
  407. };
  408. /* low-level PostScript routines */
  409. /* note: resulting array is _uninitialized_ ! */
  410. static Gt1Array *
  411. array_new (Gt1Region *r, int size)
  412. {
  413. Gt1Array *array;
  414. array = (Gt1Array *)gt1_region_alloc (r, sizeof(Gt1Array) +
  415. (size - 1) * sizeof(Gt1Value));
  416. array->n_values = size;
  417. return array;
  418. }
  419. struct _Gt1PSContext {
  420. Gt1Region *r; /* the region all PS values are allocated into */
  421. Gt1TokenContext *tc; /* this is for readstring, eexec, etc. */
  422. Gt1NameContext *nc; /* the context for all names */
  423. Gt1Value *value_stack;
  424. int n_values, n_values_max;
  425. /* ghostscript also has an execution stack - what's that? */
  426. Gt1Dict **gt1_dict_stack;
  427. int n_dicts, n_dicts_max;
  428. /* a special dict that holds all the fonts */
  429. Gt1Dict *fonts;
  430. Gt1TokenContext **file_stack; /* invariant: top of file stack == tc */
  431. int n_files, n_files_max;
  432. int quit; /* maybe this should be a string, for error messages too */
  433. };
  434. /* a very basic PostScript interpreter */
  435. /* make sure that value stack has enough room for pushing n values. */
  436. static void
  437. ensure_stack (Gt1PSContext *psc, int n)
  438. {
  439. if (psc->n_values + n == psc->n_values_max)
  440. {
  441. psc->n_values_max <<= 1;
  442. psc->value_stack = gt1_renew (psc->value_stack, Gt1Value, psc->n_values_max);
  443. }
  444. }
  445. static double
  446. parse_num (MyGt1String *number)
  447. {
  448. double sign;
  449. double mantissa;
  450. double decimal;
  451. int exp_sign;
  452. int exp;
  453. int i, length;
  454. const unsigned char *start;
  455. start = (const unsigned char *)number->start;
  456. length = number->fin - number->start;
  457. i = 0;
  458. sign = 1;
  459. if (i < length && start[i] == '-')
  460. {
  461. sign = -1;
  462. i++;
  463. }
  464. else if (i < length && start[i] == '+')
  465. i++;
  466. mantissa = 0;
  467. while (i < length && isdigit (start[i]))
  468. {
  469. mantissa = (mantissa * 10) + start[i] - '0';
  470. i++;
  471. }
  472. if (i < length && start[i] == '.')
  473. {
  474. i++;
  475. decimal = 1;
  476. while (i < length && isdigit (start[i]))
  477. {
  478. decimal *= 0.1;
  479. mantissa += (start[i] - '0') * decimal;
  480. i++;
  481. }
  482. }
  483. if (i < length && (start[i] == 'e' || start[i] == 'E'))
  484. {
  485. i++;
  486. exp_sign = 1;
  487. if (i < length && start[i] == '-')
  488. {
  489. exp_sign = -1;
  490. i++;
  491. }
  492. else if (i < length && start[i] == '+')
  493. i++;
  494. exp = 0;
  495. while (i < length && isdigit (start[i]))
  496. {
  497. exp = (exp * 10) + start[i] - '0';
  498. i++;
  499. }
  500. mantissa *= pow (10, exp * exp_sign);
  501. }
  502. return sign * mantissa;
  503. }
  504. #ifdef DEBUG
  505. static void
  506. print_mystring (MyGt1String *str)
  507. {
  508. char *start, *fin;
  509. start = str->start;
  510. fin = str->fin;
  511. while (start != fin)
  512. printf ("%c", *start++);
  513. }
  514. #endif
  515. static void
  516. print_string (Gt1String *str)
  517. {
  518. char *start;
  519. int size;
  520. int i;
  521. start = str->start;
  522. size = str->size;
  523. for (i = 0; i < size; i++);
  524. printf ("%c", start[i]);
  525. }
  526. static void
  527. print_value (Gt1PSContext *psc, Gt1Value *val)
  528. {
  529. switch (val->type)
  530. {
  531. case GT1_VAL_NUM:
  532. printf ("%g", val->val.num_val);
  533. break;
  534. case GT1_VAL_BOOL:
  535. printf ("%s", val->val.bool_val ? "true" : "false");
  536. break;
  537. case GT1_VAL_STR:
  538. printf ("\"");
  539. print_string (&val->val.str_val);
  540. printf ("\"");
  541. break;
  542. case GT1_VAL_NAME:
  543. printf ("/%s", gt1_name_context_string (psc->nc, val->val.name_val));
  544. break;
  545. case GT1_VAL_UNQ_NAME:
  546. printf ("%s", gt1_name_context_string (psc->nc, val->val.name_val));
  547. break;
  548. case GT1_VAL_DICT:
  549. printf ("<dictionary %d/%d>",
  550. val->val.dict_val->n_entries,
  551. val->val.dict_val->n_entries_max);
  552. break;
  553. case GT1_VAL_ARRAY:
  554. printf ("<array>");
  555. break;
  556. case GT1_VAL_PROC:
  557. #if 1
  558. printf ("<proc>");
  559. #else
  560. printf ("{ ");
  561. { int i;
  562. for (i = 0; i < val->val.proc_val->n_values; i++)
  563. {
  564. print_value (psc, &val->val.proc_val->vals[i]);
  565. printf (" ");
  566. }
  567. printf ("}");
  568. }
  569. #endif
  570. break;
  571. case GT1_VAL_FILE:
  572. printf ("<file>");
  573. break;
  574. case GT1_VAL_INTERNAL:
  575. printf ("<internal function>");
  576. case GT1_VAL_MARK:
  577. printf ("<mark>");
  578. break;
  579. default:
  580. printf ("???%d", val->type);
  581. }
  582. }
  583. #ifdef DEBUG
  584. static void
  585. print_token_short (TokenType type, MyGt1String *lexeme)
  586. {
  587. char *start, *fin;
  588. start = lexeme->start;
  589. fin = lexeme->fin;
  590. switch (type)
  591. {
  592. case TOK_NUM:
  593. print_mystring (lexeme);
  594. break;
  595. case TOK_IDENT:
  596. print_mystring (lexeme);
  597. break;
  598. case TOK_NAME:
  599. printf ("/");
  600. print_mystring (lexeme);
  601. break;
  602. case TOK_STR:
  603. printf ("(");
  604. print_mystring (lexeme);
  605. printf (")");
  606. break;
  607. case TOK_OPENBRACE:
  608. printf ("{");
  609. break;
  610. case TOK_CLOSEBRACE:
  611. printf ("}");
  612. break;
  613. case TOK_END:
  614. printf ("end ");
  615. break;
  616. default:
  617. break;
  618. }
  619. }
  620. #endif
  621. static void
  622. print_value_deep (Gt1PSContext *psc, Gt1Value *val, int nest)
  623. {
  624. int i, j;
  625. for (i = 0; i < nest; i++)
  626. printf (" ");
  627. switch (val->type)
  628. {
  629. case GT1_VAL_NUM:
  630. printf ("%g", val->val.num_val);
  631. break;
  632. case GT1_VAL_BOOL:
  633. printf ("%s", val->val.bool_val ? "true" : "false");
  634. break;
  635. case GT1_VAL_STR:
  636. printf ("\"");
  637. print_string (&val->val.str_val);
  638. printf ("\"");
  639. break;
  640. case GT1_VAL_NAME:
  641. printf ("/%s", gt1_name_context_string (psc->nc, val->val.name_val));
  642. break;
  643. case GT1_VAL_UNQ_NAME:
  644. printf ("%s", gt1_name_context_string (psc->nc, val->val.name_val));
  645. break;
  646. case GT1_VAL_DICT:
  647. printf ("<dictionary %d/%d> [\n",
  648. val->val.dict_val->n_entries,
  649. val->val.dict_val->n_entries_max);
  650. for (i = 0; i < val->val.dict_val->n_entries; i++)
  651. {
  652. for (j = 0; j < nest; j++)
  653. printf (" ");
  654. printf ("key %d\n", val->val.dict_val->entries[i].key);
  655. print_value_deep (psc, &val->val.dict_val->entries[i].val, nest + 1);
  656. }
  657. for (j = 0; j < nest; j++)
  658. printf (" ");
  659. printf ("]");
  660. break;
  661. case GT1_VAL_ARRAY:
  662. printf ("[\n");
  663. for (i = 0; i < val->val.array_val->n_values; i++)
  664. {
  665. print_value_deep (psc, &val->val.array_val->vals[i], nest + 1);
  666. }
  667. for (j = 0; j < nest; j++)
  668. printf (" ");
  669. printf ("]");
  670. break;
  671. case GT1_VAL_PROC:
  672. printf ("{\n");
  673. for (i = 0; i < val->val.proc_val->n_values; i++)
  674. {
  675. print_value_deep (psc, &val->val.proc_val->vals[i], nest + 1);
  676. }
  677. for (j = 0; j < nest; j++)
  678. printf (" ");
  679. printf ("}");
  680. break;
  681. case GT1_VAL_FILE:
  682. printf ("<file>");
  683. break;
  684. case GT1_VAL_INTERNAL:
  685. printf ("<internal function>");
  686. case GT1_VAL_MARK:
  687. printf ("<mark>");
  688. break;
  689. default:
  690. printf ("???");
  691. }
  692. printf ("\n");
  693. }
  694. #ifdef DEBUG
  695. static void
  696. print_stack (Gt1PSContext *psc)
  697. {
  698. int i;
  699. for (i = 0; i < psc->n_values; i++)
  700. {
  701. print_value (psc, &psc->value_stack[i]);
  702. if (i != psc->n_values - 1)
  703. printf (" ");
  704. }
  705. printf ("\n");
  706. }
  707. #endif
  708. static void
  709. eval_ps_val (Gt1PSContext *psc, Gt1Value *val);
  710. static void
  711. eval_proc (Gt1PSContext *psc, Gt1Proc *proc)
  712. {
  713. int i;
  714. #ifdef VERBOSE
  715. printf ("begin proc evaluation\n");
  716. #endif
  717. for (i = 0; !psc->quit && i < proc->n_values; i++)
  718. eval_ps_val (psc, &proc->vals[i]);
  719. #ifdef VERBOSE
  720. printf ("end proc evaluation\n");
  721. #endif
  722. }
  723. static Gt1Value *
  724. gt1_dict_stack_lookup (Gt1PSContext *psc, Gt1NameId key)
  725. {
  726. int i;
  727. Gt1Value *val;
  728. for (i = psc->n_dicts - 1; i >= 0; i--)
  729. {
  730. val = gt1_dict_lookup (psc->gt1_dict_stack[i], key);
  731. if (val != NULL)
  732. return val;
  733. }
  734. return NULL;
  735. }
  736. /* return 1 on success, with result set to the top of the value stack */
  737. static int
  738. get_stack_number (Gt1PSContext *psc, double *result, int index)
  739. {
  740. if (psc->n_values < index)
  741. {
  742. printf ("stack underflow\n");
  743. psc->quit = 1;
  744. return 0;
  745. }
  746. if (psc->value_stack[psc->n_values - index].type != GT1_VAL_NUM)
  747. {
  748. printf ("type error - expecting number\n");
  749. psc->quit = 1;
  750. return 0;
  751. }
  752. *result = psc->value_stack[psc->n_values - index].val.num_val;
  753. return 1;
  754. }
  755. /* return 1 on success, with result set to the top of the value stack */
  756. static int
  757. get_stack_dict (Gt1PSContext *psc, Gt1Dict **result, int index)
  758. {
  759. if (psc->n_values < index)
  760. {
  761. printf ("stack underflow\n");
  762. psc->quit = 1;
  763. return 0;
  764. }
  765. if (psc->value_stack[psc->n_values - index].type != GT1_VAL_DICT)
  766. {
  767. printf ("type error - expecting dict\n");
  768. psc->quit = 1;
  769. return 0;
  770. }
  771. *result = psc->value_stack[psc->n_values - index].val.dict_val;
  772. return 1;
  773. }
  774. /* return 1 on success, with result set to the top of the value stack */
  775. static int
  776. get_stack_name (Gt1PSContext *psc, Gt1NameId *result, int index)
  777. {
  778. if (psc->n_values < index)
  779. {
  780. printf ("stack underflow\n");
  781. psc->quit = 1;
  782. return 0;
  783. }
  784. if (psc->value_stack[psc->n_values - index].type != GT1_VAL_NAME)
  785. {
  786. printf ("type error - expecting atom\n");
  787. psc->quit = 1;
  788. return 0;
  789. }
  790. *result = psc->value_stack[psc->n_values - index].val.name_val;
  791. return 1;
  792. }
  793. /* return 1 on success, with result set to the top of the value stack */
  794. static int
  795. get_stack_file (Gt1PSContext *psc, Gt1TokenContext **result, int index)
  796. {
  797. if (psc->n_values < index)
  798. {
  799. printf ("stack underflow\n");
  800. psc->quit = 1;
  801. return 0;
  802. }
  803. if (psc->value_stack[psc->n_values - index].type != GT1_VAL_FILE)
  804. {
  805. printf ("type error - expecting file\n");
  806. psc->quit = 1;
  807. return 0;
  808. }
  809. *result = psc->value_stack[psc->n_values - index].val.file_val;
  810. return 1;
  811. }
  812. /* return 1 on success, with result set to the top of the value stack */
  813. static int
  814. get_stack_string (Gt1PSContext *psc, Gt1String *result, int index)
  815. {
  816. if (psc->n_values < index)
  817. {
  818. printf ("stack underflow\n");
  819. psc->quit = 1;
  820. return 0;
  821. }
  822. if (psc->value_stack[psc->n_values - index].type != GT1_VAL_STR)
  823. {
  824. printf ("type error - expecting string\n");
  825. psc->quit = 1;
  826. return 0;
  827. }
  828. *result = psc->value_stack[psc->n_values - index].val.str_val;
  829. return 1;
  830. }
  831. /* return 1 on success, with result set to the top of the value stack */
  832. static int
  833. get_stack_array (Gt1PSContext *psc, Gt1Array **result, int index)
  834. {
  835. if (psc->n_values < index)
  836. {
  837. printf ("stack underflow\n");
  838. psc->quit = 1;
  839. return 0;
  840. }
  841. if (psc->value_stack[psc->n_values - index].type != GT1_VAL_ARRAY)
  842. {
  843. printf ("type error - expecting array\n");
  844. psc->quit = 1;
  845. return 0;
  846. }
  847. *result = psc->value_stack[psc->n_values - index].val.array_val;
  848. return 1;
  849. }
  850. /* return 1 on success, with result set to the top of the value stack */
  851. static int
  852. get_stack_bool (Gt1PSContext *psc, int *result, int index)
  853. {
  854. if (psc->n_values < index)
  855. {
  856. printf ("stack underflow\n");
  857. psc->quit = 1;
  858. return 0;
  859. }
  860. if (psc->value_stack[psc->n_values - index].type != GT1_VAL_BOOL)
  861. {
  862. printf ("type error - expecting bool\n");
  863. psc->quit = 1;
  864. return 0;
  865. }
  866. *result = psc->value_stack[psc->n_values - index].val.bool_val;
  867. return 1;
  868. }
  869. /* return 1 on success, with result set to the top of the value stack */
  870. static int
  871. get_stack_proc (Gt1PSContext *psc, Gt1Proc **result, int index)
  872. {
  873. if (psc->n_values < index)
  874. {
  875. printf ("stack underflow\n");
  876. psc->quit = 1;
  877. return 0;
  878. }
  879. if (psc->value_stack[psc->n_values - index].type != GT1_VAL_PROC)
  880. {
  881. printf ("type error - expecting proc\n");
  882. psc->quit = 1;
  883. return 0;
  884. }
  885. *result = psc->value_stack[psc->n_values - index].val.proc_val;
  886. return 1;
  887. }
  888. /* here begin the internal procedures */
  889. static void
  890. internal_dict (Gt1PSContext *psc)
  891. {
  892. Gt1Dict *dict;
  893. double d_size;
  894. if (get_stack_number (psc, &d_size, 1))
  895. {
  896. dict = gt1_dict_new (psc->r, (int)d_size);
  897. psc->value_stack[psc->n_values - 1].type = GT1_VAL_DICT;
  898. psc->value_stack[psc->n_values - 1].val.dict_val = dict;
  899. }
  900. }
  901. static void
  902. internal_begin (Gt1PSContext *psc)
  903. {
  904. Gt1Dict *dict;
  905. if (get_stack_dict (psc, &dict, 1))
  906. {
  907. if (psc->n_dicts == psc->n_dicts_max)
  908. gt1_double (psc->gt1_dict_stack, Gt1Dict *, psc->n_dicts_max);
  909. psc->gt1_dict_stack[psc->n_dicts++] = dict;
  910. psc->n_values--;
  911. }
  912. }
  913. static void
  914. internal_end (Gt1PSContext *psc)
  915. {
  916. /* note: this magic constant changes if we separate out the internal
  917. dict from the user one; in fact, GhostScript uses three. */
  918. if (psc->n_dicts == 1)
  919. {
  920. printf ("dict stack underflow\n");
  921. psc->quit = 1;
  922. }
  923. psc->n_dicts--;
  924. }
  925. static void
  926. internal_dup (Gt1PSContext *psc)
  927. {
  928. if (psc->n_values == 0)
  929. {
  930. printf ("stack underflow\n");
  931. psc->quit = 1;
  932. }
  933. else
  934. {
  935. ensure_stack (psc, 1);
  936. psc->value_stack[psc->n_values] =
  937. psc->value_stack[psc->n_values - 1];
  938. psc->n_values++;
  939. }
  940. }
  941. static void
  942. internal_pop (Gt1PSContext *psc)
  943. {
  944. if (psc->n_values == 0)
  945. {
  946. printf ("stack underflow\n");
  947. psc->quit = 1;
  948. }
  949. else
  950. psc->n_values--;
  951. }
  952. static void
  953. internal_exch (Gt1PSContext *psc)
  954. {
  955. Gt1Value tmp;
  956. int stack_size;
  957. stack_size = psc->n_values;
  958. if (stack_size < 2)
  959. {
  960. printf ("stack underflow\n");
  961. psc->quit = 1;
  962. }
  963. else
  964. {
  965. tmp = psc->value_stack[stack_size - 2];
  966. psc->value_stack[stack_size - 2] =
  967. psc->value_stack[stack_size - 1];
  968. psc->value_stack[stack_size - 1] = tmp;
  969. }
  970. }
  971. /* this doesn't do anything - we don't enforce readonly */
  972. static void
  973. internal_readonly (Gt1PSContext *psc)
  974. {
  975. if (psc->n_values == 0)
  976. {
  977. printf ("stack underflow\n");
  978. psc->quit = 1;
  979. }
  980. }
  981. /* this doesn't do anything - we don't enforce executeonly */
  982. static void
  983. internal_executeonly (Gt1PSContext *psc)
  984. {
  985. if (psc->n_values == 0)
  986. {
  987. printf ("stack underflow\n");
  988. psc->quit = 1;
  989. }
  990. }
  991. /* this doesn't do anything - we don't enforce noaccess */
  992. static void
  993. internal_noaccess (Gt1PSContext *psc)
  994. {
  995. if (psc->n_values == 0)
  996. {
  997. printf ("stack underflow\n");
  998. psc->quit = 1;
  999. }
  1000. }
  1001. static void
  1002. internal_def (Gt1PSContext *psc)
  1003. {
  1004. Gt1NameId key;
  1005. Gt1Dict *dict;
  1006. if (get_stack_name (psc, &key, 2))
  1007. {
  1008. dict = psc->gt1_dict_stack[psc->n_dicts - 1];
  1009. gt1_dict_def (psc->r, dict, key, &psc->value_stack[psc->n_values - 1]);
  1010. psc->n_values -= 2;
  1011. }
  1012. }
  1013. static void
  1014. internal_false (Gt1PSContext *psc)
  1015. {
  1016. ensure_stack (psc, 1);
  1017. psc->value_stack[psc->n_values].type = GT1_VAL_BOOL;
  1018. psc->value_stack[psc->n_values].val.bool_val = gt1_false;
  1019. psc->n_values++;
  1020. }
  1021. static void
  1022. internal_true (Gt1PSContext *psc)
  1023. {
  1024. ensure_stack (psc, 1);
  1025. psc->value_stack[psc->n_values].type = GT1_VAL_BOOL;
  1026. psc->value_stack[psc->n_values].val.bool_val = gt1_true;
  1027. psc->n_values++;
  1028. }
  1029. static void
  1030. internal_StandardEncoding (Gt1PSContext *psc)
  1031. {
  1032. ensure_stack (psc, 1);
  1033. /* todo: push actual encoding array */
  1034. psc->value_stack[psc->n_values].type = GT1_VAL_NUM;
  1035. psc->value_stack[psc->n_values].val.num_val = 42;
  1036. psc->n_values++;
  1037. }
  1038. static void
  1039. internalop_openbracket (Gt1PSContext *psc)
  1040. {
  1041. ensure_stack (psc, 1);
  1042. psc->value_stack[psc->n_values].type = GT1_VAL_MARK;
  1043. psc->n_values++;
  1044. }
  1045. static void
  1046. internalop_closebracket (Gt1PSContext *psc)
  1047. {
  1048. int i;
  1049. Gt1Array *array;
  1050. int size, start_idx;
  1051. for (i = psc->n_values - 1; i >= 0; i--)
  1052. if (psc->value_stack[i].type == GT1_VAL_MARK)
  1053. break;
  1054. if (psc->value_stack[i].type != GT1_VAL_MARK)
  1055. {
  1056. printf ("unmatched mark\n");
  1057. psc->quit = 1;
  1058. }
  1059. start_idx = i + 1;
  1060. size = psc->n_values - start_idx;
  1061. array = array_new (psc->r, size);
  1062. for (i = 0; i < size; i++)
  1063. array->vals[i] = psc->value_stack[start_idx + i];
  1064. psc->n_values -= size;
  1065. psc->value_stack[psc->n_values - 1].type = GT1_VAL_ARRAY;
  1066. psc->value_stack[psc->n_values - 1].val.array_val = array;
  1067. }
  1068. static void
  1069. internal_currentdict (Gt1PSContext *psc)
  1070. {
  1071. ensure_stack (psc, 1);
  1072. psc->value_stack[psc->n_values].type = GT1_VAL_DICT;
  1073. psc->value_stack[psc->n_values].val.dict_val =
  1074. psc->gt1_dict_stack[psc->n_dicts - 1];
  1075. psc->n_values++;
  1076. }
  1077. static void
  1078. internal_currentfile (Gt1PSContext *psc)
  1079. {
  1080. /* todo: we want to move away from a tc pointer towards tags, to avoid
  1081. potential security holes from misusing these data structures */
  1082. ensure_stack (psc, 1);
  1083. psc->value_stack[psc->n_values].type = GT1_VAL_FILE;
  1084. psc->value_stack[psc->n_values].val.file_val = psc->tc;
  1085. psc->n_values++;
  1086. }
  1087. #define EEXEC_C1 ((unsigned short)52845)
  1088. #define EEXEC_C2 ((unsigned short)22719)
  1089. /* return number of bytes in result */
  1090. static int
  1091. decrypt_eexec (char *plaintext, const char *ciphertext, int ciphertext_size)
  1092. {
  1093. int i;
  1094. unsigned short r;
  1095. unsigned char cipher;
  1096. unsigned char plain;
  1097. r = 55665; /* initial key */
  1098. for (i = 0; i < ciphertext_size; i++)
  1099. {
  1100. cipher = ciphertext[i];
  1101. plain = (cipher ^ (r>>8));
  1102. r = (cipher + r) * EEXEC_C1 + EEXEC_C2;
  1103. if (i >= 4)
  1104. plaintext[i - 4] = plain;
  1105. }
  1106. return ciphertext_size - 4;
  1107. }
  1108. /* this one is great fun! */
  1109. static void
  1110. internal_eexec (Gt1PSContext *psc)
  1111. {
  1112. Gt1TokenContext *file_tc;
  1113. char *ciphertext;
  1114. int ciphertext_size, ciphertext_size_max;
  1115. char *plaintext;
  1116. int plaintext_size;
  1117. int num_nulls;
  1118. int byte;
  1119. MyGt1String string;
  1120. Gt1TokenContext *new_tc;
  1121. if (get_stack_file (psc, &file_tc, 1))
  1122. {
  1123. psc->n_values--;
  1124. /* first, suck the encrypted stream from the specified file */
  1125. ciphertext_size = 0;
  1126. ciphertext_size_max = 512;
  1127. ciphertext = gt1_new (char, ciphertext_size_max);
  1128. num_nulls = 0;
  1129. while (num_nulls < 16)
  1130. {
  1131. if (ciphertext_size == ciphertext_size_max)
  1132. gt1_double (ciphertext, char, ciphertext_size_max);
  1133. byte = tokenize_get_hex_byte (file_tc);
  1134. if (byte < 0)
  1135. {
  1136. printf ("eexec input appears to be truncated\n");
  1137. psc->quit = 1;
  1138. return;
  1139. }
  1140. if (byte == 0)
  1141. num_nulls++;
  1142. else
  1143. num_nulls = 0;
  1144. ciphertext[ciphertext_size++] = byte;
  1145. }
  1146. /* then, decrypt it */
  1147. plaintext = gt1_new (char, ciphertext_size);
  1148. plaintext_size = decrypt_eexec (plaintext, ciphertext, ciphertext_size);
  1149. gt1_free (ciphertext);
  1150. #if 1 && defined(VERBOSE)
  1151. fwrite (plaintext, 1, plaintext_size, stdout);
  1152. #endif
  1153. /* finally, create a new Gt1TokenContext for the string, and switch
  1154. to executing it. */
  1155. string.start = plaintext;
  1156. string.fin = plaintext + plaintext_size;
  1157. new_tc = tokenize_new_from_mystring (&string);
  1158. gt1_free (plaintext);
  1159. if (psc->n_files_max == psc->n_files)
  1160. {
  1161. printf ("overflow of file stack\n");
  1162. psc->quit = 1;
  1163. return;
  1164. }
  1165. psc->file_stack[psc->n_files++] = new_tc;
  1166. psc->tc = new_tc;
  1167. /* alternatively, we could have recursively called the PostScript
  1168. evaluation loop from here, but this seems to be just as good. */
  1169. }
  1170. }
  1171. static void
  1172. internal_array (Gt1PSContext *psc)
  1173. {
  1174. Gt1Array *array;
  1175. double d_size;
  1176. if (get_stack_number (psc, &d_size, 1))
  1177. {
  1178. array = array_new (psc->r, (int)d_size);
  1179. psc->value_stack[psc->n_values - 1].type = GT1_VAL_ARRAY;
  1180. psc->value_stack[psc->n_values - 1].val.array_val = array;
  1181. }
  1182. }
  1183. static void
  1184. internal_string (Gt1PSContext *psc)
  1185. {
  1186. Gt1String string;
  1187. double d_size;
  1188. int size;
  1189. if (get_stack_number (psc, &d_size, 1))
  1190. {
  1191. size = (int)d_size;
  1192. string.start = gt1_region_alloc (psc->r, size);
  1193. string.size = size;
  1194. memset (string.start, 0, size);
  1195. psc->value_stack[psc->n_values - 1].type = GT1_VAL_STR;
  1196. psc->value_stack[psc->n_values - 1].val.str_val = string;
  1197. }
  1198. }
  1199. static void
  1200. internal_readstring (Gt1PSContext *psc)
  1201. {
  1202. Gt1String string;
  1203. Gt1TokenContext *file_tc;
  1204. if (get_stack_string (psc, &string, 1) &&
  1205. get_stack_file (psc, &file_tc, 2))
  1206. {
  1207. tokenize_get_raw (file_tc, string.start, string.size);
  1208. psc->value_stack[psc->n_values - 2].type = GT1_VAL_STR;
  1209. psc->value_stack[psc->n_values - 2].val.str_val = string;
  1210. psc->value_stack[psc->n_values - 1].type = GT1_VAL_BOOL;
  1211. psc->value_stack[psc->n_values - 1].val.bool_val = gt1_true;
  1212. }
  1213. }
  1214. static void
  1215. internal_put (Gt1PSContext *psc)
  1216. {
  1217. Gt1Array *array;
  1218. double d_index;
  1219. int index;
  1220. Gt1Dict *dict;
  1221. Gt1NameId key;
  1222. if (psc->n_values >= 3 &&
  1223. psc->value_stack[psc->n_values - 3].type == GT1_VAL_DICT &&
  1224. get_stack_name (psc, &key, 2))
  1225. {
  1226. /* dict key val put -- */
  1227. get_stack_dict (psc, &dict, 3);
  1228. gt1_dict_def (psc->r, dict, key, &psc->value_stack[psc->n_values - 1]);
  1229. psc->n_values -= 3;
  1230. }
  1231. else if (psc->n_values >= 3 &&
  1232. psc->value_stack[psc->n_values - 3].type == GT1_VAL_PROC &&
  1233. get_stack_number (psc, &d_index, 2))
  1234. {
  1235. array = psc->value_stack[psc->n_values - 3].val.proc_val;
  1236. index = (int)d_index;
  1237. if (index < 0 || index >= array->n_values)
  1238. {
  1239. printf ("range check\n");
  1240. psc->quit = 1;
  1241. return;
  1242. }
  1243. array->vals[index] = psc->value_stack[psc->n_values - 1];
  1244. psc->n_values -= 3;
  1245. }
  1246. else if (psc->n_values >= 3 &&
  1247. get_stack_array (psc, &array, 3) &&
  1248. get_stack_number (psc, &d_index, 2))
  1249. {
  1250. /* array index val put -- */
  1251. index = (int)d_index;
  1252. if (index < 0 || index >= array->n_values)
  1253. {
  1254. printf ("range check\n");
  1255. psc->quit = 1;
  1256. return;
  1257. }
  1258. array->vals[index] = psc->value_stack[psc->n_values - 1];
  1259. psc->n_values -= 3;
  1260. }
  1261. }
  1262. static void
  1263. internal_get (Gt1PSContext *psc)
  1264. {
  1265. Gt1Array *array;
  1266. double d_index;
  1267. int index;
  1268. Gt1Dict *dict;
  1269. Gt1NameId key;
  1270. Gt1Value *val;
  1271. if (psc->n_values >= 2 &&
  1272. psc->value_stack[psc->n_values - 2].type == GT1_VAL_DICT &&
  1273. get_stack_name (psc, &key, 1))
  1274. {
  1275. /* dict key get val */
  1276. get_stack_dict (psc, &dict, 2);
  1277. val = gt1_dict_lookup (dict, key);
  1278. if (val == NULL)
  1279. {
  1280. printf ("key not found\n");
  1281. psc->quit = 1;
  1282. return;
  1283. }
  1284. #ifdef VERBOSE
  1285. printf ("value: ");
  1286. print_value (psc, val);
  1287. printf ("\n");
  1288. #endif
  1289. psc->n_values -= 1;
  1290. psc->value_stack[psc->n_values - 1] = *val;
  1291. }
  1292. else if (psc->n_values >= 2 &&
  1293. psc->value_stack[psc->n_values - 2].type == GT1_VAL_PROC &&
  1294. get_stack_number (psc, &d_index, 1))
  1295. {
  1296. /* array index get val */
  1297. array = psc->value_stack[psc->n_values - 2].val.proc_val;
  1298. index = (int)d_index;
  1299. if (index < 0 || index >= array->n_values)
  1300. {
  1301. printf ("range check\n");
  1302. psc->quit = 1;
  1303. return;
  1304. }
  1305. psc->n_values -= 1;
  1306. psc->value_stack[psc->n_values - 1] = array->vals[index];
  1307. }
  1308. else if (get_stack_array (psc, &array, 2) &&
  1309. get_stack_number (psc, &d_index, 1))
  1310. {
  1311. /* array index get val */
  1312. index = (int)d_index;
  1313. if (index < 0 || index >= array->n_values)
  1314. {
  1315. printf ("range check\n");
  1316. psc->quit = 1;
  1317. return;
  1318. }
  1319. psc->n_values -= 1;
  1320. psc->value_stack[psc->n_values - 1] = array->vals[index];
  1321. }
  1322. }
  1323. static void
  1324. internal_index (Gt1PSContext *psc)
  1325. {
  1326. double d_index;
  1327. int index;
  1328. if (get_stack_number (psc, &d_index, 1))
  1329. {
  1330. index = (int)d_index;
  1331. if (index < 0 || index > psc->n_values - 2)
  1332. {
  1333. printf ("index range check\n");
  1334. psc->quit = 1;
  1335. return;
  1336. }
  1337. psc->value_stack[psc->n_values - 1] =
  1338. psc->value_stack[psc->n_values - (index + 2)];
  1339. }
  1340. }
  1341. static void
  1342. internal_definefont (Gt1PSContext *psc)
  1343. {
  1344. Gt1NameId key;
  1345. Gt1Dict *dict;
  1346. if (psc->n_values < 2)
  1347. {
  1348. printf ("stack underflow\n");
  1349. psc->quit = 1;
  1350. }
  1351. else if (get_stack_name (psc, &key, 2))
  1352. {
  1353. dict = psc->fonts;
  1354. gt1_dict_def (psc->r, dict, key, &psc->value_stack[psc->n_values - 1]);
  1355. #ifdef VERBOSE
  1356. print_value_deep (psc, &psc->value_stack[psc->n_values - 1], 0);
  1357. #endif
  1358. psc->n_values -= 1;
  1359. }
  1360. }
  1361. static void
  1362. internal_mark (Gt1PSContext *psc)
  1363. {
  1364. ensure_stack (psc, 1);
  1365. psc->value_stack[psc->n_values].type = GT1_VAL_MARK;
  1366. psc->n_values++;
  1367. }
  1368. static void
  1369. internal_closefile (Gt1PSContext *psc)
  1370. {
  1371. Gt1TokenContext *tc;
  1372. if (get_stack_file (psc, &tc, 1))
  1373. {
  1374. if (psc->n_files == 1)
  1375. {
  1376. printf ("file stack underflow\n");
  1377. psc->quit = 1;
  1378. }
  1379. else if (psc->file_stack[psc->n_files - 1] == tc)
  1380. {
  1381. /* pop the file stack */
  1382. tokenize_free (psc->tc);
  1383. psc->n_files--;
  1384. psc->tc = psc->file_stack[psc->n_files - 1];
  1385. psc->n_values--;
  1386. }
  1387. else
  1388. {
  1389. printf ("closefile: whoa, file cowboy!\n");
  1390. psc->quit = 1;
  1391. }
  1392. }
  1393. }
  1394. static void
  1395. internal_cleartomark (Gt1PSContext *psc)
  1396. {
  1397. int i;
  1398. for (i = psc->n_values - 1; i >= 0; i--)
  1399. if (psc->value_stack[i].type == GT1_VAL_MARK)
  1400. break;
  1401. if (psc->value_stack[i].type != GT1_VAL_MARK)
  1402. {
  1403. printf ("cleartomark: unmatched mark\n");
  1404. psc->quit = 1;
  1405. }
  1406. psc->n_values = i;
  1407. }
  1408. static void
  1409. internal_systemdict (Gt1PSContext *psc)
  1410. {
  1411. ensure_stack (psc, 1);
  1412. psc->value_stack[psc->n_values].type = GT1_VAL_DICT;
  1413. psc->value_stack[psc->n_values].val.dict_val =
  1414. psc->gt1_dict_stack[0];
  1415. psc->n_values++;
  1416. }
  1417. static void
  1418. internal_userdict (Gt1PSContext *psc)
  1419. {
  1420. ensure_stack (psc, 1);
  1421. psc->value_stack[psc->n_values].type = GT1_VAL_DICT;
  1422. psc->value_stack[psc->n_values].val.dict_val =
  1423. psc->gt1_dict_stack[2];
  1424. psc->n_values++;
  1425. }
  1426. static void
  1427. internal_known (Gt1PSContext *psc)
  1428. {
  1429. Gt1NameId key;
  1430. Gt1Dict *dict;
  1431. int known;
  1432. if (psc->n_values >= 2 &&
  1433. get_stack_dict (psc, &dict, 2) &&
  1434. get_stack_name (psc, &key, 1))
  1435. {
  1436. known = (gt1_dict_lookup (dict, key) != 0);
  1437. psc->n_values -= 1;
  1438. psc->value_stack[psc->n_values - 1].type = GT1_VAL_BOOL;
  1439. psc->value_stack[psc->n_values - 1].val.bool_val = known;
  1440. }
  1441. }
  1442. static void
  1443. internal_ifelse (Gt1PSContext *psc)
  1444. {
  1445. Gt1Proc *proc1, *proc2;
  1446. int bool;
  1447. if (psc->n_values >= 3 &&
  1448. get_stack_bool (psc, &bool, 3) &&
  1449. get_stack_proc (psc, &proc1, 2) &&
  1450. get_stack_proc (psc, &proc2, 1))
  1451. {
  1452. psc->n_values -= 3;
  1453. if (bool)
  1454. eval_proc (psc, proc1);
  1455. else
  1456. eval_proc (psc, proc2);
  1457. }
  1458. }
  1459. static void
  1460. internal_if (Gt1PSContext *psc)
  1461. {
  1462. Gt1Proc *proc;
  1463. int bool;
  1464. if (psc->n_values >= 2 &&
  1465. get_stack_bool (psc, &bool, 2) &&
  1466. get_stack_proc (psc, &proc, 1))
  1467. {
  1468. psc->n_values -= 2;
  1469. if (bool)
  1470. eval_proc (psc, proc);
  1471. }
  1472. }
  1473. static void
  1474. internal_for (Gt1PSContext *psc)
  1475. {
  1476. double initial, increment, limit;
  1477. Gt1Proc *proc;
  1478. double val;
  1479. if (psc->n_values >= 4 &&
  1480. get_stack_number (psc, &initial, 4) &&
  1481. get_stack_number (psc, &increment, 3) &&
  1482. get_stack_number (psc, &limit, 2) &&
  1483. get_stack_proc (psc, &proc, 1))
  1484. {
  1485. psc->n_values -= 4;
  1486. for (val = initial; !psc->quit &&
  1487. (increment > 0 ? (val <= limit) : (val >= limit));
  1488. val += increment)
  1489. {
  1490. ensure_stack (psc, 1);
  1491. psc->value_stack[psc->n_values].type = GT1_VAL_NUM;
  1492. psc->value_stack[psc->n_values].val.num_val = val;
  1493. psc->n_values++;
  1494. eval_proc (psc, proc);
  1495. }
  1496. }
  1497. }
  1498. static void
  1499. internal_not (Gt1PSContext *psc)
  1500. {
  1501. int bool;
  1502. if (psc->n_values >= 1 &&
  1503. get_stack_bool (psc, &bool, 1))
  1504. {
  1505. psc->value_stack[psc->n_values - 1].val.bool_val = !bool;
  1506. }
  1507. }
  1508. static void
  1509. internal_bind (Gt1PSContext *psc)
  1510. {
  1511. Gt1Proc *proc;
  1512. if (psc->n_values >= 1 &&
  1513. get_stack_proc (psc, &proc, 1))
  1514. {
  1515. /* todo: implement, when procs become normal values */
  1516. }
  1517. }
  1518. static void
  1519. internal_exec (Gt1PSContext *psc)
  1520. {
  1521. Gt1Proc *proc;
  1522. if (psc->n_values >= 1 &&
  1523. get_stack_proc (psc, &proc, 1))
  1524. {
  1525. psc->n_values -= 1;
  1526. eval_proc (psc, proc);
  1527. }
  1528. }
  1529. static void
  1530. internal_count (Gt1PSContext *psc)
  1531. {
  1532. ensure_stack (psc, 1);
  1533. psc->value_stack[psc->n_values].type = GT1_VAL_NUM;
  1534. psc->value_stack[psc->n_values].val.num_val = psc->n_values;
  1535. psc->n_values++;
  1536. }
  1537. static void
  1538. internal_eq (Gt1PSContext *psc)
  1539. {
  1540. double a, b;
  1541. Gt1NameId na, nb;
  1542. if (psc->n_values < 2)
  1543. {
  1544. printf ("stack underflow\n");
  1545. psc->quit = 1;
  1546. return;
  1547. }
  1548. if (psc->value_stack[psc->n_values - 1].type == GT1_VAL_NAME &&
  1549. get_stack_name (psc, &na, 2) &&
  1550. get_stack_name (psc, &nb, 1))
  1551. {
  1552. psc->n_values -= 1;
  1553. psc->value_stack[psc->n_values - 1].type = GT1_VAL_BOOL;
  1554. psc->value_stack[psc->n_values - 1].val.bool_val = (na == nb);
  1555. }
  1556. else if (get_stack_number (psc, &a, 2) &&
  1557. get_stack_number (psc, &b, 1))
  1558. {
  1559. psc->n_values -= 1;
  1560. psc->value_stack[psc->n_values - 1].type = GT1_VAL_BOOL;
  1561. psc->value_stack[psc->n_values - 1].val.bool_val = (a == b);
  1562. }
  1563. }
  1564. static void
  1565. internal_ne (Gt1PSContext *psc)
  1566. {
  1567. internal_eq (psc);
  1568. if (!psc->quit)
  1569. psc->value_stack[psc->n_values - 1].val.bool_val =
  1570. !psc->value_stack[psc->n_values - 1].val.bool_val;
  1571. }
  1572. static void
  1573. internal_type (Gt1PSContext *psc)
  1574. {
  1575. Gt1ValueType type;
  1576. if (psc->n_values >= 1)
  1577. {
  1578. type = psc->value_stack[psc->n_values - 1].type;
  1579. if (type == GT1_VAL_NUM)
  1580. {
  1581. psc->value_stack[psc->n_values - 1].type = GT1_VAL_NAME;
  1582. psc->value_stack[psc->n_values - 1].val.name_val =
  1583. gt1_name_context_intern (psc->nc, "integertype");
  1584. }
  1585. else
  1586. {
  1587. printf ("type not fully implemented");
  1588. }
  1589. }
  1590. }
  1591. static void
  1592. internal_cvx (Gt1PSContext *psc)
  1593. {
  1594. Gt1Value *val;
  1595. if (psc->n_values < 1)
  1596. {
  1597. printf ("stack underflow\n");
  1598. psc->quit = 1;
  1599. }
  1600. else
  1601. {
  1602. val = &psc->value_stack[psc->n_values - 1];
  1603. if (val->type == GT1_VAL_NAME)
  1604. val->type = GT1_VAL_UNQ_NAME;
  1605. else if (val->type == GT1_VAL_ARRAY)
  1606. val->type = GT1_VAL_PROC;
  1607. else
  1608. {
  1609. printf ("warning: cvx called on ");
  1610. print_value (psc, val);
  1611. printf ("\n");
  1612. }
  1613. }
  1614. }
  1615. static void
  1616. internal_matrix (Gt1PSContext *psc)
  1617. {
  1618. Gt1Array *array;
  1619. int i;
  1620. array = array_new (psc->r, 6);
  1621. for (i = 0; i < 6; i++)
  1622. {
  1623. array->vals[i].type = GT1_VAL_NUM;
  1624. array->vals[i].val.num_val = (i == 0 || i == 3);
  1625. }
  1626. psc->value_stack[psc->n_values].type = GT1_VAL_ARRAY;
  1627. psc->value_stack[psc->n_values].val.array_val = array;
  1628. psc->n_values++;
  1629. }
  1630. static void
  1631. internal_FontDirectory (Gt1PSContext *psc)
  1632. {
  1633. ensure_stack (psc, 1);
  1634. psc->value_stack[psc->n_values].type = GT1_VAL_DICT;
  1635. psc->value_stack[psc->n_values].val.dict_val = psc->fonts;
  1636. psc->n_values++;
  1637. }
  1638. /* the table of internal procedures */
  1639. typedef struct _InternalGt1ProcListing {
  1640. char *name;
  1641. void (*function) (Gt1PSContext *psc);
  1642. } InternalGt1ProcListing;
  1643. InternalGt1ProcListing internal_procs[] = {
  1644. { "dict", internal_dict },
  1645. { "begin", internal_begin },
  1646. { "end", internal_end },
  1647. { "dup", internal_dup },
  1648. { "pop", internal_pop },
  1649. { "exch", internal_exch },
  1650. { "readonly", internal_readonly },
  1651. { "executeonly", internal_executeonly },
  1652. { "noaccess", internal_noaccess },
  1653. { "def", internal_def },
  1654. { "false", internal_false },
  1655. { "true", internal_true },
  1656. { "StandardEncoding", internal_StandardEncoding },
  1657. { "[", internalop_openbracket },
  1658. { "]", internalop_closebracket },
  1659. { "currentdict", internal_currentdict },
  1660. { "currentfile", internal_currentfile },
  1661. { "eexec", internal_eexec },
  1662. { "array", internal_array },
  1663. { "string", internal_string },
  1664. { "readstring", internal_readstring },
  1665. { "put", internal_put },
  1666. { "get", internal_get },
  1667. { "index", internal_index },
  1668. { "definefont", internal_definefont },
  1669. { "mark", internal_mark },
  1670. { "closefile", internal_closefile },
  1671. { "cleartomark", internal_cleartomark },
  1672. { "systemdict", internal_systemdict },
  1673. { "userdict", internal_userdict },
  1674. { "known", internal_known },
  1675. { "ifelse", internal_ifelse },
  1676. { "if", internal_if },
  1677. { "for", internal_for },
  1678. { "not", internal_not },
  1679. { "bind", internal_bind },
  1680. { "exec", internal_exec },
  1681. { "count", internal_count },
  1682. { "eq", internal_eq },
  1683. { "ne", internal_ne },
  1684. { "type", internal_type },
  1685. { "cvx", internal_cvx },
  1686. { "matrix", internal_matrix },
  1687. { "FontDirectory", internal_FontDirectory }
  1688. };
  1689. /* here end the internal procedures */
  1690. static Gt1PSContext *
  1691. pscontext_new (Gt1TokenContext *tc)
  1692. {
  1693. Gt1PSContext *psc;
  1694. Gt1Dict *systemdict;
  1695. Gt1Dict *globaldict;
  1696. Gt1Dict *userdict;
  1697. int i;
  1698. Gt1Value val;
  1699. psc = gt1_new (Gt1PSContext, 1);
  1700. psc->r = gt1_region_new ();
  1701. psc->tc = tc;
  1702. psc->nc = gt1_name_context_new ();
  1703. psc->n_values = 0;
  1704. psc->n_values_max = 16;
  1705. psc->value_stack = gt1_new (Gt1Value, psc->n_values_max);
  1706. psc->n_dicts_max = 16;
  1707. psc->gt1_dict_stack = gt1_new (Gt1Dict *, psc->n_dicts_max);
  1708. systemdict = gt1_dict_new (psc->r, sizeof(internal_procs) /
  1709. sizeof(InternalGt1ProcListing));
  1710. for (i = 0; i < sizeof(internal_procs) / sizeof(InternalGt1ProcListing); i++)
  1711. {
  1712. val.type = GT1_VAL_INTERNAL;
  1713. val.val.internal_val = internal_procs[i].function;
  1714. gt1_dict_def (psc->r, systemdict,
  1715. gt1_name_context_intern (psc->nc,
  1716. internal_procs[i].name),
  1717. &val);
  1718. }
  1719. psc->gt1_dict_stack[0] = systemdict;
  1720. globaldict = gt1_dict_new (psc->r, 16);
  1721. psc->gt1_dict_stack[1] = globaldict;
  1722. userdict = gt1_dict_new (psc->r, 16);
  1723. psc->gt1_dict_stack[2] = userdict;
  1724. psc->n_dicts = 3;
  1725. psc->fonts = gt1_dict_new (psc->r, 1);
  1726. psc->n_files_max = 16;
  1727. psc->file_stack = gt1_new (Gt1TokenContext *, psc->n_files_max);
  1728. psc->file_stack[0] = tc;
  1729. psc->n_files = 1;
  1730. psc->quit = 0;
  1731. return psc;
  1732. }
  1733. static void
  1734. pscontext_free (Gt1PSContext *psc)
  1735. {
  1736. /* Empty the value stack. */
  1737. while (psc->n_values > 0) internal_pop (psc);
  1738. gt1_free (psc->value_stack);
  1739. gt1_free (psc->file_stack);
  1740. gt1_free (psc->gt1_dict_stack);
  1741. gt1_name_context_free (psc->nc);
  1742. gt1_region_free (psc->r);
  1743. gt1_free (psc);
  1744. }
  1745. static void
  1746. eval_executable (Gt1PSContext *psc, Gt1Value *val)
  1747. {
  1748. switch (val->type)
  1749. {
  1750. case GT1_VAL_INTERNAL:
  1751. val->val.internal_val (psc);
  1752. break;
  1753. case GT1_VAL_PROC:
  1754. eval_proc (psc, val->val.proc_val);
  1755. break;
  1756. default:
  1757. ensure_stack (psc, 1);
  1758. psc->value_stack[psc->n_values] = *val;
  1759. psc->n_values++;
  1760. break;
  1761. }
  1762. }
  1763. /* Scan a value from the psc's token context - usually one token, or
  1764. a proc. Return the token type. */
  1765. static TokenType
  1766. parse_ps_token (Gt1PSContext *psc, Gt1Value *val)
  1767. {
  1768. MyGt1String lexeme;
  1769. TokenType type;
  1770. Gt1Proc *proc;
  1771. int n_proc, n_proc_max;
  1772. type = tokenize_get (psc->tc, &lexeme);
  1773. switch (type)
  1774. {
  1775. case TOK_NUM:
  1776. val->type = GT1_VAL_NUM;
  1777. val->val.num_val = parse_num (&lexeme);
  1778. break;
  1779. case TOK_NAME:
  1780. val->type = GT1_VAL_NAME;
  1781. val->val.name_val =
  1782. gt1_name_context_intern_size (psc->nc, lexeme.start,
  1783. lexeme.fin - lexeme.start);
  1784. break;
  1785. case TOK_STR:
  1786. val->type = GT1_VAL_STR;
  1787. /* todo: processing of escape characters */
  1788. val->val.str_val.start = lexeme.start;
  1789. val->val.str_val.size = lexeme.fin - lexeme.start;
  1790. break;
  1791. case TOK_IDENT:
  1792. val->type = GT1_VAL_UNQ_NAME;
  1793. val->val.name_val =
  1794. gt1_name_context_intern_size (psc->nc, lexeme.start,
  1795. lexeme.fin - lexeme.start);
  1796. break;
  1797. case TOK_OPENBRACE:
  1798. n_proc = 0;
  1799. n_proc_max = 16;
  1800. proc = (Gt1Proc *)gt1_region_alloc (psc->r, sizeof(Gt1Proc) +
  1801. (n_proc_max - 1) *
  1802. sizeof(Gt1Value));
  1803. while (1)
  1804. {
  1805. if (n_proc == n_proc_max)
  1806. {
  1807. int old_size;
  1808. old_size = sizeof(Gt1Proc) + (n_proc_max - 1) * sizeof(Gt1Value);
  1809. n_proc_max <<= 1;
  1810. proc = (Gt1Proc *)gt1_region_realloc (psc->r, proc,
  1811. old_size,
  1812. sizeof(Gt1Proc) +
  1813. (n_proc_max - 1) *
  1814. sizeof(Gt1Value));
  1815. }
  1816. if (parse_ps_token (psc, &proc->vals[n_proc]) == TOK_CLOSEBRACE ||
  1817. psc->quit)
  1818. break;
  1819. n_proc++;
  1820. }
  1821. proc->n_values = n_proc;
  1822. val->type = GT1_VAL_PROC;
  1823. val->val.proc_val = proc;
  1824. break;
  1825. case TOK_CLOSEBRACE:
  1826. case TOK_END:
  1827. break;
  1828. default:
  1829. printf ("unimplemented token type\n");
  1830. psc->quit = 1;
  1831. break;
  1832. }
  1833. return type;
  1834. }
  1835. static void
  1836. eval_ps_val (Gt1PSContext *psc, Gt1Value *val)
  1837. {
  1838. Gt1Value *new_val;
  1839. #ifdef VERBOSE
  1840. print_value (psc, val);
  1841. printf ("\n");
  1842. #endif
  1843. switch (val->type)
  1844. {
  1845. case GT1_VAL_NUM:
  1846. case GT1_VAL_BOOL:
  1847. case GT1_VAL_STR:
  1848. case GT1_VAL_NAME:
  1849. case GT1_VAL_ARRAY:
  1850. case GT1_VAL_PROC:
  1851. case GT1_VAL_DICT:
  1852. ensure_stack (psc, 1);
  1853. psc->value_stack[psc->n_values] = *val;
  1854. psc->n_values++;
  1855. break;
  1856. case GT1_VAL_UNQ_NAME:
  1857. new_val = gt1_dict_stack_lookup (psc, val->val.name_val);
  1858. if (new_val != NULL)
  1859. eval_executable (psc, new_val);
  1860. else
  1861. {
  1862. printf ("undefined identifier ");
  1863. print_value (psc, val);
  1864. putchar ('\n');
  1865. psc->quit = 1;
  1866. }
  1867. break;
  1868. case GT1_VAL_INTERNAL:
  1869. val->val.internal_val (psc);
  1870. break;
  1871. default:
  1872. printf ("value not handled\n");
  1873. psc->quit = 1;
  1874. break;
  1875. }
  1876. #ifdef VERBOSE
  1877. if (!psc->quit)
  1878. {
  1879. printf (" ");
  1880. print_stack (psc);
  1881. }
  1882. #endif
  1883. }
  1884. /* maybe we should return the dict; easier to handle */
  1885. static Gt1PSContext *
  1886. eval_ps (Gt1TokenContext *tc)
  1887. {
  1888. TokenType type;
  1889. Gt1PSContext *psc;
  1890. Gt1Value val;
  1891. psc = pscontext_new (tc);
  1892. do {
  1893. type = parse_ps_token (psc, &val);
  1894. if (type == TOK_END) break;
  1895. if (type == TOK_CLOSEBRACE)
  1896. {
  1897. printf ("unexpected close brace\n");
  1898. break;
  1899. }
  1900. eval_ps_val (psc, &val);
  1901. } while (!psc->quit);
  1902. return psc;
  1903. }
  1904. /* This routine _assumes_ that plaintext is passed in with enough
  1905. space to hold the decrypted text */
  1906. static void
  1907. charstring_decrypt (Gt1String *plaintext, Gt1String *ciphertext)
  1908. {
  1909. int ciphertext_size;
  1910. int i;
  1911. unsigned short r;
  1912. unsigned char cipher;
  1913. unsigned char plain;
  1914. ciphertext_size = ciphertext->size;
  1915. if (plaintext->size < ciphertext_size - 4)
  1916. {
  1917. printf ("not enough space allocated for charstring decryption\n");
  1918. return;
  1919. }
  1920. r = 4330; /* initial key */
  1921. for (i = 0; i < ciphertext_size; i++)
  1922. {
  1923. cipher = ciphertext->start[i];
  1924. plain = (cipher ^ (r>>8));
  1925. r = (cipher + r) * EEXEC_C1 + EEXEC_C2;
  1926. if (i >= 4)
  1927. plaintext->start[i - 4] = plain;
  1928. }
  1929. plaintext->size = ciphertext->size - 4;
  1930. }
  1931. #ifdef VERBOSE
  1932. static void
  1933. print_glyph_code (Gt1String *glyph_code)
  1934. {
  1935. Gt1String plaintext;
  1936. int i;
  1937. int byte, byte1, byte2, byte3, byte4;
  1938. plaintext.start = gt1_alloc (glyph_code->size);
  1939. plaintext.size = glyph_code->size;
  1940. charstring_decrypt (&plaintext, glyph_code);
  1941. for (i = 0; i < plaintext.size; i++)
  1942. {
  1943. byte = ((unsigned char *)plaintext.start)[i];
  1944. if (byte >= 32 && byte <= 246)
  1945. printf (" %d", byte - 139);
  1946. else if (byte >= 247 && byte <= 250)
  1947. {
  1948. byte1 = ((unsigned char *)plaintext.start)[++i];
  1949. printf (" %d", ((byte - 247) << 8) + byte1 + 108);
  1950. }
  1951. else if (byte >= 251 && byte <= 254)
  1952. {
  1953. byte1 = ((unsigned char *)plaintext.start)[++i];
  1954. printf (" %d", -((byte - 251) << 8) - byte1 - 108);
  1955. }
  1956. else if (byte == 255)
  1957. {
  1958. byte1 = ((unsigned char *)plaintext.start)[++i];
  1959. byte2 = ((unsigned char *)plaintext.start)[++i];
  1960. byte3 = ((unsigned char *)plaintext.start)[++i];
  1961. byte4 = ((unsigned char *)plaintext.start)[++i];
  1962. /* warning: this _must_ be a 32 bit int - alpha portability
  1963. issue! */
  1964. printf (" %d", (byte1 << 24) + (byte2 << 16) + (byte3 << 8) + byte4);
  1965. }
  1966. else if (byte == 12)
  1967. {
  1968. byte1 = ((unsigned char *)plaintext.start)[++i];
  1969. if (byte1 == 6)
  1970. printf (" seac");
  1971. else if (byte1 == 7)
  1972. printf (" sbw");
  1973. else if (byte1 == 0)
  1974. printf (" dotsection");
  1975. else if (byte1 == 2)
  1976. printf (" hstem3");
  1977. else if (byte1 == 1)
  1978. printf (" vstem3");
  1979. else if (byte1 == 12)
  1980. printf (" div");
  1981. else if (byte1 == 16)
  1982. printf (" callothersubr");
  1983. else if (byte1 == 17)
  1984. printf (" pop");
  1985. else if (byte1 == 33)
  1986. printf (" setcurrentpoint");
  1987. else
  1988. printf (" esc%d", byte1);
  1989. }
  1990. else if (byte == 14)
  1991. printf (" endchar");
  1992. else if (byte == 13)
  1993. printf (" hsbw");
  1994. else if (byte == 9)
  1995. printf (" closepath");
  1996. else if (byte == 6)
  1997. printf (" hlineto");
  1998. else if (byte == 22)
  1999. printf (" hmoveto");
  2000. else if (byte == 31)
  2001. printf (" hvcurveto");
  2002. else if (byte == 5)
  2003. printf (" rlineto");
  2004. else if (byte == 21)
  2005. printf (" rmoveto");
  2006. else if (byte == 8)
  2007. printf (" rrcurveto");
  2008. else if (byte == 30)
  2009. printf (" vhcurveto");
  2010. else if (byte == 7)
  2011. printf (" vlineto");
  2012. else if (byte == 4)
  2013. printf (" vmoveto");
  2014. else if (byte == 1)
  2015. printf (" hstem");
  2016. else if (byte == 3)
  2017. printf (" vstem");
  2018. else if (byte == 10)
  2019. printf (" callsubr");
  2020. else if (byte == 11)
  2021. printf (" return");
  2022. else
  2023. printf (" com%d", byte);
  2024. }
  2025. printf ("\n");
  2026. gt1_free (plaintext.start);
  2027. }
  2028. #endif
  2029. /* Gt1Dict is the toplevel font dict. This allocates a new string for the
  2030. plaintext and stores it in body. */
  2031. static void
  2032. get_subr_body (Gt1PSContext *psc, Gt1String *body, Gt1Dict *fontdict, int subr)
  2033. {
  2034. Gt1Value *private_val;
  2035. Gt1Value *subrs_val;
  2036. Gt1Array *subrs_array;
  2037. Gt1String *ciphertext;
  2038. private_val = gt1_dict_lookup (fontdict,
  2039. gt1_name_context_intern (psc->nc, "Private"));
  2040. if (private_val == NULL)
  2041. {
  2042. printf ("No Private array\n");
  2043. return;
  2044. }
  2045. subrs_val = gt1_dict_lookup (private_val->val.dict_val,
  2046. gt1_name_context_intern (psc->nc, "Subrs"));
  2047. if (subrs_val == NULL)
  2048. {
  2049. printf ("No Subrs array\n");
  2050. return;
  2051. }
  2052. subrs_array = subrs_val->val.array_val;
  2053. /* more type & range checking */
  2054. ciphertext = &subrs_array->vals[subr].val.str_val;
  2055. body->start = gt1_alloc (ciphertext->size);
  2056. body->size = ciphertext->size;
  2057. charstring_decrypt (body, ciphertext);
  2058. }
  2059. typedef struct _BezState {
  2060. ArtBpath *bezpath;
  2061. int size_bezpath, size_bezpath_max;
  2062. /* this is designed to do compression of a string of moveto's in a row. */
  2063. int need_moveto;
  2064. double x, y; /* current point */
  2065. double x0, y0; /* beginning of subpath */
  2066. } BezState;
  2067. static BezState *
  2068. bs_new (void)
  2069. {
  2070. BezState *bs;
  2071. bs = gt1_new (BezState, 1);
  2072. bs->size_bezpath = 0;
  2073. bs->size_bezpath_max = 16;
  2074. bs->bezpath = gt1_new (ArtBpath, bs->size_bezpath_max);
  2075. bs->x = 0;
  2076. bs->y = 0;
  2077. bs->x0 = 0;
  2078. bs->y0 = 0;
  2079. bs->need_moveto = 1;
  2080. return bs;
  2081. }
  2082. static void
  2083. bs_moveto (BezState *bs, double x, double y)
  2084. {
  2085. bs->x = x;
  2086. bs->y = y;
  2087. bs->need_moveto = 1;
  2088. }
  2089. static void
  2090. bs_rmoveto (BezState *bs, double dx, double dy)
  2091. {
  2092. bs->x += dx;
  2093. bs->y += dy;
  2094. bs->need_moveto = 1;
  2095. }
  2096. static void
  2097. bs_do_moveto (BezState *bs)
  2098. {
  2099. ArtBpath *bezpath;
  2100. int size_bezpath;
  2101. if (bs->need_moveto)
  2102. {
  2103. bezpath = bs->bezpath;
  2104. size_bezpath = bs->size_bezpath;
  2105. if (size_bezpath == bs->size_bezpath_max)
  2106. {
  2107. gt1_double (bezpath, ArtBpath, bs->size_bezpath_max);
  2108. bs->bezpath = bezpath;
  2109. }
  2110. bezpath[size_bezpath].code = ART_MOVETO;
  2111. bezpath[size_bezpath].x1 = 0;
  2112. bezpath[size_bezpath].y1 = 0;
  2113. bezpath[size_bezpath].x2 = 0;
  2114. bezpath[size_bezpath].y2 = 0;
  2115. bezpath[size_bezpath].x3 = bs->x;
  2116. bezpath[size_bezpath].y3 = bs->y;
  2117. bs->size_bezpath++;
  2118. bs->x0 = bs->x;
  2119. bs->y0 = bs->y;
  2120. bs->need_moveto = 0;
  2121. }
  2122. }
  2123. static void
  2124. bs_rlineto (BezState *bs, double dx, double dy)
  2125. {
  2126. ArtBpath *bezpath;
  2127. int size_bezpath;
  2128. bs_do_moveto (bs);
  2129. bezpath = bs->bezpath;
  2130. size_bezpath = bs->size_bezpath;
  2131. if (size_bezpath ==

Large files files are truncated, but you can click here to view the full file