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