1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: gdevpsfx.c 8324 2007-10-26 07:41:30Z ken $ */
15
/* Convert Type 1 Charstrings to Type 2 */
21
#include "gxmatrix.h" /* for gsfont.h */
28
/* ------ Type 1 Charstring parsing ------ */
31
* The parsing code handles numbers on its own; it reports callsubr and
32
* return operators to the caller, but also executes them.
34
* Only the following elements of the Type 1 state are used:
35
* ostack, os_count, ipstack, ips_count
38
#define CE_OFFSET 32 /* offset for extended opcodes */
41
fixed v0, v1; /* coordinates */
42
ushort index; /* sequential index of hint */
46
int current; /* cache cursor for search */
48
* For dotsection and Type 1 Charstring hint replacement,
49
* we store active hints at the bottom of the table, and
50
* replaced hints at the top.
52
int replaced_count; /* # of replaced hints at top */
53
cv_stem_hint data[max_total_stem_hints];
56
/* Skip over the initial bytes in a Charstring, if any. */
58
skip_iv(gs_type1_state *pcis)
60
int skip = pcis->pfont->data.lenIV;
61
ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
62
const byte *cip = ipsp->cs_data.bits.data;
63
crypt_state state = crypt_charstring_seed;
65
for (; skip > 0; ++cip, --skip)
66
decrypt_skip_next(*cip, state);
72
* Set up for parsing a Type 1 Charstring.
74
* Only uses the following elements of *pfont:
78
type1_next_init(gs_type1_state *pcis, const gs_glyph_data_t *pgd,
81
gs_type1_interp_init(pcis, NULL, NULL, NULL, NULL, false, 0, pfont);
82
pcis->flex_count = flex_max;
83
pcis->ipstack[0].cs_data = *pgd;
87
/* Clear the Type 1 operand stack. */
89
type1_clear(gs_type1_state *pcis)
94
/* Execute a callsubr. */
96
type1_callsubr(gs_type1_state *pcis, int index)
98
gs_font_type1 *pfont = pcis->pfont;
99
ip_state_t *ipsp1 = &pcis->ipstack[pcis->ips_count];
100
int code = pfont->data.procs.subr_data(pfont, index, false,
110
/* Add 1 or 3 stem hints. */
112
type1_stem1(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv,
113
fixed lsb, byte *active_hints)
115
fixed v0 = pv[0] + lsb, v1 = v0 + pv[1];
116
cv_stem_hint *bot = &psht->data[0];
117
cv_stem_hint *orig_top = bot + psht->count;
118
cv_stem_hint *top = orig_top;
120
if (psht->count >= max_total_stem_hints)
121
return_error(gs_error_limitcheck);
123
(v0 < top[-1].v0 || (v0 == top[-1].v0 && v1 < top[-1].v1))
128
if (top > bot && v0 == top[-1].v0 && v1 == top[-1].v1) {
129
/* Duplicate hint, don't add it. */
130
memmove(top, top + 1, (char *)orig_top - (char *)top);
132
uint index = top[-1].index;
134
active_hints[index >> 3] |= 0x80 >> (index & 7);
144
type1_stem3(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv3,
145
fixed lsb, byte *active_hints)
147
type1_stem1(pcis, psht, pv3, lsb, active_hints);
148
type1_stem1(pcis, psht, pv3 + 2, lsb, active_hints);
149
type1_stem1(pcis, psht, pv3 + 4, lsb, active_hints);
153
* Get the next operator from a Type 1 Charstring. This procedure handles
154
* numbers, div, blend, pop, and callsubr/return.
157
type1_next(gs_type1_state *pcis)
159
ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
160
const byte *cip, *cipe;
162
#define CLEAR (csp = pcis->ostack - 1)
163
fixed *csp = &pcis->ostack[pcis->os_count - 1];
164
const bool encrypted = pcis->pfont->data.lenIV >= 0;
165
int c, code, num_results, c0;
169
cipe = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size;
170
state = ipsp->dstate;
173
return_error(gs_error_invalidfont);
175
charstring_next(c0, state, c, encrypted);
177
/* This is a number, decode it and push it on the stack. */
178
if (c < c_pos2_0) { /* 1-byte number */
179
decode_push_num1(csp, pcis->ostack, c);
180
} else if (c < cx_num4) { /* 2-byte number */
181
decode_push_num2(csp, pcis->ostack, c, cip, state, encrypted);
182
} else if (c == cx_num4) { /* 4-byte number */
185
decode_num4(lw, cip, state, encrypted);
186
CS_CHECK_PUSH(csp, pcis->ostack);
187
*++csp = int2fixed(lw);
188
if (lw != fixed2long(*csp)) {
190
* The integer was too large to handle in fixed point.
191
* Handle this case specially.
193
code = gs_type1_check_float(&state, encrypted, &cip, csp, lw);
197
} else /* not possible */
198
return_error(gs_error_invalidfont);
202
if (gs_debug_c('1')) {
205
for (p = pcis->ostack; p <= csp; ++p)
206
dprintf1(" %g", fixed2float(*p));
207
if (c == cx_escape) {
208
crypt_state cstate = state;
211
charstring_next(*cip, cstate, cn, encrypted);
212
dprintf1(" [*%d]\n", cn);
214
dprintf1(" [%d]\n", c);
217
switch ((char_command) c) {
223
return_error(gs_error_invalidfont);
225
code = type1_callsubr(pcis, fixed2int_var(*csp) +
226
pcis->pfont->data.subroutineNumberBias);
229
ipsp->ip = cip, ipsp->dstate = state;
234
gs_glyph_data_free(&ipsp->cs_data, "type1_next");
239
/* See gstype1.h for information on this opcode. */
243
charstring_next(*cip, state, c, encrypted);
245
switch ((char1_extended_command) c) {
250
csp[-1] = float2fixed((double)csp[-1] / (double)*csp);
253
case ce1_undoc15: /* see gstype1.h */
256
case ce1_callothersubr:
257
switch (fixed2int_var(*csp)) {
259
pcis->ignore_pops = 2;
260
break; /* pass to caller */
262
pcis->ignore_pops = 1;
263
break; /* pass to caller */
265
num_results = 1; goto blend;
267
num_results = 2; goto blend;
269
num_results = 3; goto blend;
271
num_results = 4; goto blend;
275
code = gs_type1_blend(pcis, csp, num_results);
281
break; /* pass to caller */
285
if (pcis->ignore_pops != 0) {
289
return_error(gs_error_rangecheck);
295
ipsp->ip = cip, ipsp->dstate = state;
296
pcis->ips_count = ipsp + 1 - &pcis->ipstack[0];
297
pcis->os_count = csp + 1 - &pcis->ostack[0];
301
/* ------ Output ------ */
303
/* Put 2 or 4 bytes on a stream (big-endian). */
305
sputc2(stream *s, int i)
307
sputc(s, (byte)(i >> 8));
311
sputc4(stream *s, int i)
317
/* Put a Type 2 operator on a stream. */
319
type2_put_op(stream *s, int op)
321
if (op >= CE_OFFSET) {
322
spputc(s, cx_escape);
323
spputc(s, (byte)(op - CE_OFFSET));
328
/* Put a Type 2 number on a stream. */
330
type2_put_int(stream *s, int i)
332
if (i >= -107 && i <= 107)
333
sputc(s, (byte)(i + 139));
334
else if (i <= 1131 && i >= 0)
335
sputc2(s, (c_pos2_0 << 8) + i - 108);
336
else if (i >= -1131 && i < 0)
337
sputc2(s, (c_neg2_0 << 8) - i - 108);
338
else if (i >= -32768 && i <= 32767) {
339
spputc(s, c2_shortint);
343
* We can't represent this number directly: compute it.
344
* (This can be done much more efficiently in particular cases;
345
* we'll do this if it ever seems worthwhile.)
347
type2_put_int(s, i >> 10);
348
type2_put_int(s, 1024);
349
type2_put_op(s, CE_OFFSET + ce2_mul);
350
type2_put_int(s, i & 1023);
351
type2_put_op(s, CE_OFFSET + ce2_add);
355
/* Put a fixed value on a stream. */
357
type2_put_fixed(stream *s, fixed v)
360
type2_put_int(s, fixed2int_var(v));
361
else if (v >= int2fixed(-32768) && v < int2fixed(32768)) {
362
/* We can represent this as a 16:16 number. */
364
sputc4(s, v << (16 - _fixed_shift));
366
type2_put_int(s, fixed2int_var(v));
367
type2_put_fixed(s, fixed_fraction(v));
368
type2_put_op(s, CE_OFFSET + ce2_add);
372
/* Put a stem hint table on a stream. */
374
type2_put_stems(stream *s, int os_count, const cv_stem_hint_table *psht, int op)
377
int pushed = os_count;
380
for (i = 0; i < psht->count; ++i, pushed += 2) {
381
fixed v0 = psht->data[i].v0;
382
fixed v1 = psht->data[i].v1;
384
if (pushed > ostack_size - 2) {
388
type2_put_fixed(s, v0 - prev);
389
type2_put_fixed(s, v1 - v0);
395
/* Put out a hintmask command. */
397
type2_put_hintmask(stream *s, const byte *mask, uint size)
401
type2_put_op(s, c2_hintmask);
402
sputs(s, mask, size, &ignore);
405
/* ------ Main program ------ */
409
* Convert a Type 1 Charstring to (unencrypted) Type 2.
410
* For simplicity, we expand all Subrs in-line.
411
* We still need to optimize the output using these patterns:
412
* (vhcurveto hvcurveto)* (vhcurveto hrcurveto | vrcurveto) =>
414
* (hvcurveto vhcurveto)* (hvcurveto vrcurveto | hrcurveto) =>
417
#define MAX_STACK ostack_size
419
psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd,
420
gs_font_type1 *pfont)
423
cv_stem_hint_table hstem_hints; /* horizontal stem hints */
424
cv_stem_hint_table vstem_hints; /* vertical stem hints */
426
bool need_moveto = true;
427
bool replace_hints = false;
428
bool hints_changed = false;
432
} dotsection_flag = dotsection_out;
433
byte active_hints[(max_total_stem_hints + 7) / 8];
434
byte dot_save_hints[(max_total_stem_hints + 7) / 8];
436
#define HINTS_CHANGED()\
438
hints_changed = replace_hints;\
440
CHECK_OP(); /* see below */\
442
#define CHECK_HINTS_CHANGED()\
444
if (hints_changed) {\
445
type2_put_hintmask(s, active_hints, hintmask_size);\
446
hints_changed = false;\
450
* In order to combine Type 1 operators, we usually delay writing
451
* out operators (but not their operands). We must keep track of
452
* the stack depth so we don't exceed it when combining operators.
454
int depth; /* of operands on stack */
455
int prev_op; /* operator to write, -1 if none */
457
(depth = 0, prev_op = -1)
461
type2_put_op(s, prev_op);\
465
fixed mx0 = 0, my0 = 0; /* See ce1_setcurrentpoint. */
468
* Do a first pass to collect hints. Note that we must also process
469
* [h]sbw, because the hint coordinates are relative to the lsb.
471
hstem_hints.count = hstem_hints.replaced_count = hstem_hints.current = 0;
472
vstem_hints.count = vstem_hints.replaced_count = vstem_hints.current = 0;
473
type1_next_init(&cis, pgd, pfont);
475
int c = type1_next(&cis);
476
fixed *csp = &cis.ostack[cis.os_count - 1];
485
gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
488
type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, NULL);
491
type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, NULL);
493
case CE_OFFSET + ce1_sbw:
494
gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
495
cis.ostack[2], cis.ostack[3]);
497
case CE_OFFSET + ce1_vstem3:
498
type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, NULL);
500
case CE_OFFSET + ce1_hstem3:
501
type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, NULL);
505
case ce1_callothersubr:
506
if (*csp == int2fixed(3))
507
replace_hints = true;
510
case CE_OFFSET + ce1_dotsection:
511
replace_hints = true;
513
case CE_OFFSET + ce1_seac:
520
* Number the hints for hintmask. We must do this even if we never
521
* replace hints, because type1_stem# uses the index to set bits in
527
for (i = 0; i < hstem_hints.count; ++i)
528
hstem_hints.data[i].index = i;
529
for (i = 0; i < vstem_hints.count; ++i)
530
vstem_hints.data[i].index = i + hstem_hints.count;
534
(hstem_hints.count + vstem_hints.count + 7) / 8;
535
memset(active_hints, 0, hintmask_size);
539
/* Do a second pass to write the result. */
540
type1_next_init(&cis, pgd, pfont);
543
int c = type1_next(&cis);
544
fixed *csp = &cis.ostack[cis.os_count - 1];
546
(csp -= (n), cis.os_count -= (n))
550
if (need_moveto && ((c >= cx_rlineto && c <= cx_rrcurveto) ||
551
c == cx_vhcurveto || c == cx_hvcurveto))
558
type2_put_fixed(s, *csp); /* width */
559
mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
561
/* We need to move all the stored numeric values up by
562
* one in the stack, eliminating the width, so that later
563
* processing when we handle the drswing operator emits the correct
564
* values. This is different to the 'move' case below.
567
for (i = 0; i < cis.os_count; ++i)
568
cis.ostack[i] = cis.ostack[i+1];
570
CHECK_HINTS_CHANGED();
572
type2_put_fixed(s, my);
573
depth = 1, prev_op = cx_vmoveto;
574
} else if (my == 0) {
575
type2_put_fixed(s, mx);
576
depth = 1, prev_op = cx_hmoveto;
578
type2_put_fixed(s, mx);
579
type2_put_fixed(s, my);
580
depth = 2, prev_op = cx_rmoveto;
589
return_error(gs_error_rangecheck);
590
/* The Type 1 use of all other operators is the same in Type 2. */
593
CHECK_HINTS_CHANGED();
595
for (i = 0; i < cis.os_count; ++i)
596
type2_put_fixed(s, cis.ostack[i]);
597
depth += cis.os_count;
602
type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, active_hints);
608
type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, active_hints);
610
case CE_OFFSET + ce1_vstem3:
611
type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, active_hints);
613
case CE_OFFSET + ce1_hstem3:
614
type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, active_hints);
616
case CE_OFFSET + ce1_dotsection:
617
if (dotsection_flag == dotsection_out) {
618
memcpy(dot_save_hints, active_hints, hintmask_size);
619
memset(active_hints, 0, hintmask_size);
620
dotsection_flag = dotsection_in;
622
memcpy(active_hints, dot_save_hints, hintmask_size);
623
dotsection_flag = dotsection_out;
630
case CE_OFFSET + ce1_setcurrentpoint:
632
/* A workaround for fonts which use ce1_setcurrentpoint
633
in an illegal way for shifting a path.
634
See t1_hinter__setcurrentpoint for more information. */
635
mx0 = csp[-1], my0 = *csp;
645
mx = csp[-1], my = *csp;
652
type2_put_fixed(s, *csp); /* width */
653
mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
656
if (cis.flex_count != flex_max) {
657
/* We're accumulating points for a flex. */
658
if (type1_next(&cis) != ce1_callothersubr)
659
return_error(gs_error_rangecheck);
660
csp = &cis.ostack[cis.os_count - 1];
661
if (*csp != int2fixed(2) || csp[-1] != fixed_0)
662
return_error(gs_error_rangecheck);
664
csp[-1] = mx, *csp = my;
667
CHECK_HINTS_CHANGED();
669
type2_put_fixed(s, my);
670
depth = 1, prev_op = cx_vmoveto;
671
} else if (my == 0) {
672
type2_put_fixed(s, mx);
673
depth = 1, prev_op = cx_hmoveto;
675
type2_put_fixed(s, mx);
676
type2_put_fixed(s, my);
677
depth = 2, prev_op = cx_rmoveto;
682
gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
684
* Leave the l.s.b. on the operand stack for the initial hint,
685
* moveto, or endchar command.
687
cis.ostack[0] = cis.ostack[1];
689
/* cff_write_Private doesn't write defaultWidthX
690
when called with the Type 1 font,
691
so the reader will assume
692
defaultWidthX = defaultWidthX_DEFAULT
695
if (cis.ostack[0] == default_defaultWidthX)
698
cis.ostack[0] -= default_defaultWidthX;
701
if (hstem_hints.count) {
703
type2_put_fixed(s, cis.ostack[0]);
704
type2_put_stems(s, cis.os_count, &hstem_hints,
705
(replace_hints ? c2_hstemhm : cx_hstem));
708
if (vstem_hints.count) {
710
type2_put_fixed(s, cis.ostack[0]);
711
type2_put_stems(s, cis.os_count, &vstem_hints,
712
(replace_hints ? c2_vstemhm : cx_vstem));
716
case CE_OFFSET + ce1_seac:
718
* It is an undocumented feature of the Type 2 CharString
719
* format that endchar + 4 or 5 operands is equivalent to
720
* seac with an implicit asb operand + endchar with 0 or 1
721
* operands. Remove the asb argument from the stack, but
722
* adjust the adx argument to compensate for the fact that
723
* Type 2 CharStrings don't have any concept of l.s.b.
725
csp[-3] += cis.lsb.x - csp[-4];
726
memmove(csp - 4, csp - 3, sizeof(*csp) * 4);
728
/* (falls through) */
731
for (i = 0; i < cis.os_count; ++i)
732
type2_put_fixed(s, cis.ostack[i]);
733
type2_put_op(s, cx_endchar);
735
case CE_OFFSET + ce1_sbw:
736
gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
737
cis.ostack[2], cis.ostack[3]);
738
cis.ostack[0] = cis.ostack[2];
740
case ce1_callothersubr:
742
switch (fixed2int_var(*csp)) {
744
return_error(gs_error_rangecheck);
747
* The operand stack contains: delta to reference point,
748
* 6 deltas for the two curves, fd, final point, 3, 0.
750
csp[-18] += csp[-16], csp[-17] += csp[-15];
751
memmove(csp - 16, csp - 14, sizeof(*csp) * 11);
752
cis.os_count -= 6, csp -= 6;
754
* We could optimize by using [h]flex[1],
755
* but it isn't worth the trouble.
757
c = CE_OFFSET + ce2_flex;
758
cis.flex_count = flex_max; /* not inside flex */
765
/*case 2:*/ /* detected in *moveto */
767
memset(active_hints, 0, hintmask_size);
774
/* Counter control is not implemented. */
775
cis.os_count -= 2 + fixed2int(csp[-1]);
779
* The remaining cases are strictly for optimization.
782
if (depth > MAX_STACK - 2)
785
case cx_rlineto: /* rlineto+ => rlineto */
787
case cx_rrcurveto: /* rrcurveto+ rlineto => rcurveline */
793
case cx_hlineto: /* hlineto (vlineto hlineto)* [vlineto] => hlineto */
794
if (depth > MAX_STACK - 1 ||
795
prev_op != (depth & 1 ? cx_vlineto : cx_hlineto))
799
case cx_vlineto: /* vlineto (hlineto vlineto)* [hlineto] => vlineto */
800
if (depth > MAX_STACK - 1 ||
801
prev_op != (depth & 1 ? cx_hlineto : cx_vlineto))
805
case cx_hvcurveto: /* hvcurveto (vhcurveto hvcurveto)* => hvcurveto */
806
/* (vhcurveto hvcurveto)+ => vhcurveto */
808
* We have to check (depth & 1) because the last curve might
809
* have 5 parameters rather than 4 (see rrcurveto below).
811
if ((depth & 1) || depth > MAX_STACK - 4 ||
812
prev_op != (depth & 4 ? cx_vhcurveto : cx_hvcurveto))
816
case cx_vhcurveto: /* vhcurveto (hvcurveto vhcurveto)* => vhcurveto */
817
/* (hvcurveto vhcurveto)+ => hvcurveto */
818
/* See above re the (depth & 1) check. */
819
if ((depth & 1) || depth > MAX_STACK - 4 ||
820
prev_op != (depth & 4 ? cx_hvcurveto : cx_vhcurveto))
827
/* A|0 B C D 0 F rrcurveto => [A] B C D F vvcurveto */
831
memmove(csp - 5, csp - 4, sizeof(*csp) * 4);
835
} else if (*csp == 0) {
836
/* A B|0 C D E 0 rrcurveto => [B] A C D E hhcurveto */
839
memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
842
*csp = csp[-5], csp[-5] = csp[-4], csp[-4] = *csp;
847
* We could also optimize:
848
* 0 B C D E F|0 rrcurveto => B C D E [F] vhcurveto
849
* A 0 C D E|0 F rrcurveto => A C D F [E] hvcurveto
850
* but this gets in the way of subsequent optimization
851
* of multiple rrcurvetos, so we don't do it.
855
if (depth > MAX_STACK - 6)
858
case c2_hhcurveto: /* hrcurveto (x1 0 x2 y2 x3 0 rrcurveto)* => */
860
if (csp[-4] == 0 && *csp == 0) {
861
memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
867
case c2_vvcurveto: /* rvcurveto (0 y1 x2 y2 0 y3 rrcurveto)* => */
869
if (csp[-5] == 0 && csp[-1] == 0) {
870
memmove(csp - 5, csp - 4, sizeof(*csp) * 3);
882
vrc: /* (vhcurveto hvcurveto)+ vrcurveto => vhcurveto */
883
/* hvcurveto (vhcurveto hvcurveto)* vrcurveto => hvcurveto */
886
memmove(csp - 5, csp - 4, sizeof(*csp) * 5);
895
hrc: /* (hvcurveto vhcurveto)+ hrcurveto => hvcurveto */
896
/* vhcurveto (hvcurveto vhcurveto)* hrcurveto => vhcurveto */
899
/* A 0 C D E F => A C D F E */
900
memmove(csp - 4, csp - 3, sizeof(*csp) * 2);
905
case cx_rlineto: /* rlineto+ rrcurveto => rlinecurve */
908
case cx_rrcurveto: /* rrcurveto+ => rrcurveto */