PageRenderTime 41ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/R-2.10.1-patched/src/modules/vfonts/g_cntrlify.c

http://r4jvm.googlecode.com/
C | 814 lines | 477 code | 65 blank | 272 comment | 162 complexity | 2d8f24e587a17aad7186769bbe4c01e5 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.0, LGPL-3.0, BSD-3-Clause, AGPL-3.0, GPL-2.0, LGPL-2.1
  1. /* PAUL MURRELL
  2. This is from the GNU plotutils libplot-2.3 distribution
  3. All references to HAVE_PROTOS removed
  4. All references to "plotter" replaced with references to "GEDevDesc"
  5. */
  6. /* <UTF8-FIXME> This assumes single-byte encoding */
  7. /* _controlify() converts a "label" (i.e. a character string), which may
  8. contain troff-like escape sequences, into a string of unsigned shorts.
  9. The possible troff-like escape sequences are listed in g_cntrlify.h.
  10. This conversion is to facilitate rendering. _controlify() is called by
  11. alabel(), and the converted label is rendered by _alabel_standard(),
  12. _alabel_stroke(), or _alabel_device(), depending on what sort of font is
  13. currently selected. See g_alabel.c (_controlify() is called by
  14. labelwidth() too).
  15. If the currently selected font is a font with ISO-Latin-1 encoding, the
  16. valid escape sequences include escape sequences for the non-ASCII
  17. ISO-Latin-1 characters. Also allowed are such escape sequences as \f0,
  18. \f1, \f2, \f3, \f4, etc., which switch among the various fonts in the
  19. current typeface:
  20. \f1 Switch to font #1, basic
  21. \f2 Switch to font #2, italic
  22. \f3 Switch to font #3, bold
  23. \f4 Switch to font #4, bold italic
  24. \f0 Switch to font #0, symbol (including Greek characters)
  25. \fP switches to the previously used font (there is a depth-1 stack,
  26. i.e. only one previous font is remembered, as in troff).
  27. All typefaces include at least two fonts: fonts #0 and #1. Some may
  28. include more than the above five. Each unsigned short in the converted
  29. string is really an annotated character: the low byte is the character,
  30. and the high byte is the font number.
  31. Besides font annotations, the controlified string may include control
  32. codes (unsigned shorts with particular bit patterns in their high
  33. bytes), which are produced by the escape sequences:
  34. \sp start superscript
  35. \ep end superscript
  36. \sb start subscript
  37. \eb end subscript
  38. \mk mark location
  39. \rt return to mark
  40. [useful e.g. for underlining, and filling square roots]
  41. There are also control codes for horizontal shifts. \r1, \r2, \r4,
  42. \r6, \r8, \r^ will produce control codes that will shift right by 1 em,
  43. 1/2 em, 1/4 em, 1/6 em, 1/8 em, 1/12 em, respectively. \l1, \l2, \l4,
  44. \l6, \l8, \l^ are similar.
  45. The string of unsigned shorts, which is returned, is allocated with
  46. malloc and may be freed later. */
  47. /* PAUL MURRELL
  48. sys-defines.h not used
  49. */
  50. /* #include "sys-defines.h" */
  51. /* PAUL MURRELL
  52. extern.h renamed g_extern.h
  53. */
  54. #include "g_extern.h"
  55. #include "g_control.h"
  56. #include "g_cntrlify.h"
  57. #include "g_jis.h"
  58. /* these two array lengths must agree with values in file g_her_glyph.c */
  59. #define NUM_OCCIDENTAL_HERSHEY_GLYPHS 4400
  60. #define NUM_ORIENTAL_HERSHEY_GLYPHS 5500
  61. /* PAUL MURRELL
  62. Added typeface and fontindex arguments
  63. */
  64. attribute_hidden
  65. unsigned short * _controlify (pGEDevDesc dd, const unsigned char *src,
  66. int typeface, int fontindex)
  67. {
  68. unsigned short *dest;
  69. unsigned char c, d;
  70. unsigned char esc[3];
  71. int j = 0;
  72. int raw_fontnum, raw_symbol_fontnum;
  73. int previous_raw_fontnum; /* implement depth-1 stack */
  74. unsigned short fontword, symbol_fontword;
  75. /* note: string length can grow by a factor of 6, because a single
  76. printable character can be mapped to a sequence of unsigned shorts, of
  77. length up to 6 (see comment below) */
  78. /* PAUL MURRELL
  79. replace _plot_xmalloc with R_alloc
  80. */
  81. dest = (unsigned short *) R_alloc (1, (6 * strlen ((char *)src) + 1) *
  82. sizeof(unsigned short));
  83. /* PAUL MURRELL
  84. only for Hershey fonts so removed switch ...
  85. */
  86. raw_fontnum = _hershey_typeface_info[typeface].fonts[fontindex];
  87. raw_symbol_fontnum = _hershey_typeface_info[typeface].fonts[0];
  88. /* Of the following two words, `fontword' is updated whenever an escape
  89. sequence like \f0, \f1, \f2 etc. is seen, since raw_fontnum is itself
  90. updated. But `symbol_fontword' is fixed */
  91. fontword = ((unsigned short)raw_fontnum) << FONT_SHIFT;
  92. symbol_fontword = ((unsigned short)raw_symbol_fontnum) << FONT_SHIFT;
  93. /* Implement depth-1 stack of fonts, for use by \fP macro */
  94. previous_raw_fontnum = raw_fontnum;
  95. while (*src != (unsigned char)'\0')
  96. {
  97. /* If EUC, check first for high bit and process two-byte characters
  98. separately. This approach is awkward (we duplicate a lot of code
  99. here, which appears elsewhere below). */
  100. if ((raw_fontnum == HERSHEY_EUC)
  101. && (*src & 0x80) && (*(src + 1) & 0x80))
  102. {
  103. unsigned char jis_row = *src & ~(0x80);
  104. unsigned char jis_col = *(src + 1) & ~(0x80);
  105. if (GOOD_JIS_INDEX(jis_row, jis_col))
  106. {
  107. int jis_glyphindex = 256 * jis_row + jis_col;
  108. if (jis_glyphindex >= BEGINNING_OF_KANJI)
  109. /* in Kanji range, so check if we have it */
  110. {
  111. #ifndef NO_KANJI
  112. const struct kanjipair *kanji = _builtin_kanji_glyphs;
  113. bool matched = false;
  114. while (kanji->jis != 0)
  115. {
  116. if (jis_glyphindex == kanji->jis)
  117. {
  118. matched = true;
  119. break;
  120. }
  121. kanji++;
  122. }
  123. if (matched)
  124. {
  125. dest[j++] = RAW_ORIENTAL_HERSHEY_GLYPH | (kanji->nelson);
  126. src += 2;
  127. continue; /* back to top of while loop */
  128. }
  129. else /* a Kanji we don't have */
  130. {
  131. /* render as standard `undefined character' glyph */
  132. dest[j++] = RAW_HERSHEY_GLYPH | UNDE;
  133. src += 2;
  134. continue; /* back to top of while loop */
  135. }
  136. #endif /* not NO_KANJI */
  137. }
  138. else
  139. /* not in Kanji range, so look for it in char table */
  140. {
  141. const struct jis_entry *char_mapping = _builtin_jis_chars;
  142. bool matched = false;
  143. while (char_mapping->jis != 0)
  144. {
  145. if (jis_glyphindex == char_mapping->jis)
  146. {
  147. matched = true;
  148. break;
  149. }
  150. char_mapping++;
  151. }
  152. if (matched)
  153. /* the entry in the character table maps the JIS
  154. character to a character (in 0..255 range) in
  155. one of the fonts in the master table in g_fontdb.c */
  156. {
  157. int fontnum = char_mapping->font;
  158. unsigned short charnum = char_mapping->charnum;
  159. if (charnum & RAW_HERSHEY_GLYPH)
  160. /* a raw Hershey glyph, not in any font */
  161. dest[j++] = RAW_HERSHEY_GLYPH | charnum;
  162. else
  163. /* a character in one of the fonts in g_fontdb.c */
  164. dest[j++] = (((unsigned short)fontnum) << FONT_SHIFT) | charnum;
  165. src += 2;
  166. continue; /* back to top of while loop */
  167. }
  168. else /* a character we don't have */
  169. {
  170. /* render as standard `undefined character' glyph */
  171. dest[j++] = RAW_HERSHEY_GLYPH | UNDE;
  172. src += 2;
  173. continue; /* back to top of while loop */
  174. }
  175. }
  176. }
  177. else
  178. /* JIS index is OOB */
  179. {
  180. src += 2;
  181. continue; /* back to top of while loop */
  182. }
  183. }
  184. /* if current font is Hershey, first try to match each ligature
  185. pattern (no ligatures supported in non-Hershey fonts) */
  186. if (1) /* _plotter->drawstate->font_type == F_HERSHEY) */
  187. {
  188. int i;
  189. bool matched = false;
  190. for (i = 0; i < NUM_LIGATURES; i++)
  191. if ((_ligature_tbl[i].font == raw_fontnum)
  192. && (strncmp ((char *)src, _ligature_tbl[i].from,
  193. strlen (_ligature_tbl[i].from)) == 0))
  194. {
  195. matched = true;
  196. break;
  197. }
  198. if (matched)
  199. {
  200. dest[j++] = fontword | (unsigned short)_ligature_tbl[i].byte;
  201. src += strlen (_ligature_tbl[i].from);
  202. continue; /* back to top of while loop */
  203. }
  204. }
  205. c = *(src++); /* no ligature, so get single new char */
  206. if (c != (unsigned char)'\\') /* ordinary char, may pass through */
  207. {
  208. /* if current font is an ISO-Latin-1 Hershey font ... */
  209. if (1 /* _plotter->drawstate->font_type == F_HERSHEY */
  210. && _hershey_font_info[raw_fontnum].iso8859_1)
  211. {
  212. int i;
  213. bool matched = false;
  214. /* check if this is a `raised' ISO-Latin-1 character */
  215. for (i = 0; i < NUM_RAISED_CHARS; i++)
  216. if (c == _raised_char_tbl[i].from)
  217. {
  218. matched = true;
  219. break;
  220. }
  221. if (matched) /* it's a raised character */
  222. {
  223. /* map to string of unsigned shorts, length 3 or 6:
  224. `begin superscript' control code, [`mark'
  225. control code,] replacement char, [`return'
  226. control code, underline,] `end superscript' */
  227. dest[j++] =
  228. (unsigned short) (CONTROL_CODE | C_BEGIN_SUPERSCRIPT);
  229. if (_raised_char_tbl[i].underscored) /* also underline */
  230. {
  231. dest[j++] =
  232. (unsigned short) (CONTROL_CODE | C_PUSH_LOCATION);
  233. dest[j++] =
  234. fontword | (unsigned short)_raised_char_tbl[i].to;
  235. dest[j++] =
  236. (unsigned short) (CONTROL_CODE | C_POP_LOCATION);
  237. /* select appropriate HersheySymbol font */
  238. dest[j++] =
  239. symbol_fontword | (unsigned short)VECTOR_SYMBOL_FONT_UNDERSCORE;
  240. }
  241. else /* just print raised char, no underline */
  242. dest[j++] =
  243. fontword | (unsigned short)_raised_char_tbl[i].to;
  244. dest[j++] =
  245. (unsigned short) (CONTROL_CODE | C_END_SUPERSCRIPT);
  246. continue; /* back to top of while loop */
  247. }
  248. /* since current font is an ISO-Latin-1 Hershey font, also
  249. check if this char should be deligatured */
  250. for (i = 0; i < NUM_DELIGATURED_CHARS; i++)
  251. if (c == _deligature_char_tbl[i].from)
  252. {
  253. matched = true;
  254. break;
  255. }
  256. if (matched)
  257. {
  258. if (_deligature_char_tbl[i].except_font != raw_fontnum)
  259. {
  260. dest[j++] = fontword
  261. | (unsigned short)_deligature_char_tbl[i].to[0];
  262. dest[j++] = fontword
  263. | (unsigned short)_deligature_char_tbl[i].to[1];
  264. continue; /* back to top of while loop */
  265. }
  266. }
  267. }
  268. /* didn't do anything special, so just pass the character thru */
  269. dest[j++] = fontword | (unsigned short)c;
  270. continue; /* back to top of while loop */
  271. }
  272. else /* character is a backslash */
  273. {
  274. int i;
  275. c = *(src++); /* grab next character */
  276. if (c == (unsigned char)'\0') /* ASCII NUL ? */
  277. {
  278. dest[j++] = fontword | (unsigned short)'\\';
  279. break; /* string terminated with a backslash */
  280. }
  281. if (c == (unsigned char)'\\')
  282. {
  283. dest[j++] = fontword | (unsigned short)'\\';
  284. dest[j++] = fontword | (unsigned short)'\\';
  285. continue; /* saw \\, leave as is */
  286. }
  287. d = *(src++);
  288. if (d == (unsigned char)'\0')
  289. {
  290. dest[j++] = fontword | (unsigned short)'\\';
  291. dest[j++] = fontword | (unsigned short)c;
  292. break; /* string terminated with \c */
  293. }
  294. esc[0] = c;
  295. esc[1] = d;
  296. esc[2] = (unsigned char)'\0'; /* have an escape sequence */
  297. /* is this an escape seq. (e.g. \#H0001) for a raw Hershey glyph? */
  298. if (1 /* _plotter->drawstate->font_type == F_HERSHEY */
  299. && esc[0] == '#' && esc[1] == 'H'
  300. && src[0] >= '0' && src[0] <= '9'
  301. && src[1] >= '0' && src[1] <= '9'
  302. && src[2] >= '0' && src[2] <= '9'
  303. && src[3] >= '0' && src[3] <= '9')
  304. {
  305. int glyphindex;
  306. glyphindex = (src[3] - '0') + 10 * (src[2] - '0')
  307. + 100 * (src[1] - '0') + 1000 * (src[0] - '0');
  308. if (glyphindex < NUM_OCCIDENTAL_HERSHEY_GLYPHS)
  309. {
  310. dest[j++] = RAW_HERSHEY_GLYPH | glyphindex;
  311. src += 4;
  312. continue; /* back to top of while loop */
  313. }
  314. }
  315. #ifndef NO_KANJI
  316. /* is this an escape seq. (e.g. \#N0001) for a raw Japanese
  317. Hershey glyph (Kanji), as numbered in Nelson's dictionary? */
  318. if (1 /* _plotter->drawstate->font_type == F_HERSHEY */
  319. && esc[0] == '#' && esc[1] == 'N'
  320. && src[0] >= '0' && src[0] <= '9'
  321. && src[1] >= '0' && src[1] <= '9'
  322. && src[2] >= '0' && src[2] <= '9'
  323. && src[3] >= '0' && src[3] <= '9')
  324. {
  325. int glyphindex;
  326. glyphindex = (src[3] - '0') + 10 * (src[2] - '0')
  327. + 100 * (src[1] - '0') + 1000 * (src[0] - '0');
  328. if (glyphindex < NUM_ORIENTAL_HERSHEY_GLYPHS)
  329. {
  330. dest[j++] = RAW_ORIENTAL_HERSHEY_GLYPH | glyphindex;
  331. src += 4;
  332. continue; /* back to top of while loop */
  333. }
  334. }
  335. #endif /* not NO_KANJI */
  336. /* is this an escape seq. (e.g. \#J0001) for a raw Japanese
  337. Hershey glyph (JIS numbering, in hex)? */
  338. if (1 /* _plotter->drawstate->font_type == F_HERSHEY */
  339. && esc[0] == '#' && esc[1] == 'J'
  340. && ((src[0] >= '0' && src[0] <= '9')
  341. || (src[0] >= 'a' && src[0] <= 'f')
  342. || (src[0] >= 'A' && src[0] <= 'F'))
  343. && ((src[1] >= '0' && src[1] <= '9')
  344. || (src[1] >= 'a' && src[1] <= 'f')
  345. || (src[1] >= 'A' && src[1] <= 'F'))
  346. && ((src[2] >= '0' && src[2] <= '9')
  347. || (src[2] >= 'a' && src[2] <= 'f')
  348. || (src[2] >= 'A' && src[2] <= 'F'))
  349. && ((src[3] >= '0' && src[3] <= '9')
  350. || (src[3] >= 'a' && src[3] <= 'f')
  351. || (src[3] >= 'A' && src[3] <= 'F')))
  352. {
  353. int jis_glyphindex;
  354. int i, hexnum[4];
  355. int jis_row, jis_col;
  356. for (i = 0; i < 4; i++)
  357. if (src[i] >= 'a' && src[i] <= 'f')
  358. hexnum[i] = 10 + src[i] - 'a';
  359. else if (src[i] >= 'A' && src[i] <= 'F')
  360. hexnum[i] = 10 + src[i] - 'A';
  361. else /* a decimal digit */
  362. hexnum[i] = src[i] - '0';
  363. jis_glyphindex = (hexnum[3] + 16 * hexnum[2]
  364. + 256 * hexnum[1] + 4096 * hexnum[0]);
  365. jis_row = hexnum[1] + 16 * hexnum[0];
  366. jis_col = hexnum[3] + 16 * hexnum[2];
  367. if (GOOD_JIS_INDEX(jis_row, jis_col))
  368. {
  369. if (jis_glyphindex >= BEGINNING_OF_KANJI)
  370. /* in Kanji range, so check if we have it */
  371. {
  372. #ifndef NO_KANJI
  373. const struct kanjipair *kanji = _builtin_kanji_glyphs;
  374. bool matched = false;
  375. while (kanji->jis != 0)
  376. {
  377. if (jis_glyphindex == kanji->jis)
  378. {
  379. matched = true;
  380. break;
  381. }
  382. kanji++;
  383. }
  384. if (matched)
  385. {
  386. dest[j++] = RAW_ORIENTAL_HERSHEY_GLYPH | (kanji->nelson);
  387. src += 4;
  388. continue; /* back to top of while loop */
  389. }
  390. else /* a Kanji we don't have */
  391. {
  392. /* render as standard `undefined character' glyph */
  393. dest[j++] = RAW_HERSHEY_GLYPH | UNDE;
  394. src += 4;
  395. continue; /* back to top of while loop */
  396. }
  397. #endif /* not NO_KANJI */
  398. }
  399. else
  400. /* not in Kanji range, so look for it in char table */
  401. {
  402. const struct jis_entry *char_mapping = _builtin_jis_chars;
  403. bool matched = false;
  404. while (char_mapping->jis != 0)
  405. {
  406. if (jis_glyphindex == char_mapping->jis)
  407. {
  408. matched = true;
  409. break;
  410. }
  411. char_mapping++;
  412. }
  413. if (matched)
  414. /* the entry in the character table maps the JIS
  415. character to a character (in 0..255 range) in
  416. one of the fonts in the master table in g_fontdb.c*/
  417. {
  418. int fontnum = char_mapping->font;
  419. unsigned short charnum = char_mapping->charnum;
  420. if (charnum & RAW_HERSHEY_GLYPH)
  421. /* a raw Hershey glyph, not in any font */
  422. dest[j++] = RAW_HERSHEY_GLYPH | charnum;
  423. else
  424. /* a character in one of the fonts in g_fontdb.c */
  425. dest[j++] = (((unsigned short)fontnum) << FONT_SHIFT) | charnum;
  426. src += 4;
  427. continue; /* back to top of while loop */
  428. }
  429. else /* a character we don't have */
  430. {
  431. /* render as standard `undefined character' glyph */
  432. dest[j++] = RAW_HERSHEY_GLYPH | UNDE;
  433. src += 4;
  434. continue; /* back to top of while loop */
  435. }
  436. }
  437. }
  438. }
  439. {
  440. bool matched = false;
  441. /* is this an escape seq. for a control code? */
  442. for (i = 0; i < NUM_CONTROLS; i++)
  443. if (strcmp ((char *)esc, _control_tbl[i]) == 0)
  444. {
  445. matched = true;
  446. break;
  447. }
  448. if (matched) /* it's a control code */
  449. {
  450. dest[j++] = CONTROL_CODE | i;
  451. continue; /* back to top of while loop */
  452. }
  453. }
  454. /* if current font is an ISO-Latin-1 Hershey font, is this an
  455. escape sequence for an 8-bit (non-ASCII) char, which due to
  456. nonexistence should be deligatured? */
  457. if (1 /* _plotter->drawstate->font_type == F_HERSHEY */
  458. && _hershey_font_info[raw_fontnum].iso8859_1)
  459. {
  460. int i;
  461. bool matched = false;
  462. for (i = 0; i < NUM_DELIGATURED_ESCAPES; i++)
  463. if (strcmp ((char *)esc, _deligature_escape_tbl[i].from) == 0)
  464. {
  465. matched = true;
  466. break;
  467. }
  468. if (matched)
  469. {
  470. if (_deligature_escape_tbl[i].except_font != raw_fontnum)
  471. {
  472. dest[j++] = fontword
  473. | (unsigned short)_deligature_escape_tbl[i].to[0];
  474. dest[j++] = fontword
  475. | (unsigned short)_deligature_escape_tbl[i].to[1];
  476. continue; /* back to top of while loop */
  477. }
  478. }
  479. }
  480. /* if the current font is an ISO-Latin-1 font (no matter whether
  481. font is a a Hershey font, a PS or PCL/Stick font, or a
  482. device-specific font for which we have no table entry), is
  483. this an escape seq. for an 8-bit (non-ASCII) ISO8859-1 char? */
  484. /* PAUL MURRELL
  485. Only concerned with Hershey fonts
  486. */
  487. /*
  488. if ((_plotter->drawstate->font_type == F_POSTSCRIPT
  489. && _ps_font_info[raw_fontnum].iso8859_1)
  490. || (_plotter->drawstate->font_type == F_HERSHEY
  491. && _hershey_font_info[raw_fontnum].iso8859_1)
  492. || (_plotter->drawstate->font_type == F_PCL
  493. && _pcl_font_info[raw_fontnum].iso8859_1)
  494. || (_plotter->drawstate->font_type == F_STICK
  495. && _stick_font_info[raw_fontnum].iso8859_1)
  496. || (_plotter->drawstate->font_type == F_OTHER
  497. && _plotter->drawstate->font_is_iso8859_1
  498. && raw_fontnum == 1))
  499. */
  500. if (1 /* _plotter->drawstate->font_type == F_HERSHEY */
  501. && _hershey_font_info[raw_fontnum].iso8859_1)
  502. {
  503. bool matched = false;
  504. for (i = 0; i < NUM_ISO_ESCAPES; i++)
  505. if (strcmp ((char *)esc, _iso_escape_tbl[i].string) == 0)
  506. {
  507. matched = true;
  508. break;
  509. }
  510. if (matched) /* it's an 8-bit ISO8859-1 character */
  511. {
  512. /* certain such characters are drawn in the Hershey fonts
  513. as superscripts */
  514. if (1) /* _plotter->drawstate->font_type == F_HERSHEY) */
  515. {
  516. int k;
  517. bool matched2 = false;
  518. /* check if this is a `raised' ISO-Latin-1 character */
  519. for (k = 0; k < NUM_RAISED_CHARS; k++)
  520. if (_iso_escape_tbl[i].byte == _raised_char_tbl[k].from)
  521. {
  522. matched2 = true;
  523. break;
  524. }
  525. if (matched2) /* it's a raised character */
  526. {
  527. /* map to string of unsigned shorts, length 3 or 6:
  528. `begin superscript' control code, [`mark'
  529. control code,] replacement char, [`return'
  530. control code, underline,] `end superscript' */
  531. dest[j++] =
  532. (unsigned short) (CONTROL_CODE | C_BEGIN_SUPERSCRIPT);
  533. if (_raised_char_tbl[k].underscored) /* also underline */
  534. {
  535. dest[j++] =
  536. (unsigned short) (CONTROL_CODE | C_PUSH_LOCATION);
  537. dest[j++] =
  538. fontword | (unsigned short)_raised_char_tbl[k].to;
  539. dest[j++] =
  540. (unsigned short) (CONTROL_CODE | C_POP_LOCATION);
  541. /* select appropriate HersheySymbol font */
  542. dest[j++] =
  543. symbol_fontword | (unsigned short)VECTOR_SYMBOL_FONT_UNDERSCORE;
  544. }
  545. else /* just print raised char, no underline */
  546. {
  547. dest[j++] =
  548. fontword | (unsigned short)_raised_char_tbl[k].to;
  549. }
  550. dest[j++] =
  551. (unsigned short) (CONTROL_CODE | C_END_SUPERSCRIPT);
  552. continue; /* back to top of while loop */
  553. }
  554. }
  555. /* won't draw this char as a superscript; just pass thru */
  556. dest[j++] = fontword | (unsigned short)(_iso_escape_tbl[i].byte);
  557. continue; /* back to top of while loop */
  558. }
  559. }
  560. /* is this an escape seq. for a `special' (non-ISO, non-Symbol)
  561. Hershey glyph? Such glyphs include astronomical signs, and
  562. `final s'. */
  563. if (1) /* _plotter->drawstate->font_type == F_HERSHEY) */
  564. {
  565. bool matched = false;
  566. for (i = 0; i < NUM_SPECIAL_ESCAPES; i++)
  567. if (strcmp ((char *)esc, _special_escape_tbl[i].string) == 0)
  568. {
  569. matched = true;
  570. break;
  571. }
  572. if (matched) /* it's a special character */
  573. {
  574. /* "\s-" is special; yields character in current font */
  575. if (_special_escape_tbl[i].byte == FINAL_LOWERCASE_S)
  576. dest[j++] =
  577. fontword | (unsigned short)(_special_escape_tbl[i].byte);
  578. else
  579. /* we select symbol font of typeface, in which we've
  580. stored all other special characters */
  581. dest[j++] = symbol_fontword | (unsigned short)(_special_escape_tbl[i].byte);
  582. continue; /* back to top of while loop */
  583. }
  584. }
  585. {
  586. bool matched = false;
  587. /* Irrespective of font type, is this an escape seq. for a char
  588. in the font's corresponding symbol font? */
  589. for (i = 0; i < NUM_SYMBOL_ESCAPES; i++)
  590. if (strcmp (_symbol_escape_tbl[i].string, "NO_ABBREV") != 0
  591. && strcmp ((char *)esc, _symbol_escape_tbl[i].string) == 0)
  592. {
  593. matched = true;
  594. break;
  595. }
  596. if (matched) /* it's a character in the symbol font */
  597. {
  598. /* select symbol font by OR'ing in the symbol fontword */
  599. dest[j++] = symbol_fontword | (unsigned short)(_symbol_escape_tbl[i].byte);
  600. continue; /* back to top of while loop */
  601. }
  602. }
  603. /* Gross kludge. In the non-Hershey fonts we handle the "\rn"
  604. control sequence in a painful way. For a PS font we map it
  605. into (1) a left shift, (2) the `radicalex' character in the PS
  606. Symbol font, and (3) a right shift. Shift distances are taken
  607. from the bbox of the radicalex char, and are slightly larger
  608. than 0.5 em. For a PCL font it's similar, but the shifts are
  609. much smaller. The reason it's different for PCL is that the
  610. PCL radicalex character is different from the PS radicalex
  611. character: the overbar is not displaced. Possibly someone at
  612. HP made a mistake while reimplementing the Adobe Symbol font
  613. for PCL 5?
  614. We don't implement \rn for Stick fonts, because they have
  615. no associated symbol font. */
  616. /* PAUL MURRELL
  617. Only concerned with Hershey fonts
  618. */
  619. /* if (strcmp ((char *)esc, "rn") == 0)
  620. cc {
  621. cc if (_plotter->drawstate->font_type == F_POSTSCRIPT
  622. cc || _plotter->drawstate->font_type == F_PCL)
  623. cc {
  624. cc dest[j++]
  625. cc = (unsigned short)(CONTROL_CODE | C_LEFT_RADICAL_SHIFT);
  626. cc take `radicalex' glyph from PS symbol font
  627. cc dest[j++]
  628. cc = symbol_fontword | (unsigned short)RADICALEX;
  629. cc dest[j++]
  630. cc = (unsigned short)(CONTROL_CODE | C_RIGHT_RADICAL_SHIFT);
  631. cc continue; cc back to top of while loop
  632. cc }
  633. cc }
  634. cc Attempt to parse as a font-change command, i.e. as one of the
  635. macros \f0, \f1, \f2, etc., or \fP. \fR, \fI, \fB are the
  636. same as \f1, \f2, \f3 for troff compatibility. cc
  637. cc if (esc[0] == 'f' && ((esc[1] >= '0' && esc[1] <= '9')
  638. cc || esc[1] == 'P' || esc[1] == 'R'
  639. cc || esc[1] == 'I' || esc[1] == 'B'))
  640. cc {
  641. cc If a user-specified, device-specific font [e.g. an X font,
  642. for which we have no internal table listing the other
  643. fonts in its family] is being used, we can't really do
  644. font switching, except via \f0, \f1. These switch to the
  645. X symbol font and the current user-specified font,
  646. respectively. (\fP is also supported.) cc
  647. cc if (_plotter->drawstate->font_type == F_OTHER
  648. cc && ((esc[1] >= '2' && esc[1] <= '9')
  649. cc || esc[1] == 'I' || esc[1] == 'B'))
  650. cc esc[1] = '1'; cc treat as \f1 cc
  651. cc troff compatibility cc
  652. cc if (esc[1] == 'R')
  653. cc esc[1] = '1';
  654. cc else if (esc[1] == 'I')
  655. cc esc[1] = '2';
  656. cc else if (esc[1] == 'B')
  657. cc esc[1] = '3';
  658. cc if (esc[1] == 'P') cc \fP seen, so go back to previous font cc
  659. cc raw_fontnum = previous_raw_fontnum;
  660. cc else cc font specified as index into typeface cc
  661. cc {
  662. cc int new_font_index = esc[1] - '0';
  663. cc switch to specified font (OOB tests here now obsolete?) cc
  664. cc previous_raw_fontnum = raw_fontnum;
  665. cc switch (_plotter->drawstate->font_type)
  666. cc {
  667. cc case F_HERSHEY:
  668. cc if ((new_font_index >= _hershey_typeface_info[_plotter->drawstate->typeface_index].numfonts)
  669. cc || new_font_index < 0)
  670. cc new_font_index = 1; cc OOB -> use default font cc
  671. cc raw_fontnum = _hershey_typeface_info[_plotter->drawstate->typeface_index].fonts[new_font_index];
  672. cc break;
  673. cc case F_PCL:
  674. cc if ((new_font_index >= _pcl_typeface_info[_plotter->drawstate->typeface_index].numfonts)
  675. cc || new_font_index < 0)
  676. cc new_font_index = 1; cc OOB -> use default font cc
  677. cc raw_fontnum = _pcl_typeface_info[_plotter->drawstate->typeface_index].fonts[new_font_index];
  678. cc break;
  679. cc case F_STICK:
  680. cc if ((new_font_index >= _stick_typeface_info[_plotter->drawstate->typeface_index].numfonts)
  681. cc || new_font_index < 0)
  682. cc new_font_index = 1; cc OOB -> use default font cc
  683. cc raw_fontnum = _stick_typeface_info[_plotter->drawstate->typeface_index].fonts[new_font_index];
  684. cc break;
  685. cc case F_POSTSCRIPT:
  686. cc default:
  687. cc if ((new_font_index >= _ps_typeface_info[_plotter->drawstate->typeface_index].numfonts)
  688. cc || new_font_index < 0)
  689. cc new_font_index = 1; cc OOB -> use default font cc
  690. cc raw_fontnum = _ps_typeface_info[_plotter->drawstate->typeface_index].fonts[new_font_index];
  691. cc break;
  692. cc case F_OTHER:
  693. cc if (new_font_index != 0 && new_font_index != 1)
  694. cc new_font_index = 1; cc OOB -> use default font cc
  695. cc raw_fontnum = new_font_index;
  696. cc break;
  697. cc }
  698. cc }
  699. cc fontword = ((unsigned short)raw_fontnum) << FONT_SHIFT;
  700. cc continue; cc back to top of while loop cc
  701. cc }
  702. */
  703. /* couldn't match; unknown escape seq., so pass through unchanged */
  704. dest[j++] = fontword | (unsigned short)'\\';
  705. dest[j++] = fontword | (unsigned short)c;
  706. dest[j++] = fontword | (unsigned short)d;
  707. }
  708. }
  709. dest[j] = (unsigned short)'\0'; /* terminate string */
  710. return dest;
  711. }
  712. #ifdef UNUSED
  713. int
  714. #ifdef _HAVE_PROTOS
  715. _codestring_len (const unsigned short *codestring)
  716. #else
  717. _codestring_len (codestring)
  718. const unsigned short *codestring;
  719. #endif
  720. {
  721. int i = 0;
  722. while (*codestring)
  723. {
  724. i++;
  725. codestring++;
  726. }
  727. return i;
  728. }
  729. #endif