~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to base/gdevpsfx.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
 
2
   All Rights Reserved.
 
3
  
 
4
   This software is provided AS-IS with no warranty, either express or
 
5
   implied.
 
6
 
 
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.
 
12
*/
 
13
 
 
14
/* $Id: gdevpsfx.c 8324 2007-10-26 07:41:30Z ken $ */
 
15
/* Convert Type 1 Charstrings to Type 2 */
 
16
#include "math_.h"
 
17
#include "memory_.h"
 
18
#include "gx.h"
 
19
#include "gserrors.h"
 
20
#include "gxfixed.h"
 
21
#include "gxmatrix.h"           /* for gsfont.h */
 
22
#include "gxfont.h"
 
23
#include "gxfont1.h"
 
24
#include "gxtype1.h"
 
25
#include "stream.h"
 
26
#include "gdevpsf.h"
 
27
 
 
28
/* ------ Type 1 Charstring parsing ------ */
 
29
 
 
30
/*
 
31
 * The parsing code handles numbers on its own; it reports callsubr and
 
32
 * return operators to the caller, but also executes them.
 
33
 *
 
34
 * Only the following elements of the Type 1 state are used:
 
35
 *      ostack, os_count, ipstack, ips_count
 
36
 */
 
37
 
 
38
#define CE_OFFSET 32            /* offset for extended opcodes */
 
39
 
 
40
typedef struct {
 
41
    fixed v0, v1;               /* coordinates */
 
42
    ushort index;               /* sequential index of hint */
 
43
} cv_stem_hint;
 
44
typedef struct {
 
45
    int count;
 
46
    int current;                /* cache cursor for search */
 
47
    /*
 
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.
 
51
     */
 
52
    int replaced_count;         /* # of replaced hints at top */
 
53
    cv_stem_hint data[max_total_stem_hints];
 
54
} cv_stem_hint_table;
 
55
 
 
56
/* Skip over the initial bytes in a Charstring, if any. */
 
57
static void
 
58
skip_iv(gs_type1_state *pcis)
 
59
{
 
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;
 
64
 
 
65
    for (; skip > 0; ++cip, --skip)
 
66
        decrypt_skip_next(*cip, state);
 
67
    ipsp->ip = cip;
 
68
    ipsp->dstate = state;
 
69
}
 
70
 
 
71
/*
 
72
 * Set up for parsing a Type 1 Charstring.
 
73
 *
 
74
 * Only uses the following elements of *pfont:
 
75
 *      data.lenIV
 
76
 */
 
77
static void
 
78
type1_next_init(gs_type1_state *pcis, const gs_glyph_data_t *pgd,
 
79
                gs_font_type1 *pfont)
 
80
{
 
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;
 
84
    skip_iv(pcis);
 
85
}
 
86
 
 
87
/* Clear the Type 1 operand stack. */
 
88
static inline void
 
89
type1_clear(gs_type1_state *pcis)
 
90
{
 
91
    pcis->os_count = 0;
 
92
}
 
93
 
 
94
/* Execute a callsubr. */
 
95
static int
 
96
type1_callsubr(gs_type1_state *pcis, int index)
 
97
{
 
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,
 
101
                                           &ipsp1->cs_data);
 
102
 
 
103
    if (code < 0)
 
104
        return_error(code);
 
105
    pcis->ips_count++;
 
106
    skip_iv(pcis);
 
107
    return code;
 
108
}
 
109
 
 
110
/* Add 1 or 3 stem hints. */
 
111
static int
 
112
type1_stem1(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv,
 
113
            fixed lsb, byte *active_hints)
 
114
{
 
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;
 
119
 
 
120
    if (psht->count >= max_total_stem_hints)
 
121
        return_error(gs_error_limitcheck);
 
122
    while (top > bot &&
 
123
           (v0 < top[-1].v0 || (v0 == top[-1].v0 && v1 < top[-1].v1))
 
124
           ) {
 
125
        *top = top[-1];
 
126
        top--;
 
127
    }
 
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);
 
131
        if (active_hints) {
 
132
            uint index = top[-1].index;
 
133
 
 
134
            active_hints[index >> 3] |= 0x80 >> (index & 7);
 
135
        }
 
136
        return 0;
 
137
    }
 
138
    top->v0 = v0;
 
139
    top->v1 = v1;
 
140
    psht->count++;
 
141
    return 0;
 
142
}
 
143
static void
 
144
type1_stem3(gs_type1_state *pcis, cv_stem_hint_table *psht, const fixed *pv3,
 
145
            fixed lsb, byte *active_hints)
 
146
{
 
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);
 
150
}
 
151
 
 
152
/*
 
153
 * Get the next operator from a Type 1 Charstring.  This procedure handles
 
154
 * numbers, div, blend, pop, and callsubr/return.
 
155
 */
 
156
static int
 
157
type1_next(gs_type1_state *pcis)
 
158
{
 
159
    ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
 
160
    const byte *cip, *cipe;
 
161
    crypt_state state;
 
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;
 
166
 
 
167
 load:
 
168
    cip = ipsp->ip;
 
169
    cipe = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size;
 
170
    state = ipsp->dstate;
 
171
    for (;;) {
 
172
        if (cip >= cipe)
 
173
            return_error(gs_error_invalidfont);
 
174
        c0 = *cip++;
 
175
        charstring_next(c0, state, c, encrypted);
 
176
        if (c >= c_num1) {
 
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 */
 
183
                long lw;
 
184
 
 
185
                decode_num4(lw, cip, state, encrypted);
 
186
                CS_CHECK_PUSH(csp, pcis->ostack);
 
187
                *++csp = int2fixed(lw);
 
188
                if (lw != fixed2long(*csp)) {
 
189
                    /*
 
190
                     * The integer was too large to handle in fixed point.
 
191
                     * Handle this case specially.
 
192
                     */
 
193
                    code = gs_type1_check_float(&state, encrypted, &cip, csp, lw);
 
194
                    if (code < 0)
 
195
                       return code;
 
196
                }
 
197
            } else              /* not possible */
 
198
                return_error(gs_error_invalidfont);
 
199
            continue;
 
200
        }
 
201
#ifdef DEBUG
 
202
        if (gs_debug_c('1')) {
 
203
            const fixed *p;
 
204
 
 
205
            for (p = pcis->ostack; p <= csp; ++p)
 
206
                dprintf1(" %g", fixed2float(*p));
 
207
            if (c == cx_escape) {
 
208
                crypt_state cstate = state;
 
209
                int cn;
 
210
 
 
211
                charstring_next(*cip, cstate, cn, encrypted);
 
212
                dprintf1(" [*%d]\n", cn);
 
213
            } else
 
214
                dprintf1(" [%d]\n", c);
 
215
        }
 
216
#endif
 
217
        switch ((char_command) c) {
 
218
        default:
 
219
            break;
 
220
        case c_undef0:
 
221
        case c_undef2:
 
222
        case c_undef17:
 
223
            return_error(gs_error_invalidfont);
 
224
        case c_callsubr:
 
225
            code = type1_callsubr(pcis, fixed2int_var(*csp) +
 
226
                                  pcis->pfont->data.subroutineNumberBias);
 
227
            if (code < 0)
 
228
                return_error(code);
 
229
            ipsp->ip = cip, ipsp->dstate = state;
 
230
            --csp;
 
231
            ++ipsp;
 
232
            goto load;
 
233
        case c_return:
 
234
            gs_glyph_data_free(&ipsp->cs_data, "type1_next");
 
235
            pcis->ips_count--;
 
236
            --ipsp;
 
237
            goto load;
 
238
        case c_undoc15:
 
239
            /* See gstype1.h for information on this opcode. */
 
240
            CLEAR;
 
241
            continue;
 
242
        case cx_escape:
 
243
            charstring_next(*cip, state, c, encrypted);
 
244
            ++cip;
 
245
            switch ((char1_extended_command) c) {
 
246
            default:
 
247
                c += CE_OFFSET;
 
248
                break;
 
249
            case ce1_div:
 
250
                csp[-1] = float2fixed((double)csp[-1] / (double)*csp);
 
251
                --csp;
 
252
                continue;
 
253
            case ce1_undoc15:   /* see gstype1.h */
 
254
                CLEAR;
 
255
                continue;
 
256
            case ce1_callothersubr:
 
257
                switch (fixed2int_var(*csp)) {
 
258
                case 0:
 
259
                    pcis->ignore_pops = 2;
 
260
                    break;      /* pass to caller */
 
261
                case 3:
 
262
                    pcis->ignore_pops = 1;
 
263
                    break;      /* pass to caller */
 
264
                case 14:
 
265
                    num_results = 1; goto blend;
 
266
                case 15:
 
267
                    num_results = 2; goto blend;
 
268
                case 16:
 
269
                    num_results = 3; goto blend;
 
270
                case 17:
 
271
                    num_results = 4; goto blend;
 
272
                case 18:
 
273
                    num_results = 6;
 
274
                blend:
 
275
                    code = gs_type1_blend(pcis, csp, num_results);
 
276
                    if (code < 0)
 
277
                        return code;
 
278
                    csp -= code;
 
279
                    continue;
 
280
                default:
 
281
                    break;      /* pass to caller */
 
282
                }
 
283
                break;
 
284
            case ce1_pop:
 
285
                if (pcis->ignore_pops != 0) {
 
286
                    pcis->ignore_pops--;
 
287
                    continue;
 
288
                }
 
289
                return_error(gs_error_rangecheck);
 
290
            }
 
291
            break;
 
292
        }
 
293
        break;
 
294
    }
 
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];
 
298
    return c;
 
299
}
 
300
 
 
301
/* ------ Output ------ */
 
302
 
 
303
/* Put 2 or 4 bytes on a stream (big-endian). */
 
304
static void
 
305
sputc2(stream *s, int i)
 
306
{
 
307
    sputc(s, (byte)(i >> 8));
 
308
    sputc(s, (byte)i);
 
309
}
 
310
static void
 
311
sputc4(stream *s, int i)
 
312
{
 
313
    sputc2(s, i >> 16);
 
314
    sputc2(s, i);
 
315
}
 
316
 
 
317
/* Put a Type 2 operator on a stream. */
 
318
static void
 
319
type2_put_op(stream *s, int op)
 
320
{
 
321
    if (op >= CE_OFFSET) {
 
322
        spputc(s, cx_escape);
 
323
        spputc(s, (byte)(op - CE_OFFSET));
 
324
    } else
 
325
        sputc(s, (byte)op);
 
326
}
 
327
 
 
328
/* Put a Type 2 number on a stream. */
 
329
static void
 
330
type2_put_int(stream *s, int i)
 
331
{
 
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);
 
340
        sputc2(s, i);
 
341
    } else {
 
342
        /*
 
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.)
 
346
         */
 
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);
 
352
    }
 
353
}
 
354
 
 
355
/* Put a fixed value on a stream. */
 
356
static void
 
357
type2_put_fixed(stream *s, fixed v)
 
358
{
 
359
    if (fixed_is_int(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. */
 
363
        spputc(s, cx_num4);
 
364
        sputc4(s, v << (16 - _fixed_shift));
 
365
    } else {
 
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);
 
369
    }
 
370
}
 
371
 
 
372
/* Put a stem hint table on a stream. */
 
373
static void
 
374
type2_put_stems(stream *s, int os_count, const cv_stem_hint_table *psht, int op)
 
375
{
 
376
    fixed prev = 0;
 
377
    int pushed = os_count;
 
378
    int i;
 
379
 
 
380
    for (i = 0; i < psht->count; ++i, pushed += 2) {
 
381
        fixed v0 = psht->data[i].v0;
 
382
        fixed v1 = psht->data[i].v1;
 
383
 
 
384
        if (pushed > ostack_size - 2) {
 
385
            type2_put_op(s, op);
 
386
            pushed = 0;
 
387
        }
 
388
        type2_put_fixed(s, v0 - prev);
 
389
        type2_put_fixed(s, v1 - v0);
 
390
        prev = v1;
 
391
    }
 
392
    type2_put_op(s, op);
 
393
}
 
394
 
 
395
/* Put out a hintmask command. */
 
396
static void
 
397
type2_put_hintmask(stream *s, const byte *mask, uint size)
 
398
{
 
399
    uint ignore;
 
400
 
 
401
    type2_put_op(s, c2_hintmask);
 
402
    sputs(s, mask, size, &ignore);
 
403
}
 
404
 
 
405
/* ------ Main program ------ */
 
406
 
 
407
 
 
408
/*
 
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) =>
 
413
 *        vhcurveto
 
414
 *      (hvcurveto vhcurveto)* (hvcurveto vrcurveto | hrcurveto) =>
 
415
 *        hvcurveto
 
416
 */
 
417
#define MAX_STACK ostack_size
 
418
int
 
419
psf_convert_type1_to_type2(stream *s, const gs_glyph_data_t *pgd,
 
420
                           gs_font_type1 *pfont)
 
421
{
 
422
    gs_type1_state cis;
 
423
    cv_stem_hint_table hstem_hints;     /* horizontal stem hints */
 
424
    cv_stem_hint_table vstem_hints;     /* vertical stem hints */
 
425
    bool first = true;
 
426
    bool need_moveto = true;
 
427
    bool replace_hints = false;
 
428
    bool hints_changed = false;
 
429
    enum {
 
430
        dotsection_in = 0,
 
431
        dotsection_out = -1
 
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];
 
435
    uint hintmask_size;
 
436
#define HINTS_CHANGED()\
 
437
  BEGIN\
 
438
    hints_changed = replace_hints;\
 
439
    if (hints_changed)\
 
440
        CHECK_OP();             /* see below */\
 
441
  END
 
442
#define CHECK_HINTS_CHANGED()\
 
443
  BEGIN\
 
444
    if (hints_changed) {\
 
445
        type2_put_hintmask(s, active_hints, hintmask_size);\
 
446
        hints_changed = false;\
 
447
    }\
 
448
  END
 
449
    /* 
 
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.
 
453
     */
 
454
    int depth;                  /* of operands on stack */
 
455
    int prev_op;                /* operator to write, -1 if none */
 
456
#define CLEAR_OP()\
 
457
  (depth = 0, prev_op = -1)
 
458
#define CHECK_OP()\
 
459
  BEGIN\
 
460
    if (prev_op >= 0) {\
 
461
        type2_put_op(s, prev_op);\
 
462
        CLEAR_OP();\
 
463
    }\
 
464
  END
 
465
    fixed mx0 = 0, my0 = 0; /* See ce1_setcurrentpoint. */
 
466
 
 
467
    /*
 
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.
 
470
     */
 
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);
 
474
    for (;;) {
 
475
        int c = type1_next(&cis);
 
476
        fixed *csp = &cis.ostack[cis.os_count - 1];
 
477
 
 
478
        switch (c) {
 
479
        default:
 
480
            if (c < 0)
 
481
                return c;
 
482
            type1_clear(&cis);
 
483
            continue;
 
484
        case c1_hsbw:
 
485
            gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
 
486
            goto clear;
 
487
        case cx_hstem:
 
488
            type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, NULL);
 
489
            goto clear;
 
490
        case cx_vstem:
 
491
            type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, NULL);
 
492
            goto clear;
 
493
        case CE_OFFSET + ce1_sbw:
 
494
            gs_type1_sbw(&cis, cis.ostack[0], cis.ostack[1],
 
495
                         cis.ostack[2], cis.ostack[3]);
 
496
            goto clear;
 
497
        case CE_OFFSET + ce1_vstem3:
 
498
            type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, NULL);
 
499
            goto clear;
 
500
        case CE_OFFSET + ce1_hstem3:
 
501
            type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, NULL);
 
502
        clear:
 
503
            type1_clear(&cis);
 
504
            continue;
 
505
        case ce1_callothersubr:
 
506
            if (*csp == int2fixed(3))
 
507
                replace_hints = true;
 
508
            cis.os_count -= 2;
 
509
            continue;
 
510
        case CE_OFFSET + ce1_dotsection:
 
511
            replace_hints = true;
 
512
            continue;
 
513
        case CE_OFFSET + ce1_seac:
 
514
        case cx_endchar:
 
515
            break;
 
516
        }
 
517
        break;
 
518
    }
 
519
    /*
 
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
 
522
     * active_hints.
 
523
     */
 
524
    {
 
525
        int i;
 
526
 
 
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;
 
531
    }
 
532
    if (replace_hints) {
 
533
        hintmask_size =
 
534
            (hstem_hints.count + vstem_hints.count + 7) / 8;
 
535
        memset(active_hints, 0, hintmask_size);
 
536
    } else 
 
537
        hintmask_size = 0;
 
538
 
 
539
    /* Do a second pass to write the result. */
 
540
    type1_next_init(&cis, pgd, pfont);
 
541
    CLEAR_OP();
 
542
    for (;;) {
 
543
        int c = type1_next(&cis);
 
544
        fixed *csp = &cis.ostack[cis.os_count - 1];
 
545
#define POP(n)\
 
546
  (csp -= (n), cis.os_count -= (n))
 
547
        int i;
 
548
        fixed mx, my;
 
549
 
 
550
        if (need_moveto && ((c >= cx_rlineto && c <= cx_rrcurveto) || 
 
551
            c == cx_vhcurveto || c == cx_hvcurveto))
 
552
        {
 
553
            mx = my = 0;
 
554
            need_moveto = false;
 
555
            CHECK_OP();
 
556
            if (first) {
 
557
                if (cis.os_count)
 
558
                    type2_put_fixed(s, *csp); /* width */
 
559
                mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
 
560
                first = false;
 
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.
 
565
                 */
 
566
                cis.os_count--;
 
567
                for (i = 0; i < cis.os_count; ++i)
 
568
                    cis.ostack[i] = cis.ostack[i+1];
 
569
            }
 
570
            CHECK_HINTS_CHANGED();
 
571
            if (mx == 0) {
 
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;
 
577
            } else {
 
578
                type2_put_fixed(s, mx);
 
579
                type2_put_fixed(s, my);
 
580
                depth = 2, prev_op = cx_rmoveto;
 
581
            }
 
582
        }
 
583
 
 
584
        switch (c) {
 
585
        default:
 
586
            if (c < 0)
 
587
                return c;
 
588
            if (c >= CE_OFFSET)
 
589
                return_error(gs_error_rangecheck);
 
590
            /* The Type 1 use of all other operators is the same in Type 2. */
 
591
        copy:
 
592
            CHECK_OP();
 
593
            CHECK_HINTS_CHANGED();
 
594
        put:
 
595
            for (i = 0; i < cis.os_count; ++i)
 
596
                type2_put_fixed(s, cis.ostack[i]);
 
597
            depth += cis.os_count;
 
598
            prev_op = c;
 
599
            type1_clear(&cis);
 
600
            continue;
 
601
        case cx_hstem:
 
602
            type1_stem1(&cis, &hstem_hints, csp - 1, cis.lsb.y, active_hints);
 
603
        hint:
 
604
            HINTS_CHANGED();
 
605
            type1_clear(&cis);
 
606
            continue;
 
607
        case cx_vstem:
 
608
            type1_stem1(&cis, &vstem_hints, csp - 1, cis.lsb.x, active_hints);
 
609
            goto hint;
 
610
        case CE_OFFSET + ce1_vstem3:
 
611
            type1_stem3(&cis, &vstem_hints, csp - 5, cis.lsb.x, active_hints);
 
612
            goto hint;
 
613
        case CE_OFFSET + ce1_hstem3:
 
614
            type1_stem3(&cis, &hstem_hints, csp - 5, cis.lsb.y, active_hints);
 
615
            goto hint;
 
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;
 
621
            } else {
 
622
                memcpy(active_hints, dot_save_hints, hintmask_size);
 
623
                dotsection_flag = dotsection_out;
 
624
            }
 
625
            HINTS_CHANGED();
 
626
            continue;
 
627
        case c1_closepath:
 
628
            need_moveto = true;
 
629
            continue;
 
630
        case CE_OFFSET + ce1_setcurrentpoint:
 
631
            if (first) {
 
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;
 
636
            }
 
637
            continue;
 
638
        case cx_vmoveto:
 
639
            mx = 0, my = *csp;
 
640
            POP(1); goto move;
 
641
        case cx_hmoveto:
 
642
            mx = *csp, my = 0;
 
643
            POP(1); goto move;
 
644
        case cx_rmoveto:
 
645
            mx = csp[-1], my = *csp;
 
646
            POP(2);
 
647
        move:
 
648
            need_moveto = false;
 
649
            CHECK_OP();
 
650
            if (first) {
 
651
                if (cis.os_count)
 
652
                    type2_put_fixed(s, *csp); /* width */
 
653
                mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
 
654
                first = false;
 
655
            }
 
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);
 
663
                cis.flex_count++;
 
664
                csp[-1] = mx, *csp = my;
 
665
                continue;
 
666
            }
 
667
            CHECK_HINTS_CHANGED();
 
668
            if (mx == 0) {
 
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;
 
674
            } else {
 
675
                type2_put_fixed(s, mx);
 
676
                type2_put_fixed(s, my);
 
677
                depth = 2, prev_op = cx_rmoveto;
 
678
            }
 
679
            type1_clear(&cis);
 
680
            continue;
 
681
        case c1_hsbw:
 
682
            gs_type1_sbw(&cis, cis.ostack[0], fixed_0, cis.ostack[1], fixed_0);
 
683
            /*
 
684
             * Leave the l.s.b. on the operand stack for the initial hint,
 
685
             * moveto, or endchar command.
 
686
             */
 
687
            cis.ostack[0] = cis.ostack[1];
 
688
        sbw:
 
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
 
693
               Use the latter here.
 
694
             */
 
695
            if (cis.ostack[0] == default_defaultWidthX)
 
696
                cis.os_count = 0;
 
697
            else {
 
698
                cis.ostack[0] -= default_defaultWidthX;
 
699
                cis.os_count = 1;
 
700
            }
 
701
            if (hstem_hints.count) {
 
702
                if (cis.os_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));
 
706
                cis.os_count = 0;
 
707
            }
 
708
            if (vstem_hints.count) {
 
709
                if (cis.os_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));
 
713
                cis.os_count = 0;
 
714
            }
 
715
            continue;
 
716
        case CE_OFFSET + ce1_seac:
 
717
            /*
 
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.
 
724
             */
 
725
            csp[-3] += cis.lsb.x - csp[-4];
 
726
            memmove(csp - 4, csp - 3, sizeof(*csp) * 4);
 
727
            POP(1);
 
728
            /* (falls through) */
 
729
        case cx_endchar:
 
730
            CHECK_OP();
 
731
            for (i = 0; i < cis.os_count; ++i)
 
732
                type2_put_fixed(s, cis.ostack[i]);
 
733
            type2_put_op(s, cx_endchar);
 
734
            return 0;
 
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];
 
739
            goto sbw;
 
740
        case ce1_callothersubr:
 
741
            CHECK_OP();
 
742
            switch (fixed2int_var(*csp)) {
 
743
            default:
 
744
                return_error(gs_error_rangecheck);
 
745
            case 0:
 
746
                /*
 
747
                 * The operand stack contains: delta to reference point,
 
748
                 * 6 deltas for the two curves, fd, final point, 3, 0.
 
749
                 */
 
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;
 
753
                /*
 
754
                 * We could optimize by using [h]flex[1],
 
755
                 * but it isn't worth the trouble.
 
756
                 */
 
757
                c = CE_OFFSET + ce2_flex;
 
758
                cis.flex_count = flex_max;      /* not inside flex */
 
759
                cis.ignore_pops = 2;
 
760
                goto copy;
 
761
            case 1:
 
762
                cis.flex_count = 0;
 
763
                cis.os_count -= 2;
 
764
                continue;
 
765
            /*case 2:*/         /* detected in *moveto */
 
766
            case 3:
 
767
                memset(active_hints, 0, hintmask_size);
 
768
                HINTS_CHANGED();
 
769
                cis.ignore_pops = 1;
 
770
                cis.os_count -= 2;
 
771
                continue;
 
772
            case 12:
 
773
            case 13:
 
774
                /* Counter control is not implemented. */
 
775
                cis.os_count -= 2 + fixed2int(csp[-1]);
 
776
                continue;
 
777
            }
 
778
            /*
 
779
             * The remaining cases are strictly for optimization.
 
780
             */
 
781
        case cx_rlineto:
 
782
            if (depth > MAX_STACK - 2)
 
783
                goto copy;
 
784
            switch (prev_op) {
 
785
            case cx_rlineto:    /* rlineto+ => rlineto */
 
786
                goto put;
 
787
            case cx_rrcurveto:  /* rrcurveto+ rlineto => rcurveline */
 
788
                c = c2_rcurveline;
 
789
                goto put;
 
790
            default:
 
791
                goto copy;
 
792
            }
 
793
        case cx_hlineto:  /* hlineto (vlineto hlineto)* [vlineto] => hlineto */
 
794
            if (depth > MAX_STACK - 1 ||
 
795
                prev_op != (depth & 1 ? cx_vlineto : cx_hlineto))
 
796
                goto copy;
 
797
            c = prev_op;
 
798
            goto put;
 
799
        case cx_vlineto:  /* vlineto (hlineto vlineto)* [hlineto] => vlineto */
 
800
            if (depth > MAX_STACK - 1 ||
 
801
                prev_op != (depth & 1 ? cx_hlineto : cx_vlineto))
 
802
                goto copy;
 
803
            c = prev_op;
 
804
            goto put;
 
805
        case cx_hvcurveto: /* hvcurveto (vhcurveto hvcurveto)* => hvcurveto */
 
806
                                /* (vhcurveto hvcurveto)+ => vhcurveto  */
 
807
            /*
 
808
             * We have to check (depth & 1) because the last curve might
 
809
             * have 5 parameters rather than 4 (see rrcurveto below).
 
810
             */
 
811
            if ((depth & 1) || depth > MAX_STACK - 4 ||
 
812
                prev_op != (depth & 4 ? cx_vhcurveto : cx_hvcurveto))
 
813
                goto copy;
 
814
            c = prev_op;
 
815
            goto put;
 
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))
 
821
                goto copy;
 
822
            c = prev_op;
 
823
            goto put;
 
824
        case cx_rrcurveto:
 
825
            if (depth == 0) {
 
826
                if (csp[-1] == 0) {
 
827
                    /* A|0 B C D 0 F rrcurveto => [A] B C D F vvcurveto */
 
828
                    c = c2_vvcurveto;
 
829
                    csp[-1] = csp[0];
 
830
                    if (csp[-5] == 0) {
 
831
                        memmove(csp - 5, csp - 4, sizeof(*csp) * 4);
 
832
                        POP(2);
 
833
                    } else
 
834
                        POP(1);
 
835
                } else if (*csp == 0) {
 
836
                    /* A B|0 C D E 0 rrcurveto => [B] A C D E hhcurveto */
 
837
                    c = c2_hhcurveto;
 
838
                    if (csp[-4] == 0) {
 
839
                        memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
 
840
                        POP(2);
 
841
                    } else {
 
842
                        *csp = csp[-5], csp[-5] = csp[-4], csp[-4] = *csp;
 
843
                        POP(1);
 
844
                    }
 
845
                }
 
846
                /*
 
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.
 
852
                 */
 
853
                goto copy;
 
854
            }
 
855
            if (depth > MAX_STACK - 6)
 
856
                goto copy;
 
857
            switch (prev_op) {
 
858
            case c2_hhcurveto:  /* hrcurveto (x1 0 x2 y2 x3 0 rrcurveto)* => */
 
859
                                /* hhcurveto */
 
860
                if (csp[-4] == 0 && *csp == 0) {
 
861
                    memmove(csp - 4, csp - 3, sizeof(*csp) * 3);
 
862
                    c = prev_op;
 
863
                    POP(2);
 
864
                    goto put;
 
865
                }
 
866
                goto copy;
 
867
            case c2_vvcurveto:  /* rvcurveto (0 y1 x2 y2 0 y3 rrcurveto)* => */
 
868
                                /* vvcurveto */
 
869
                if (csp[-5] == 0 && csp[-1] == 0) {
 
870
                    memmove(csp - 5, csp - 4, sizeof(*csp) * 3);
 
871
                    csp[-2] = *csp;
 
872
                    c = prev_op;
 
873
                    POP(2);
 
874
                    goto put;
 
875
                }
 
876
                goto copy;
 
877
            case cx_hvcurveto:
 
878
                if (depth & 1)
 
879
                    goto copy;
 
880
                if (!(depth & 4))
 
881
                    goto hrc;
 
882
            vrc:  /* (vhcurveto hvcurveto)+ vrcurveto => vhcurveto */
 
883
                /* hvcurveto (vhcurveto hvcurveto)* vrcurveto => hvcurveto */
 
884
                if (csp[-5] != 0)
 
885
                    goto copy;
 
886
                memmove(csp - 5, csp - 4, sizeof(*csp) * 5);
 
887
                c = prev_op;
 
888
                POP(1);
 
889
                goto put;
 
890
            case cx_vhcurveto:
 
891
                if (depth & 1)
 
892
                    goto copy;
 
893
                if (!(depth & 4))
 
894
                    goto vrc;
 
895
            hrc:  /* (hvcurveto vhcurveto)+ hrcurveto => hvcurveto */
 
896
                /* vhcurveto (hvcurveto vhcurveto)* hrcurveto => vhcurveto */
 
897
                if (csp[-4] != 0)
 
898
                    goto copy;
 
899
                /* A 0 C D E F => A C D F E */
 
900
                memmove(csp - 4, csp - 3, sizeof(*csp) * 2);
 
901
                csp[-2] = *csp;
 
902
                c = prev_op;
 
903
                POP(1);
 
904
                goto put;
 
905
            case cx_rlineto:    /* rlineto+ rrcurveto => rlinecurve */
 
906
                c = c2_rlinecurve;
 
907
                goto put;
 
908
            case cx_rrcurveto:  /* rrcurveto+ => rrcurveto */
 
909
                goto put;
 
910
            default:
 
911
                goto copy;
 
912
            }
 
913
        }
 
914
    }
 
915
}