xref: /plan9/sys/src/cmd/gs/src/gstype1.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1990, 2000 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gstype1.c,v 1.32 2004/10/28 08:39:21 igor Exp $ */
18 /* Adobe Type 1 charstring interpreter */
19 #include "math_.h"
20 #include "memory_.h"
21 #include "gx.h"
22 #include "gserrors.h"
23 #include "gsstruct.h"
24 #include "gxarith.h"
25 #include "gxfixed.h"
26 #include "gxmatrix.h"
27 #include "gxcoord.h"
28 #include "gxistate.h"
29 #include "gxpath.h"
30 #include "gxfont.h"
31 #include "gxfont1.h"
32 #include "gxtype1.h"
33 #include "gxhintn.h"
34 
35 /*
36  * Define whether to always do Flex segments as curves.
37  * This is only an issue because some old Adobe DPS fonts
38  * seem to violate the Flex specification in a way that requires this.
39  * We changed this from 1 to 0 in release 5.02: if it causes any
40  * problems, we'll implement a more sophisticated test.
41  */
42 #define ALWAYS_DO_FLEX_AS_CURVE 0
43 
44 /* ------ Main interpreter ------ */
45 
46 /*
47  * Continue interpreting a Type 1 charstring.  If str != 0, it is taken as
48  * the byte string to interpret.  Return 0 on successful completion, <0 on
49  * error, or >0 when client intervention is required (or allowed).  The int*
50  * argument is where the othersubr # is stored for callothersubr.
51  */
52 int
gs_type1_interpret(gs_type1_state * pcis,const gs_glyph_data_t * pgd,int * pindex)53 gs_type1_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd,
54 		   int *pindex)
55 {
56     gs_font_type1 *pfont = pcis->pfont;
57     gs_type1_data *pdata = &pfont->data;
58     t1_hinter *h = &pcis->h;
59     bool encrypted = pdata->lenIV >= 0;
60     fixed cstack[ostack_size];
61 
62 #define cs0 cstack[0]
63 #define ics0 fixed2int_var(cs0)
64 #define cs1 cstack[1]
65 #define ics1 fixed2int_var(cs1)
66 #define cs2 cstack[2]
67 #define ics2 fixed2int_var(cs2)
68 #define cs3 cstack[3]
69 #define ics3 fixed2int_var(cs3)
70 #define cs4 cstack[4]
71 #define ics4 fixed2int_var(cs4)
72 #define cs5 cstack[5]
73 #define ics5 fixed2int_var(cs5)
74     cs_ptr csp;
75 #define clear CLEAR_CSTACK(cstack, csp)
76     ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
77     register const byte *cip;
78     register crypt_state state;
79     register int c;
80     int code = 0;
81     fixed ftx = pcis->origin.x, fty = pcis->origin.y;
82 
83     switch (pcis->init_done) {
84 	case -1:
85 	    t1_hinter__init(h, pcis->path);
86 	    break;
87 	case 0:
88 	    gs_type1_finish_init(pcis);	/* sets origin */
89 	    ftx = pcis->origin.x, fty = pcis->origin.y;
90             code = t1_hinter__set_mapping(h, &pcis->pis->ctm,
91 			    &pfont->FontMatrix, &pfont->base->FontMatrix,
92 			    pcis->scale.x.log2_unit, pcis->scale.x.log2_unit,
93 			    pcis->scale.x.log2_unit - pcis->log2_subpixels.x,
94 			    pcis->scale.y.log2_unit - pcis->log2_subpixels.y,
95 			    pcis->origin.x, pcis->origin.y,
96 			    gs_currentaligntopixels(pfont->dir));
97 	    if (code < 0)
98 	    	return code;
99 	    code = t1_hinter__set_font_data(h, 1, pdata, pcis->no_grid_fitting);
100 	    if (code < 0)
101 	    	return code;
102 	    break;
103 	default /*case 1 */ :
104 	    break;
105     }
106     INIT_CSTACK(cstack, csp, pcis);
107 
108     if (pgd == 0)
109 	goto cont;
110     ipsp->cs_data = *pgd;
111     cip = pgd->bits.data;
112   call:state = crypt_charstring_seed;
113     if (encrypted) {
114 	int skip = pdata->lenIV;
115 
116 	/* Skip initial random bytes */
117 	for (; skip > 0; ++cip, --skip)
118 	    decrypt_skip_next(*cip, state);
119     }
120     goto top;
121   cont:cip = ipsp->ip;
122     state = ipsp->dstate;
123   top:for (;;) {
124 	uint c0 = *cip++;
125 
126 	charstring_next(c0, state, c, encrypted);
127 	if (c >= c_num1) {
128 	    /* This is a number, decode it and push it on the stack. */
129 
130 	    if (c < c_pos2_0) {	/* 1-byte number */
131 		decode_push_num1(csp, cstack, c);
132 	    } else if (c < cx_num4) {	/* 2-byte number */
133 		decode_push_num2(csp, cstack, c, cip, state, encrypted);
134 	    } else if (c == cx_num4) {	/* 4-byte number */
135 		long lw;
136 
137 		decode_num4(lw, cip, state, encrypted);
138 		CS_CHECK_PUSH(csp, cstack);
139 		*++csp = int2fixed(lw);
140 		if (lw != fixed2long(*csp)) {
141 		    /*
142 		     * We handle the only case we've ever seen that
143 		     * actually uses such large numbers specially.
144 		     */
145 		    long denom;
146 
147 		    c0 = *cip++;
148 		    charstring_next(c0, state, c, encrypted);
149 		    if (c < c_num1)
150 			return_error(gs_error_rangecheck);
151 		    if (c < c_pos2_0)
152 			decode_num1(denom, c);
153 		    else if (c < cx_num4)
154 			decode_num2(denom, c, cip, state, encrypted);
155 		    else if (c == cx_num4)
156 			decode_num4(denom, cip, state, encrypted);
157 		    else
158 			return_error(gs_error_invalidfont);
159 		    c0 = *cip++;
160 		    charstring_next(c0, state, c, encrypted);
161 		    if (c != cx_escape)
162 			return_error(gs_error_rangecheck);
163 		    c0 = *cip++;
164 		    charstring_next(c0, state, c, encrypted);
165 		    if (c != ce1_div)
166 			return_error(gs_error_rangecheck);
167 		    *csp = float2fixed((double)lw / denom);
168 		}
169 	    } else		/* not possible */
170 		return_error(gs_error_invalidfont);
171 	  pushed:if_debug3('1', "[1]%d: (%d) %f\n",
172 		      (int)(csp - cstack), c, fixed2float(*csp));
173 	    continue;
174 	}
175 #ifdef DEBUG
176 	if (gs_debug['1']) {
177 	    static const char *const c1names[] =
178 	    {char1_command_names};
179 
180 	    if (c1names[c] == 0)
181 		dlprintf2("[1]0x%lx: %02x??\n", (ulong) (cip - 1), c);
182 	    else
183 		dlprintf3("[1]0x%lx: %02x %s\n", (ulong) (cip - 1), c,
184 			  c1names[c]);
185 	}
186 #endif
187 	switch ((char_command) c) {
188 #define cnext clear; goto top
189 #define inext goto top
190 
191 		/* Commands with identical functions in Type 1 and Type 2, */
192 		/* except for 'escape'. */
193 
194 	    case c_undef0:
195 	    case c_undef2:
196 	    case c_undef17:
197 		return_error(gs_error_invalidfont);
198 	    case c_callsubr:
199 		c = fixed2int_var(*csp) + pdata->subroutineNumberBias;
200 		code = pdata->procs.subr_data
201 		    (pfont, c, false, &ipsp[1].cs_data);
202 		if (code < 0)
203 		    return_error(code);
204 		--csp;
205 		ipsp->ip = cip, ipsp->dstate = state;
206 		++ipsp;
207 		cip = ipsp->cs_data.bits.data;
208 		goto call;
209 	    case c_return:
210 		gs_glyph_data_free(&ipsp->cs_data, "gs_type1_interpret");
211 		--ipsp;
212 		goto cont;
213 	    case c_undoc15:
214 		/* See gstype1.h for information on this opcode. */
215 		cnext;
216 
217 		/* Commands with similar but not identical functions */
218 		/* in Type 1 and Type 2 charstrings. */
219 
220 	    case cx_hstem:
221                 code = t1_hinter__hstem(h, cs0, cs1);
222 		if (code < 0)
223 		    return code;
224 		cnext;
225 	    case cx_vstem:
226                 code = t1_hinter__vstem(h, cs0, cs1);
227 		if (code < 0)
228 		    return code;
229 		cnext;
230 	    case cx_vmoveto:
231 		cs1 = cs0;
232 		cs0 = 0;
233 	      move:		/* cs0 = dx, cs1 = dy for hint checking. */
234                 code = t1_hinter__rmoveto(h, cs0, cs1);
235 		goto cc;
236 	    case cx_rlineto:
237 	      line:		/* cs0 = dx, cs1 = dy for hint checking. */
238                 code = t1_hinter__rlineto(h, cs0, cs1);
239 	      cc:if (code < 0)
240 		    return code;
241 		cnext;
242 	    case cx_hlineto:
243 		cs1 = 0;
244 		goto line;
245 	    case cx_vlineto:
246 		cs1 = cs0;
247 		cs0 = 0;
248 		goto line;
249 	    case cx_rrcurveto:
250                 code = t1_hinter__rcurveto(h, cs0, cs1, cs2, cs3, cs4, cs5);
251 		goto cc;
252 	    case cx_endchar:
253                 code = t1_hinter__endchar(h, (pcis->seac_accent >= 0));
254 		if (code < 0)
255 		    return code;
256                 if (pcis->seac_accent < 0) {
257                     code = t1_hinter__endglyph(h);
258 		    if (code < 0)
259 			return code;
260 		    code = gx_setcurrentpoint_from_path(pcis->pis, pcis->path);
261 		    if (code < 0)
262 			return code;
263 		}
264 		code = gs_type1_endchar(pcis);
265 		if (code == 1) {
266 		    /* do accent of seac */
267 		    ipsp = &pcis->ipstack[pcis->ips_count - 1];
268 		    cip = ipsp->cs_data.bits.data;
269 		    goto call;
270 		}
271 		return code;
272 	    case cx_rmoveto:
273 		goto move;
274 	    case cx_hmoveto:
275 		cs1 = 0;
276 		goto move;
277 	    case cx_vhcurveto:
278                 code = t1_hinter__rcurveto(h, 0, cs0, cs1, cs2, cs3, 0);
279 		goto cc;
280 	    case cx_hvcurveto:
281                 code = t1_hinter__rcurveto(h, cs0, 0, cs1, cs2, 0, cs3);
282 		goto cc;
283 
284 		/* Commands only recognized in Type 1 charstrings, */
285 		/* plus 'escape'. */
286 
287 	    case c1_closepath:
288                 code = t1_hinter__closepath(h);
289 		goto cc;
290 	    case c1_hsbw:
291                 if (!h->seac_flag) {
292 		    fixed sbx = cs0, sby = fixed_0, wx = cs1, wy = fixed_0;
293 
294 		    if (pcis->sb_set) {
295 			sbx = pcis->lsb.x;
296 			sby = pcis->lsb.y;
297 		    }
298 		    if (pcis->width_set) {
299 			wx = pcis->width.x;
300 			wy = pcis->width.y;
301 		    }
302 		    code = t1_hinter__sbw(h, sbx, sby, wx, wy);
303                 } else
304                     code = t1_hinter__sbw_seac(h, pcis->adxy.x, pcis->adxy.y);
305 		if (code < 0)
306 		    return code;
307 		gs_type1_sbw(pcis, cs0, fixed_0, cs1, fixed_0);
308 		cs1 = fixed_0;
309 rsbw:		/* Give the caller the opportunity to intervene. */
310 		pcis->os_count = 0;	/* clear */
311 		ipsp->ip = cip, ipsp->dstate = state;
312 		pcis->ips_count = ipsp - &pcis->ipstack[0] + 1;
313 		/* If we aren't in a seac, do nothing else now; */
314 		/* finish_init will take care of the rest. */
315 		if (pcis->init_done < 0) {
316 		    /* Finish init when we return. */
317 		    pcis->init_done = 0;
318 		} else {
319 		    /*
320 		     * Accumulate the side bearing now, but don't do it
321 		     * a second time for the base character of a seac.
322 		     */
323 		    if (pcis->seac_accent >= 0) {
324 			/*
325 			 * As a special hack to work around a bug in
326 			 * Fontographer, we deal with the (illegal)
327 			 * situation in which the side bearing of the
328 			 * accented character (save_lsbx) is different from
329 			 * the side bearing of the base character (cs0/cs1).
330 			 */
331 			fixed dsbx = cs0 - pcis->save_lsb.x;
332 			fixed dsby = cs1 - pcis->save_lsb.y;
333 
334 			if (dsbx | dsby) {
335 			    pcis->lsb.x += dsbx;
336 			    pcis->lsb.y += dsby;
337 			    pcis->save_adxy.x -= dsbx;
338 			    pcis->save_adxy.y -= dsby;
339 			}
340 		    }
341 		}
342 		return type1_result_sbw;
343 	    case cx_escape:
344 		charstring_next(*cip, state, c, encrypted);
345 		++cip;
346 #ifdef DEBUG
347 		if (gs_debug['1'] && c < char1_extended_command_count) {
348 		    static const char *const ce1names[] =
349 		    {char1_extended_command_names};
350 
351 		    if (ce1names[c] == 0)
352 			dlprintf2("[1]0x%lx: %02x??\n", (ulong) (cip - 1), c);
353 		    else
354 			dlprintf3("[1]0x%lx: %02x %s\n", (ulong) (cip - 1), c,
355 				  ce1names[c]);
356 		}
357 #endif
358 		switch ((char1_extended_command) c) {
359 		    case ce1_dotsection:
360                         code = t1_hinter__dotsection(h);
361 			if (code < 0)
362 			    return code;
363 			cnext;
364 		    case ce1_vstem3:
365                         code = t1_hinter__vstem3(h, cs0, cs1, cs2, cs3, cs4, cs5);
366 			if (code < 0)
367 			    return code;
368 			cnext;
369 		    case ce1_hstem3:
370                         code = t1_hinter__hstem3(h, cs0, cs1, cs2, cs3, cs4, cs5);
371 			if (code < 0)
372 			    return code;
373 			cnext;
374 		    case ce1_seac:
375 			code = gs_type1_seac(pcis, cstack + 1, cstack[0],
376 					     ipsp);
377 			if (code != 0) {
378 			    *pindex = ics3;
379 			    return code;
380 			}
381 			clear;
382 			cip = ipsp->cs_data.bits.data;
383 			goto call;
384 		    case ce1_sbw:
385                         if (!h->seac_flag)
386                             code = t1_hinter__sbw(h, cs0, cs1, cs2, cs3);
387                         else
388                             code = t1_hinter__sbw_seac(h, cs0 + pcis->adxy.x , cs1 + pcis->adxy.y);
389 			if (code < 0)
390 			    return code;
391 			gs_type1_sbw(pcis, cs0, cs1, cs2, cs3);
392 			goto rsbw;
393 		    case ce1_div:
394 			csp[-1] = float2fixed((double)csp[-1] / (double)*csp);
395 			--csp;
396 			goto pushed;
397 		    case ce1_undoc15:
398 			/* See gstype1.h for information on this opcode. */
399 			cnext;
400 		    case ce1_callothersubr:
401 			{
402 			    int num_results;
403 			    /* We must remember to pop both the othersubr # */
404 			    /* and the argument count off the stack. */
405 			    switch (*pindex = fixed2int_var(*csp)) {
406 				case 0:
407 				    {
408 					fixed fheight = csp[-4];
409 					/* Assume the next two opcodes */
410 					/* are `pop' `pop'.  Unfortunately, some */
411 					/* Monotype fonts put these in a Subr, */
412 					/* so we can't just look ahead in the */
413 					/* opcode stream. */
414 					pcis->ignore_pops = 2;
415 					csp[-4] = csp[-3] - pcis->asb_diff;
416 					csp[-3] = csp[-2];
417 					csp -= 3;
418 					code = t1_hinter__flex_end(h, fheight);
419 				    }
420 				    if (code < 0)
421 					return code;
422 				    pcis->flex_count = flex_max;	/* not inside flex */
423 				    inext;
424 				case 1:
425 				    code = t1_hinter__flex_beg(h);
426 				    if (code < 0)
427 					return code;
428 				    pcis->flex_count = 1;
429 				    csp -= 2;
430 				    inext;
431 				case 2:
432 				    if (pcis->flex_count >= flex_max)
433 					return_error(gs_error_invalidfont);
434 				    code = t1_hinter__flex_point(h);
435 				    if (code < 0)
436 					return code;
437 				    csp -= 2;
438 				    inext;
439 				case 3:
440 				    /* Assume the next opcode is a `pop'. */
441 				    /* See above as to why we don't just */
442 				    /* look ahead in the opcode stream. */
443 				    pcis->ignore_pops = 1;
444                                     code = t1_hinter__drop_hints(h);
445 				    if (code < 0)
446 					return code;
447 				    csp -= 2;
448 				    inext;
449 				case 12:
450 				case 13:
451 				    /* Counter control isn't implemented. */
452 				    cnext;
453 				case 14:
454 				    num_results = 1;
455 				  blend:
456 				    code = gs_type1_blend(pcis, csp,
457 							  num_results);
458 				    if (code < 0)
459 					return code;
460 				    csp -= code;
461 				    inext;
462 				case 15:
463 				    num_results = 2;
464 				    goto blend;
465 				case 16:
466 				    num_results = 3;
467 				    goto blend;
468 				case 17:
469 				    num_results = 4;
470 				    goto blend;
471 				case 18:
472 				    num_results = 6;
473 				    goto blend;
474 			    }
475 			}
476 			/* Not a recognized othersubr, */
477 			/* let the client handle it. */
478 			{
479 			    int scount = csp - cstack;
480 			    int n;
481 
482 			    /* Copy the arguments to the caller's stack. */
483 			    if (scount < 1 || csp[-1] < 0 ||
484 				csp[-1] > int2fixed(scount - 1)
485 				)
486 				return_error(gs_error_invalidfont);
487 			    n = fixed2int_var(csp[-1]);
488 			    code = (*pdata->procs.push_values)
489 				(pcis->callback_data, csp - (n + 1), n);
490 			    if (code < 0)
491 				return_error(code);
492 			    scount -= n + 1;
493 			    /* Exit to caller */
494 			    ipsp->ip = cip, ipsp->dstate = state;
495 			    pcis->os_count = scount;
496 			    pcis->ips_count = ipsp - &pcis->ipstack[0] + 1;
497 			    if (scount)
498 				memcpy(pcis->ostack, cstack, scount * sizeof(fixed));
499 			    return type1_result_callothersubr;
500 			}
501 		    case ce1_pop:
502 			/* Check whether we're ignoring the pops after */
503 			/* a known othersubr. */
504 			if (pcis->ignore_pops != 0) {
505 			    pcis->ignore_pops--;
506 			    inext;
507 			}
508 			CS_CHECK_PUSH(csp, cstack);
509 			++csp;
510 			code = (*pdata->procs.pop_value)
511 			    (pcis->callback_data, csp);
512 			if (code < 0)
513 			    return_error(code);
514 			goto pushed;
515 		    case ce1_setcurrentpoint:
516 			t1_hinter__setcurrentpoint(h, cs0, cs1);
517 			cs0 += pcis->adxy.x;
518 			cs1 += pcis->adxy.y;
519 			cnext;
520 		    default:
521 			return_error(gs_error_invalidfont);
522 		}
523 		/*NOTREACHED */
524 
525 		/* Fill up the dispatch up to 32. */
526 
527 	      case_c1_undefs:
528 	    default:		/* pacify compiler */
529 		return_error(gs_error_invalidfont);
530 	}
531     }
532 }
533