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

« back to all changes in this revision

Viewing changes to base/gstype2.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: gstype2.c 8250 2007-09-25 13:31:24Z giles $ */
 
15
/* Adobe Type 2 charstring interpreter */
 
16
#include "math_.h"
 
17
#include "memory_.h"
 
18
#include "gx.h"
 
19
#include "gserrors.h"
 
20
#include "gsstruct.h"
 
21
#include "gxarith.h"
 
22
#include "gxfixed.h"
 
23
#include "gxmatrix.h"
 
24
#include "gxcoord.h"
 
25
#include "gxistate.h"
 
26
#include "gxpath.h"
 
27
#include "gxfont.h"
 
28
#include "gxfont1.h"
 
29
#include "gxtype1.h"
 
30
#include "gxhintn.h"
 
31
 
 
32
/* NOTE: The following are not yet implemented:
 
33
 *      Registry items other than 0
 
34
 *      Counter masks (but they are parsed correctly)
 
35
 *      'random' operator
 
36
 */
 
37
 
 
38
/* ------ Internal routines ------ */
 
39
 
 
40
/*
 
41
 * Set the character width.  This is provided as an optional extra operand
 
42
 * on the stack for the first operator.  After setting the width, we remove
 
43
 * the extra operand, and back up the interpreter pointer so we will
 
44
 * re-execute the operator when control re-enters the interpreter.
 
45
 */
 
46
#define check_first_operator(explicit_width)\
 
47
  BEGIN\
 
48
    if ( pcis->init_done < 0 )\
 
49
      { ipsp->ip = cip, ipsp->dstate = state;\
 
50
        return type2_sbw(pcis, csp, cstack, ipsp, explicit_width);\
 
51
      }\
 
52
  END
 
53
static int
 
54
type2_sbw(gs_type1_state * pcis, cs_ptr csp, cs_ptr cstack, ip_state_t * ipsp,
 
55
          bool explicit_width)
 
56
{
 
57
    t1_hinter *h = &pcis->h;
 
58
    fixed sbx = fixed_0, sby = fixed_0, wx, wy = fixed_0;
 
59
    int code;
 
60
 
 
61
    if (explicit_width) {
 
62
        wx = cstack[0] + pcis->pfont->data.nominalWidthX;
 
63
        memmove(cstack, cstack + 1, (csp - cstack) * sizeof(*cstack));
 
64
        --csp;
 
65
    } else
 
66
        wx = pcis->pfont->data.defaultWidthX;
 
67
    if (pcis->seac_accent < 0) {
 
68
        if (pcis->sb_set) {
 
69
            pcis->origin_offset.x = pcis->lsb.x - sbx;
 
70
            pcis->origin_offset.y = pcis->lsb.y - sby;
 
71
            sbx = pcis->lsb.x;
 
72
            sby = pcis->lsb.y;
 
73
        }
 
74
        if (pcis->width_set) {
 
75
            wx = pcis->width.x;
 
76
            wy = pcis->width.y;
 
77
        }
 
78
    }
 
79
    code = t1_hinter__sbw(h, sbx, sby, wx, wy);
 
80
    if (code < 0)
 
81
        return code;
 
82
    gs_type1_sbw(pcis, fixed_0, fixed_0, wx, fixed_0);
 
83
    /* Back up the interpretation pointer. */
 
84
    ipsp->ip--;
 
85
    decrypt_skip_previous(*ipsp->ip, ipsp->dstate);
 
86
    /* Save the interpreter state. */
 
87
    pcis->os_count = csp + 1 - cstack;
 
88
    pcis->ips_count = ipsp - &pcis->ipstack[0] + 1;
 
89
    memcpy(pcis->ostack, cstack, pcis->os_count * sizeof(cstack[0]));
 
90
    if (pcis->init_done < 0) {  /* Finish init when we return. */
 
91
        pcis->init_done = 0;
 
92
    }
 
93
    return type1_result_sbw;
 
94
}
 
95
static int
 
96
type2_vstem(gs_type1_state * pcis, cs_ptr csp, cs_ptr cstack)
 
97
{
 
98
    fixed x = 0;
 
99
    cs_ptr ap;
 
100
    t1_hinter *h = &pcis->h;
 
101
    int code;
 
102
 
 
103
    for (ap = cstack; ap + 1 <= csp; x += ap[1], ap += 2) {
 
104
        code = t1_hinter__vstem(h, x += ap[0], ap[1]);
 
105
        if (code < 0)
 
106
            return code;
 
107
    }
 
108
    pcis->num_hints += (csp + 1 - cstack) >> 1;
 
109
    return 0;
 
110
}
 
111
 
 
112
/* ------ Main interpreter ------ */
 
113
 
 
114
/*
 
115
 * Continue interpreting a Type 2 charstring.  If str != 0, it is taken as
 
116
 * the byte string to interpret.  Return 0 on successful completion, <0 on
 
117
 * error, or >0 when client intervention is required (or allowed).  The int*
 
118
 * argument is only for compatibility with the Type 1 charstring interpreter.
 
119
 */
 
120
int
 
121
gs_type2_interpret(gs_type1_state * pcis, const gs_glyph_data_t *pgd,
 
122
                   int *ignore_pindex)
 
123
{
 
124
    gs_font_type1 *pfont = pcis->pfont;
 
125
    gs_type1_data *pdata = &pfont->data;
 
126
    t1_hinter *h = &pcis->h;
 
127
    bool encrypted = pdata->lenIV >= 0;
 
128
    fixed cstack[ostack_size];
 
129
    cs_ptr csp;
 
130
#define clear CLEAR_CSTACK(cstack, csp)
 
131
    ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1];
 
132
    register const byte *cip;
 
133
    register crypt_state state;
 
134
    register int c;
 
135
    cs_ptr ap;
 
136
    bool vertical;
 
137
    int code = 0;
 
138
 
 
139
/****** FAKE THE REGISTRY ******/
 
140
    struct {
 
141
        float *values;
 
142
        uint size;
 
143
    } Registry[1];
 
144
 
 
145
    Registry[0].values = pcis->pfont->data.WeightVector.values;
 
146
 
 
147
    switch (pcis->init_done) {
 
148
        case -1:
 
149
            t1_hinter__init(h, pcis->path);
 
150
            break;
 
151
        case 0:
 
152
            gs_type1_finish_init(pcis); /* sets origin */
 
153
            code = t1_hinter__set_mapping(h, &pcis->pis->ctm,
 
154
                            &pfont->FontMatrix, &pfont->base->FontMatrix,
 
155
                            pcis->scale.x.log2_unit, pcis->scale.x.log2_unit,
 
156
                            pcis->scale.x.log2_unit - pcis->log2_subpixels.x,
 
157
                            pcis->scale.y.log2_unit - pcis->log2_subpixels.y,
 
158
                            pcis->origin.x, pcis->origin.y, 
 
159
                            gs_currentaligntopixels(pfont->dir));
 
160
            if (code < 0)
 
161
                return code;
 
162
            code = t1_hinter__set_font_data(h, 2, pdata, pcis->no_grid_fitting,
 
163
                            pcis->pfont->is_resource);
 
164
            if (code < 0)
 
165
                return code;
 
166
            break;
 
167
        default /*case 1 */ :
 
168
            break;
 
169
    }
 
170
    INIT_CSTACK(cstack, csp, pcis);
 
171
 
 
172
    if (pgd == 0)
 
173
        goto cont;
 
174
    ipsp->cs_data = *pgd;
 
175
    cip = pgd->bits.data;
 
176
  call:state = crypt_charstring_seed;
 
177
    if (encrypted) {
 
178
        int skip = pdata->lenIV;
 
179
 
 
180
        /* Skip initial random bytes */
 
181
        for (; skip > 0; ++cip, --skip)
 
182
            decrypt_skip_next(*cip, state);
 
183
    }
 
184
    goto top;
 
185
  cont:cip = ipsp->ip;
 
186
    state = ipsp->dstate;
 
187
  top:for (;;) {
 
188
        uint c0 = *cip++;
 
189
 
 
190
        charstring_next(c0, state, c, encrypted);
 
191
        if (c >= c_num1) {
 
192
            /* This is a number, decode it and push it on the stack. */
 
193
 
 
194
            if (c < c_pos2_0) { /* 1-byte number */
 
195
                decode_push_num1(csp, cstack, c);
 
196
            } else if (c < cx_num4) {   /* 2-byte number */
 
197
                decode_push_num2(csp, cstack, c, cip, state, encrypted);
 
198
            } else if (c == cx_num4) {  /* 4-byte number */
 
199
                long lw;
 
200
 
 
201
                decode_num4(lw, cip, state, encrypted);
 
202
                /* 32-bit numbers are 16:16. */
 
203
                CS_CHECK_PUSH(csp, cstack);
 
204
                *++csp = arith_rshift(lw, 16 - _fixed_shift);
 
205
            } else              /* not possible */
 
206
                return_error(gs_error_invalidfont);
 
207
          pushed:if_debug3('1', "[1]%d: (%d) %f\n",
 
208
                      (int)(csp - cstack), c, fixed2float(*csp));
 
209
            continue;
 
210
        }
 
211
#ifdef DEBUG
 
212
        if (gs_debug['1']) {
 
213
            static const char *const c2names[] =
 
214
            {char2_command_names};
 
215
 
 
216
            if (c2names[c] == 0)
 
217
                dlprintf2("[1]0x%lx: %02x??\n", (ulong) (cip - 1), c);
 
218
            else
 
219
                dlprintf3("[1]0x%lx: %02x %s\n", (ulong) (cip - 1), c,
 
220
                          c2names[c]);
 
221
        }
 
222
#endif
 
223
        switch ((char_command) c) {
 
224
#define cnext clear; goto top
 
225
 
 
226
                /* Commands with identical functions in Type 1 and Type 2, */
 
227
                /* except for 'escape'. */
 
228
 
 
229
            case c_undef0:
 
230
            case c_undef2:
 
231
            case c_undef17:
 
232
                return_error(gs_error_invalidfont);
 
233
            case c_callsubr:
 
234
                c = fixed2int_var(*csp) + pdata->subroutineNumberBias;
 
235
                code = pdata->procs.subr_data
 
236
                    (pfont, c, false, &ipsp[1].cs_data);
 
237
              subr:if (code < 0) {
 
238
                    /* Calling a Subr with an out-of-range index is clearly a error:
 
239
                     * the Adobe documentation says the results of doing this are
 
240
                     * undefined. However, we have seen a PDF file produced by Adobe
 
241
                     * PDF Library 4.16 that included a Type 2 font that called an
 
242
                     * out-of-range Subr, and Acrobat Reader did not signal an error.
 
243
                     * Therefore, we ignore such calls.
 
244
                     */
 
245
                    cip++;
 
246
                    goto top;
 
247
                }
 
248
                --csp;
 
249
                ipsp->ip = cip, ipsp->dstate = state;
 
250
                ++ipsp;
 
251
                cip = ipsp->cs_data.bits.data;
 
252
                goto call;
 
253
            case c_return:
 
254
                gs_glyph_data_free(&ipsp->cs_data, "gs_type2_interpret");
 
255
                --ipsp;
 
256
                goto cont;
 
257
            case c_undoc15:
 
258
                /* See gstype1.h for information on this opcode. */
 
259
                cnext;
 
260
 
 
261
                /* Commands with similar but not identical functions */
 
262
                /* in Type 1 and Type 2 charstrings. */
 
263
 
 
264
            case cx_hstem:
 
265
                goto hstem;
 
266
            case cx_vstem:
 
267
                goto vstem;
 
268
            case cx_vmoveto:
 
269
                check_first_operator(csp > cstack);
 
270
                code = t1_hinter__rmoveto(h, 0, *csp);
 
271
              move:
 
272
              cc:
 
273
                if (code < 0)
 
274
                    return code;
 
275
                goto pp;
 
276
            case cx_rlineto:
 
277
                for (ap = cstack; ap + 1 <= csp; ap += 2) {
 
278
                    code = t1_hinter__rlineto(h, ap[0], ap[1]);
 
279
                    if (code < 0)
 
280
                        return code;
 
281
                }
 
282
              pp:
 
283
                cnext;
 
284
            case cx_hlineto:
 
285
                vertical = false;
 
286
                goto hvl;
 
287
            case cx_vlineto:
 
288
                vertical = true;
 
289
              hvl:for (ap = cstack; ap <= csp; vertical = !vertical, ++ap) {
 
290
                    if (vertical) {
 
291
                        code = t1_hinter__rlineto(h, 0, ap[0]);
 
292
                    } else {
 
293
                        code = t1_hinter__rlineto(h, ap[0], 0);
 
294
                    }
 
295
                    if (code < 0)
 
296
                        return code;
 
297
                }
 
298
                goto pp;
 
299
            case cx_rrcurveto:
 
300
                for (ap = cstack; ap + 5 <= csp; ap += 6) {
 
301
                    code = t1_hinter__rcurveto(h, ap[0], ap[1], ap[2],
 
302
                                            ap[3], ap[4], ap[5]);
 
303
                    if (code < 0)
 
304
                        return code;
 
305
                }
 
306
                goto pp;
 
307
            case cx_endchar:
 
308
                /*
 
309
                 * It is a feature of Type 2 CharStrings that if endchar is
 
310
                 * invoked with 4 or 5 operands, it is equivalent to the
 
311
                 * Type 1 seac operator. In this case, the asb operand of
 
312
                 * seac is missing: we assume it is the same as the
 
313
                 * l.s.b. of the accented character.  This feature was
 
314
                 * undocumented until the 16 March 2000 version of the Type
 
315
                 * 2 Charstring Format specification, but, thankfully, is
 
316
                 * described in that revision.
 
317
                 */
 
318
                if (csp >= cstack + 3) {
 
319
                    check_first_operator(csp > cstack + 3);
 
320
                    code = gs_type1_seac(pcis, cstack, 0, ipsp);
 
321
                    if (code < 0)
 
322
                        return code;
 
323
                    clear;
 
324
                    cip = ipsp->cs_data.bits.data;
 
325
                    goto call;
 
326
                }
 
327
                /*
 
328
                 * This might be the only operator in the charstring.
 
329
                 * In this case, there might be a width on the stack.
 
330
                 */
 
331
                check_first_operator(csp >= cstack);
 
332
                if (pcis->seac_accent < 0) {
 
333
                    code = t1_hinter__endglyph(h);
 
334
                    if (code < 0)
 
335
                        return code;
 
336
                    code = gx_setcurrentpoint_from_path(pcis->pis, pcis->path);
 
337
                    if (code < 0)
 
338
                        return code;
 
339
                } else {
 
340
                    t1_hinter__setcurrentpoint(h, pcis->save_adxy.x + pcis->origin_offset.x, 
 
341
                                                  pcis->save_adxy.y + pcis->origin_offset.y);
 
342
                    code = t1_hinter__end_subglyph(h);
 
343
                    if (code < 0)
 
344
                        return code;
 
345
                }
 
346
                code = gs_type1_endchar(pcis);
 
347
                if (code == 1) {
 
348
                    /*
 
349
                     * Reset the total hint count so that hintmask will
 
350
                     * parse its following data correctly.
 
351
                     * (gs_type1_endchar already reset the actual hint
 
352
                     * tables.)
 
353
                     */
 
354
                    pcis->num_hints = 0;
 
355
                    /* do accent of seac */
 
356
                    ipsp = &pcis->ipstack[pcis->ips_count - 1];
 
357
                    cip = ipsp->cs_data.bits.data;
 
358
                    goto call;
 
359
                }
 
360
                return code;
 
361
            case cx_rmoveto:
 
362
                /* See vmoveto above re closing the subpath. */
 
363
                check_first_operator(!((csp - cstack) & 1));
 
364
                if (csp > cstack + 1) {
 
365
                  /* Some Type 2 charstrings omit the vstemhm operator before rmoveto, 
 
366
                     even though this is only allowed before hintmask and cntrmask.
 
367
                     Thanks to Felix Pahl.
 
368
                   */
 
369
                  type2_vstem(pcis, csp - 2, cstack);
 
370
                  cstack [0] = csp [-1];
 
371
                  cstack [1] = csp [ 0];
 
372
                  csp = cstack + 1;
 
373
                }
 
374
                code = t1_hinter__rmoveto(h, csp[-1], *csp);
 
375
                goto move;
 
376
            case cx_hmoveto:
 
377
                /* See vmoveto above re closing the subpath. */
 
378
                check_first_operator(csp > cstack);
 
379
                code = t1_hinter__rmoveto(h, *csp, 0);
 
380
                goto move;
 
381
            case cx_vhcurveto:
 
382
                vertical = true;
 
383
                goto hvc;
 
384
            case cx_hvcurveto:
 
385
                vertical = false;
 
386
              hvc:for (ap = cstack; ap + 3 <= csp; vertical = !vertical, ap += 4) {
 
387
                    gs_fixed_point pt[2] = {{0, 0}, {0, 0}};
 
388
                    if (vertical) {
 
389
                        pt[0].y = ap[0];
 
390
                        pt[1].x = ap[3];
 
391
                        if (ap + 4 == csp)
 
392
                            pt[1].y = ap[4];
 
393
                    } else {
 
394
                        pt[0].x = ap[0];
 
395
                        if (ap + 4 == csp)
 
396
                            pt[1].x = ap[4];
 
397
                        pt[1].y = ap[3];
 
398
                    }
 
399
                    code = t1_hinter__rcurveto(h, pt[0].x, pt[0].y, ap[1], ap[2], pt[1].x, pt[1].y);
 
400
                    if (code < 0)
 
401
                        return code;
 
402
                }
 
403
                goto pp;
 
404
 
 
405
                        /***********************
 
406
                         * New Type 2 commands *
 
407
                         ***********************/
 
408
 
 
409
            case c2_blend:
 
410
                {
 
411
                    int n = fixed2int_var(*csp);
 
412
                    int num_values = csp - cstack;
 
413
                    gs_font_type1 *pfont = pcis->pfont;
 
414
                    int k = pfont->data.WeightVector.count;
 
415
                    int i, j;
 
416
                    cs_ptr base, deltas;
 
417
 
 
418
                    base = csp - 1 - num_values;
 
419
                    deltas = base + n - 1;
 
420
                    for (j = 0; j < n; j++, base++, deltas += k - 1)
 
421
                        for (i = 1; i < k; i++)
 
422
                            *base += (fixed)(deltas[i] * 
 
423
                                pfont->data.WeightVector.values[i]);
 
424
                }
 
425
                cnext;
 
426
            case c2_hstemhm:
 
427
              hstem:check_first_operator(!((csp - cstack) & 1));
 
428
                {
 
429
                    fixed x = 0;
 
430
 
 
431
                    for (ap = cstack; ap + 1 <= csp; x += ap[1], ap += 2) {
 
432
                            code = t1_hinter__hstem(h, x += ap[0], ap[1]);
 
433
                            if (code < 0)
 
434
                                return code;
 
435
                    }
 
436
                }
 
437
                pcis->num_hints += (csp + 1 - cstack) >> 1;
 
438
                cnext;
 
439
            case c2_hintmask:
 
440
                /*
 
441
                 * A hintmask at the beginning of the CharString is
 
442
                 * equivalent to vstemhm + hintmask.  For simplicity, we use
 
443
                 * this interpretation everywhere.
 
444
                 */
 
445
            case c2_cntrmask:
 
446
                check_first_operator(!((csp - cstack) & 1));
 
447
                type2_vstem(pcis, csp, cstack);
 
448
                /*
 
449
                 * We should clear the stack here only if this is the
 
450
                 * initial mask operator that includes the implicit
 
451
                 * vstemhm, but currently this is too much trouble to
 
452
                 * detect.
 
453
                 */
 
454
                clear;
 
455
                {
 
456
                    byte mask[max_total_stem_hints / 8];
 
457
                    int i;
 
458
 
 
459
                    for (i = 0; i < pcis->num_hints; ++cip, i += 8) {
 
460
                        charstring_next(*cip, state, mask[i >> 3], encrypted);
 
461
                        if_debug1('1', " 0x%02x", mask[i >> 3]);
 
462
                    }
 
463
                    if_debug0('1', "\n");
 
464
                    ipsp->ip = cip;
 
465
                    ipsp->dstate = state;
 
466
                    if (c == c2_cntrmask) {
 
467
                        /****** NYI ******/
 
468
                    } else {    /* hintmask or equivalent */
 
469
                        if_debug0('1', "[1]hstem hints:\n");
 
470
                        if_debug0('1', "[1]vstem hints:\n");
 
471
                        code = t1_hinter__hint_mask(h, mask);
 
472
                        if (code < 0)
 
473
                            return code;
 
474
                    }
 
475
                }
 
476
                break;
 
477
            case c2_vstemhm:
 
478
              vstem:check_first_operator(!((csp - cstack) & 1));
 
479
                type2_vstem(pcis, csp, cstack);
 
480
                cnext;
 
481
            case c2_rcurveline:
 
482
                for (ap = cstack; ap + 5 <= csp; ap += 6) {
 
483
                    code = t1_hinter__rcurveto(h, ap[0], ap[1], ap[2], ap[3],
 
484
                                            ap[4], ap[5]);
 
485
                    if (code < 0)
 
486
                        return code;
 
487
                }
 
488
                code = t1_hinter__rlineto(h, ap[0], ap[1]);
 
489
                goto cc;
 
490
            case c2_rlinecurve:
 
491
                for (ap = cstack; ap + 7 <= csp; ap += 2) {
 
492
                    code = t1_hinter__rlineto(h, ap[0], ap[1]);
 
493
                    if (code < 0)
 
494
                        return code;
 
495
                }
 
496
                code = t1_hinter__rcurveto(h, ap[0], ap[1], ap[2], ap[3],
 
497
                                        ap[4], ap[5]);
 
498
                goto cc;
 
499
            case c2_vvcurveto:
 
500
                ap = cstack;
 
501
                {
 
502
                    int n = csp + 1 - cstack;
 
503
                    fixed dxa = (n & 1 ? *ap++ : 0);
 
504
 
 
505
                    for (; ap + 3 <= csp; ap += 4) {
 
506
                        code = t1_hinter__rcurveto(h, dxa, ap[0], ap[1], ap[2],
 
507
                                                fixed_0, ap[3]);
 
508
                        if (code < 0)
 
509
                            return code;
 
510
                        dxa = 0;
 
511
                    }
 
512
                }
 
513
                goto pp;
 
514
            case c2_hhcurveto:
 
515
                ap = cstack;
 
516
                {
 
517
                    int n = csp + 1 - cstack;
 
518
                    fixed dya = (n & 1 ? *ap++ : 0);
 
519
 
 
520
                    for (; ap + 3 <= csp; ap += 4) {
 
521
                        code = t1_hinter__rcurveto(h, ap[0], dya, ap[1], ap[2],
 
522
                                                ap[3], fixed_0);
 
523
                        if (code < 0)
 
524
                            return code;
 
525
                        dya = 0;
 
526
                    }
 
527
                }
 
528
                goto pp;
 
529
            case c2_shortint:
 
530
                {
 
531
                    int c1, c2;
 
532
 
 
533
                    charstring_next(*cip, state, c1, encrypted);
 
534
                    ++cip;
 
535
                    charstring_next(*cip, state, c2, encrypted);
 
536
                    ++cip;
 
537
                    CS_CHECK_PUSH(csp, cstack);
 
538
                    *++csp = int2fixed((((c1 ^ 0x80) - 0x80) << 8) + c2);
 
539
                }
 
540
                goto pushed;
 
541
            case c2_callgsubr:
 
542
                c = fixed2int_var(*csp) + pdata->gsubrNumberBias;
 
543
                code = pdata->procs.subr_data
 
544
                    (pfont, c, true, &ipsp[1].cs_data);
 
545
                goto subr;
 
546
            case cx_escape:
 
547
                charstring_next(*cip, state, c, encrypted);
 
548
                ++cip;
 
549
#ifdef DEBUG
 
550
                if (gs_debug['1'] && c < char2_extended_command_count) {
 
551
                    static const char *const ce2names[] =
 
552
                    {char2_extended_command_names};
 
553
 
 
554
                    if (ce2names[c] == 0)
 
555
                        dlprintf2("[1]0x%lx: %02x??\n", (ulong) (cip - 1), c);
 
556
                    else
 
557
                        dlprintf3("[1]0x%lx: %02x %s\n", (ulong) (cip - 1), c,
 
558
                                  ce2names[c]);
 
559
                }
 
560
#endif
 
561
                switch ((char2_extended_command) c) {
 
562
                    case ce2_and:
 
563
                        csp[-1] = ((csp[-1] != 0) & (*csp != 0) ? fixed_1 : 0);
 
564
                        --csp;
 
565
                        break;
 
566
                    case ce2_or:
 
567
                        csp[-1] = (csp[-1] | *csp ? fixed_1 : 0);
 
568
                        --csp;
 
569
                        break;
 
570
                    case ce2_not:
 
571
                        *csp = (*csp ? 0 : fixed_1);
 
572
                        break;
 
573
                    case ce2_store:
 
574
                        {
 
575
                            int i, n = fixed2int_var(*csp);
 
576
                            float *to = Registry[fixed2int_var(csp[-3])].values +
 
577
                            fixed2int_var(csp[-2]);
 
578
                            const fixed *from =
 
579
                            pcis->transient_array + fixed2int_var(csp[-1]);
 
580
 
 
581
                            for (i = 0; i < n; ++i)
 
582
                                to[i] = fixed2float(from[i]);
 
583
                        }
 
584
                        csp -= 4;
 
585
                        break;
 
586
                    case ce2_abs:
 
587
                        if (*csp < 0)
 
588
                            *csp = -*csp;
 
589
                        break;
 
590
                    case ce2_add:
 
591
                        csp[-1] += *csp;
 
592
                        --csp;
 
593
                        break;
 
594
                    case ce2_sub:
 
595
                        csp[-1] -= *csp;
 
596
                        --csp;
 
597
                        break;
 
598
                    case ce2_div:
 
599
                        csp[-1] = float2fixed((double)csp[-1] / *csp);
 
600
                        --csp;
 
601
                        break;
 
602
                    case ce2_load:
 
603
                        /* The specification says there is no j (starting index */
 
604
                        /* in registry array) argument.... */
 
605
                        {
 
606
                            int i, n = fixed2int_var(*csp);
 
607
                            const float *from = Registry[fixed2int_var(csp[-2])].values;
 
608
                            fixed *to =
 
609
                            pcis->transient_array + fixed2int_var(csp[-1]);
 
610
 
 
611
                            for (i = 0; i < n; ++i)
 
612
                                to[i] = float2fixed(from[i]);
 
613
                        }
 
614
                        csp -= 3;
 
615
                        break;
 
616
                    case ce2_neg:
 
617
                        *csp = -*csp;
 
618
                        break;
 
619
                    case ce2_eq:
 
620
                        csp[-1] = (csp[-1] == *csp ? fixed_1 : 0);
 
621
                        --csp;
 
622
                        break;
 
623
                    case ce2_drop:
 
624
                        --csp;
 
625
                        break;
 
626
                    case ce2_put:
 
627
                        pcis->transient_array[fixed2int_var(*csp)] = csp[-1];
 
628
                        csp -= 2;
 
629
                        break;
 
630
                    case ce2_get:
 
631
                        *csp = pcis->transient_array[fixed2int_var(*csp)];
 
632
                        break;
 
633
                    case ce2_ifelse:
 
634
                        if (csp[-1] > *csp)
 
635
                            csp[-3] = csp[-2];
 
636
                        csp -= 3;
 
637
                        break;
 
638
                    case ce2_random:
 
639
                        CS_CHECK_PUSH(csp, cstack);
 
640
                        ++csp;
 
641
                        /****** NYI ******/
 
642
                        break;
 
643
                    case ce2_mul:
 
644
                        {
 
645
                            double prod = fixed2float(csp[-1]) * *csp;
 
646
 
 
647
                            csp[-1] = 
 
648
                                (prod > max_fixed ? max_fixed :
 
649
                                 prod < min_fixed ? min_fixed : (fixed)prod);
 
650
                        }
 
651
                        --csp;
 
652
                        break;
 
653
                    case ce2_sqrt:
 
654
                        if (*csp >= 0)
 
655
                            *csp = float2fixed(sqrt(fixed2float(*csp)));
 
656
                        break;
 
657
                    case ce2_dup:
 
658
                        CS_CHECK_PUSH(csp, cstack);
 
659
                        csp[1] = *csp;
 
660
                        ++csp;
 
661
                        break;
 
662
                    case ce2_exch:
 
663
                        {
 
664
                            fixed top = *csp;
 
665
 
 
666
                            *csp = csp[-1], csp[-1] = top;
 
667
                        }
 
668
                        break;
 
669
                    case ce2_index:
 
670
                        *csp =
 
671
                            (*csp < 0 ? csp[-1] : csp[-1 - fixed2int_var(csp[-1])]);
 
672
                        break;
 
673
                    case ce2_roll:
 
674
                        {
 
675
                            int distance = fixed2int_var(*csp);
 
676
                            int count = fixed2int_var(csp[-1]);
 
677
                            cs_ptr bot;
 
678
 
 
679
                            csp -= 2;
 
680
                            if (count < 0 || count > csp + 1 - cstack)
 
681
                                return_error(gs_error_invalidfont);
 
682
                            if (count == 0)
 
683
                                break;
 
684
                            if (distance < 0)
 
685
                                distance = count - (-distance % count);
 
686
                            bot = csp + 1 - count;
 
687
                            while (--distance >= 0) {
 
688
                                fixed top = *csp;
 
689
 
 
690
                                memmove(bot + 1, bot,
 
691
                                        (count - 1) * sizeof(fixed));
 
692
                                *bot = top;
 
693
                            }
 
694
                        }
 
695
                        break;
 
696
                    case ce2_hflex:
 
697
                        csp[6] = fixed_half;    /* fd/100 */
 
698
                        csp[4] = *csp, csp[5] = 0;      /* dx6, dy6 */
 
699
                        csp[2] = csp[-1], csp[3] = -csp[-4];    /* dx5, dy5 */
 
700
                        *csp = csp[-2], csp[1] = 0;     /* dx4, dy4 */
 
701
                        csp[-2] = csp[-3], csp[-1] = 0;         /* dx3, dy3 */
 
702
                        csp[-3] = csp[-4], csp[-4] = csp[-5];   /* dx2, dy2 */
 
703
                        csp[-5] = 0;    /* dy1 */
 
704
                        csp += 6;
 
705
                        goto flex;
 
706
                    case ce2_flex:
 
707
                        *csp /= 100;    /* fd/100 */
 
708
flex:                   {
 
709
                            fixed x_join = csp[-12] + csp[-10] + csp[-8];
 
710
                            fixed y_join = csp[-11] + csp[-9] + csp[-7];
 
711
                            fixed x_end = x_join + csp[-6] + csp[-4] + csp[-2];
 
712
                            fixed y_end = y_join + csp[-5] + csp[-3] + csp[-1];
 
713
                            gs_point join, end;
 
714
                            double flex_depth;
 
715
 
 
716
                            if ((code =
 
717
                                 gs_distance_transform(fixed2float(x_join),
 
718
                                                       fixed2float(y_join),
 
719
                                                       &ctm_only(pcis->pis),
 
720
                                                       &join)) < 0 ||
 
721
                                (code =
 
722
                                 gs_distance_transform(fixed2float(x_end),
 
723
                                                       fixed2float(y_end),
 
724
                                                       &ctm_only(pcis->pis),
 
725
                                                       &end)) < 0
 
726
                                )
 
727
                                return code;
 
728
                            /*
 
729
                             * Use the X or Y distance depending on whether
 
730
                             * the curve is more horizontal or more
 
731
                             * vertical.
 
732
                             */
 
733
                            if (any_abs(end.y) > any_abs(end.x))
 
734
                                flex_depth = join.x;
 
735
                            else
 
736
                                flex_depth = join.y;
 
737
                            if (fabs(flex_depth) < fixed2float(*csp)) {
 
738
                                /* Do flex as line. */
 
739
                                code = t1_hinter__rlineto(h, x_end, y_end);
 
740
                            } else {
 
741
                                /*
 
742
                                 * Do flex as curve.  We can't jump to rrc,
 
743
                                 * because the flex operators don't clear
 
744
                                 * the stack (!).
 
745
                                 */
 
746
                                code = t1_hinter__rcurveto(h, 
 
747
                                        csp[-12], csp[-11], csp[-10],
 
748
                                        csp[-9], csp[-8], csp[-7]);
 
749
                                if (code < 0)
 
750
                                    return code;
 
751
                                code = t1_hinter__rcurveto(h, 
 
752
                                        csp[-6], csp[-5], csp[-4],
 
753
                                        csp[-3], csp[-2], csp[-1]);
 
754
                            }
 
755
                            if (code < 0)
 
756
                                return code;
 
757
                            csp -= 13;
 
758
                        }
 
759
                        cnext;
 
760
                    case ce2_hflex1:
 
761
                        csp[4] = fixed_half;    /* fd/100 */
 
762
                        csp[2] = *csp;          /* dx6 */
 
763
                        csp[3] = -(csp[-7] + csp[-5] + csp[-1]);        /* dy6 */
 
764
                        *csp = csp[-2], csp[1] = csp[-1];       /* dx5, dy5 */
 
765
                        csp[-2] = csp[-3], csp[-1] = 0;         /* dx4, dy4 */
 
766
                        csp[-3] = 0;    /* dy3 */
 
767
                        csp += 4;
 
768
                        goto flex;
 
769
                    case ce2_flex1:
 
770
                        {
 
771
                            fixed dx = csp[-10] + csp[-8] + csp[-6] + csp[-4] + csp[-2];
 
772
                            fixed dy = csp[-9] + csp[-7] + csp[-5] + csp[-3] + csp[-1];
 
773
 
 
774
                            if (any_abs(dx) > any_abs(dy))
 
775
                                csp[1] = -dy;   /* d6 is dx6 */
 
776
                            else
 
777
                                csp[1] = *csp, *csp = -dx;      /* d6 is dy6 */
 
778
                        }
 
779
                        csp[2] = fixed_half;    /* fd/100 */
 
780
                        csp += 2;
 
781
                        goto flex;
 
782
                }
 
783
                break;
 
784
 
 
785
                /* Fill up the dispatch up to 32. */
 
786
 
 
787
              case_c2_undefs:
 
788
            default:            /* pacify compiler */
 
789
                return_error(gs_error_invalidfont);
 
790
        }
 
791
    }
 
792
}