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

« back to all changes in this revision

Viewing changes to src/gdevpsf1.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: gdevpsf1.c 8296 2007-10-16 07:54:08Z ken $ */
15
 
/* Write an embedded Type 1 font */
16
 
#include "memory_.h"
17
 
#include "gx.h"
18
 
#include "gserrors.h"
19
 
#include "gsccode.h"
20
 
#include "gsmatrix.h"
21
 
#include "gxfixed.h"
22
 
#include "gxfont.h"
23
 
#include "gxfont1.h"
24
 
#include "gxmatrix.h"           /* for gxtype1.h */
25
 
#include "gxtype1.h"
26
 
#include "strimpl.h"            /* required by Watcom compiler (why?) */
27
 
#include "stream.h"
28
 
#include "sfilter.h"
29
 
#include "spsdf.h"
30
 
#include "sstring.h"
31
 
#include "spprint.h"
32
 
#include "gdevpsf.h"
33
 
 
34
 
/* ------ Utilities shared with CFF writer ------ */
35
 
 
36
 
/* Gather glyph information for a Type 1 or Type 2 font. */
37
 
int
38
 
psf_type1_glyph_data(gs_font_base *pbfont, gs_glyph glyph,
39
 
                     gs_glyph_data_t *pgd, gs_font_type1 **ppfont)
40
 
{
41
 
    gs_font_type1 *const pfont = (gs_font_type1 *)pbfont;
42
 
 
43
 
    *ppfont = pfont;
44
 
    return pfont->data.procs.glyph_data(pfont, glyph, pgd);
45
 
}
46
 
int
47
 
psf_get_type1_glyphs(psf_outline_glyphs_t *pglyphs, gs_font_type1 *pfont,
48
 
                     gs_glyph *subset_glyphs, uint subset_size)
49
 
{
50
 
    return psf_get_outline_glyphs(pglyphs, (gs_font_base *)pfont,
51
 
                                  subset_glyphs, subset_size,
52
 
                                  psf_type1_glyph_data);
53
 
}
54
 
 
55
 
/* ------ Main program ------ */
56
 
 
57
 
/* Write a (named) array of floats. */
58
 
static int
59
 
write_float_array(gs_param_list *plist, const char *key, const float *values,
60
 
                  int count)
61
 
{
62
 
    if (count != 0) {
63
 
        gs_param_float_array fa;
64
 
 
65
 
        fa.size = count;
66
 
        fa.data = values;
67
 
        return param_write_float_array(plist, key, &fa);
68
 
    }
69
 
    return 0;
70
 
}
71
 
 
72
 
/* Write a UniqueID and/or XUID. */
73
 
static void
74
 
write_uid(stream *s, const gs_uid *puid)
75
 
{
76
 
    if (uid_is_UniqueID(puid))
77
 
        pprintld1(s, "/UniqueID %ld def\n", puid->id);
78
 
    else if (uid_is_XUID(puid)) {
79
 
        uint i, n = uid_XUID_size(puid);
80
 
 
81
 
        stream_puts(s, "/XUID [");
82
 
        for (i = 0; i < n; ++i)
83
 
            pprintld1(s, "%ld ", uid_XUID_values(puid)[i]);
84
 
        stream_puts(s, "] readonly def\n");
85
 
    }
86
 
}
87
 
 
88
 
/* Write the font name. */
89
 
static void
90
 
write_font_name(stream *s, const gs_font_type1 *pfont,
91
 
                const gs_const_string *alt_font_name, bool as_name)
92
 
{
93
 
    const byte *c;
94
 
    const byte *name = (alt_font_name ? alt_font_name->data : pfont->font_name.chars);
95
 
    int         n    = (alt_font_name ? alt_font_name->size : pfont->font_name.size);
96
 
 
97
 
    if (n == 0)
98
 
        /* empty name, may need to write it as empty string */
99
 
        stream_puts(s, (as_name ? "/" : "()"));
100
 
    else {
101
 
        for (c = (byte *)"()<>[]{}/% \n\r\t\b\f\004\033"; *c; c++)
102
 
            if (memchr(name, *c, n))
103
 
                break;
104
 
        if (*c || memchr(name, 0, n)) {
105
 
            /* name contains whitespace (NUL included) or a PostScript separator */
106
 
            byte pssebuf[1 + 4 * gs_font_name_max + 1]; /* "(" + "\ooo" * gs_font_name_max + ")" */
107
 
            stream_cursor_read  r;
108
 
            stream_cursor_write w;
109
 
 
110
 
            pssebuf[0] = '(';
111
 
            r.limit = (r.ptr = name - 1) + n;
112
 
            w.limit = (w.ptr = pssebuf) + sizeof pssebuf - 1;
113
 
            s_PSSE_template.process(NULL, &r, &w, true);
114
 
            stream_write(s, pssebuf, w.ptr - pssebuf + 1);
115
 
            if (as_name)
116
 
                stream_puts(s, " cvn");
117
 
        } else {
118
 
            /* name without any special characters */
119
 
            if (as_name)
120
 
                stream_putc(s, '/');
121
 
            stream_write(s, name, n);
122
 
        }
123
 
    }
124
 
}
125
 
/*
126
 
 * Write the Encoding array.  This is a separate procedure only for
127
 
 * readability.
128
 
 */
129
 
static int
130
 
write_Encoding(stream *s, gs_font_type1 *pfont, int options,
131
 
              gs_glyph *subset_glyphs, uint subset_size, gs_glyph notdef)
132
 
{
133
 
    stream_puts(s, "/Encoding ");
134
 
    switch (pfont->encoding_index) {
135
 
        case ENCODING_INDEX_STANDARD:
136
 
            stream_puts(s, "StandardEncoding");
137
 
            break;
138
 
        case ENCODING_INDEX_ISOLATIN1:
139
 
            /* ATM only recognizes StandardEncoding. */
140
 
            if (options & WRITE_TYPE1_POSTSCRIPT) {
141
 
                stream_puts(s, "ISOLatin1Encoding");
142
 
                break;
143
 
            }
144
 
        default:{
145
 
                gs_char i;
146
 
 
147
 
                stream_puts(s, "256 array\n");
148
 
                stream_puts(s, "0 1 255 {1 index exch /.notdef put} for\n");
149
 
                for (i = 0; i < 256; ++i) {
150
 
                    gs_glyph glyph =
151
 
                        (*pfont->procs.encode_char)
152
 
                        ((gs_font *)pfont, (gs_char)i, GLYPH_SPACE_NAME);
153
 
                    gs_const_string namestr;
154
 
 
155
 
                    if (subset_glyphs && subset_size) {
156
 
                        /*
157
 
                         * Only write Encoding entries for glyphs in the
158
 
                         * subset.  Use binary search to check each glyph,
159
 
                         * since subset_glyphs are sorted.
160
 
                         */
161
 
                        if (!psf_sorted_glyphs_include(subset_glyphs,
162
 
                                                        subset_size, glyph))
163
 
                            continue;
164
 
                    }
165
 
                    if (glyph != gs_no_glyph && glyph != notdef &&
166
 
                        pfont->procs.glyph_name((gs_font *)pfont, glyph,
167
 
                                                &namestr) >= 0
168
 
                        ) {
169
 
                        pprintd1(s, "dup %d /", (int)i);
170
 
                        stream_write(s, namestr.data, namestr.size);
171
 
                        stream_puts(s, " put\n");
172
 
                    }
173
 
                }
174
 
                stream_puts(s, "readonly");
175
 
            }
176
 
    }
177
 
    stream_puts(s, " def\n");
178
 
    return 0;
179
 
}
180
 
 
181
 
/*
182
 
 * Write the Private dictionary.  This is a separate procedure only for
183
 
 * readability.  write_CharString is a parameter so that we can encrypt
184
 
 * Subrs and CharStrings when the font's lenIV == -1 but we are writing
185
 
 * the font with lenIV = 0.
186
 
 */
187
 
static int
188
 
write_Private(stream *s, gs_font_type1 *pfont,
189
 
              gs_glyph *subset_glyphs, uint subset_size,
190
 
              gs_glyph notdef, int lenIV,
191
 
              int (*write_CharString)(stream *, const void *, uint),
192
 
              const param_printer_params_t *ppp)
193
 
{
194
 
    const gs_type1_data *const pdata = &pfont->data;
195
 
    printer_param_list_t rlist;
196
 
    gs_param_list *const plist = (gs_param_list *)&rlist;
197
 
    int code = s_init_param_printer(&rlist, ppp, s);
198
 
 
199
 
    if (code < 0)
200
 
        return 0;
201
 
    stream_puts(s, "dup /Private 17 dict dup begin\n");
202
 
    stream_puts(s, "/-|{string currentfile exch readstring pop}executeonly def\n");
203
 
    stream_puts(s, "/|-{noaccess def}executeonly def\n");
204
 
    stream_puts(s, "/|{noaccess put}executeonly def\n");
205
 
    {
206
 
        static const gs_param_item_t private_items[] = {
207
 
            {"BlueFuzz", gs_param_type_int,
208
 
             offset_of(gs_type1_data, BlueFuzz)},
209
 
            {"BlueScale", gs_param_type_float,
210
 
             offset_of(gs_type1_data, BlueScale)},
211
 
            {"BlueShift", gs_param_type_float,
212
 
             offset_of(gs_type1_data, BlueShift)},
213
 
            {"ExpansionFactor", gs_param_type_float,
214
 
             offset_of(gs_type1_data, ExpansionFactor)},
215
 
            {"ForceBold", gs_param_type_bool,
216
 
             offset_of(gs_type1_data, ForceBold)},
217
 
            {"LanguageGroup", gs_param_type_int,
218
 
             offset_of(gs_type1_data, LanguageGroup)},
219
 
            {"RndStemUp", gs_param_type_bool,
220
 
             offset_of(gs_type1_data, RndStemUp)},
221
 
            gs_param_item_end
222
 
        };
223
 
        gs_type1_data defaults;
224
 
 
225
 
        defaults.BlueFuzz = 1;
226
 
        defaults.BlueScale = (float)0.039625;
227
 
        defaults.BlueShift = 7.0;
228
 
        defaults.ExpansionFactor = (float)0.06;
229
 
        defaults.ForceBold = false;
230
 
        defaults.LanguageGroup = 0;
231
 
        defaults.RndStemUp = true;
232
 
        code = gs_param_write_items(plist, pdata, &defaults, private_items);
233
 
        if (code < 0)
234
 
            return code;
235
 
        if (lenIV != 4) {
236
 
            code = param_write_int(plist, "lenIV", &lenIV);
237
 
            if (code < 0)
238
 
                return code;
239
 
        }
240
 
        write_float_array(plist, "BlueValues", pdata->BlueValues.values,
241
 
                          pdata->BlueValues.count);
242
 
        write_float_array(plist, "OtherBlues", pdata->OtherBlues.values,
243
 
                          pdata->OtherBlues.count);
244
 
        write_float_array(plist, "FamilyBlues", pdata->FamilyBlues.values,
245
 
                          pdata->FamilyBlues.count);
246
 
        write_float_array(plist, "FamilyOtherBlues", pdata->FamilyOtherBlues.values,
247
 
                          pdata->FamilyOtherBlues.count);
248
 
        write_float_array(plist, "StdHW", pdata->StdHW.values,
249
 
                          pdata->StdHW.count);
250
 
        write_float_array(plist, "StdVW", pdata->StdVW.values,
251
 
                          pdata->StdVW.count);
252
 
        write_float_array(plist, "StemSnapH", pdata->StemSnapH.values,
253
 
                          pdata->StemSnapH.count);
254
 
        write_float_array(plist, "StemSnapV", pdata->StemSnapV.values,
255
 
                          pdata->StemSnapV.count);
256
 
    }
257
 
    write_uid(s, &pfont->UID);
258
 
    stream_puts(s, "/MinFeature{16 16} def\n");
259
 
    stream_puts(s, "/password 5839 def\n");
260
 
 
261
 
    /*
262
 
     * Write the Subrs.  We always write them all, even for subsets.
263
 
     * (We will fix this someday.)
264
 
     */
265
 
 
266
 
    {
267
 
        int n, i;
268
 
        gs_glyph_data_t gdata;
269
 
        int code;
270
 
 
271
 
        gdata.memory = pfont->memory;
272
 
        for (n = 0;
273
 
             (code = pdata->procs.subr_data(pfont, n, false, &gdata)) !=
274
 
                 gs_error_rangecheck;
275
 
             ) {
276
 
            ++n;
277
 
            if (code >= 0)
278
 
                gs_glyph_data_free(&gdata, "write_Private(Subrs)");
279
 
        }
280
 
        pprintd1(s, "/Subrs %d array\n", n);
281
 
        for (i = 0; i < n; ++i)
282
 
            if ((code = pdata->procs.subr_data(pfont, i, false, &gdata)) >= 0) {
283
 
                char buf[50];
284
 
 
285
 
                if (gdata.bits.size) {
286
 
                    sprintf(buf, "dup %d %u -| ", i, gdata.bits.size);
287
 
                    stream_puts(s, buf);
288
 
                    write_CharString(s, gdata.bits.data, gdata.bits.size);
289
 
                    stream_puts(s, " |\n");
290
 
                }
291
 
                gs_glyph_data_free(&gdata, "write_Private(Subrs)");
292
 
            }
293
 
        stream_puts(s, "|-\n");
294
 
    }
295
 
 
296
 
    /* We don't write OtherSubrs -- there had better not be any! */
297
 
 
298
 
    /* Write the CharStrings. */
299
 
 
300
 
    {
301
 
        int num_chars = 0;
302
 
        gs_glyph glyph;
303
 
        psf_glyph_enum_t genum;
304
 
        gs_glyph_data_t gdata;
305
 
        int code;
306
 
 
307
 
        gdata.memory = pfont->memory;
308
 
        psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, subset_glyphs,
309
 
                                    (subset_glyphs ? subset_size : 0),
310
 
                                    GLYPH_SPACE_NAME);
311
 
        for (glyph = gs_no_glyph;
312
 
             (code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1;
313
 
             )
314
 
            if (code == 0 &&
315
 
                (code = pdata->procs.glyph_data(pfont, glyph, &gdata)) >= 0
316
 
                ) {
317
 
                ++num_chars;
318
 
                gs_glyph_data_free(&gdata, "write_Private(CharStrings)");
319
 
            }
320
 
        pprintd1(s, "2 index /CharStrings %d dict dup begin\n", num_chars);
321
 
        psf_enumerate_glyphs_reset(&genum);
322
 
        for (glyph = gs_no_glyph;
323
 
             (code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1;
324
 
            )
325
 
            if (code == 0 &&
326
 
                (code = pdata->procs.glyph_data(pfont, glyph, &gdata)) >= 0
327
 
                ) {
328
 
                gs_const_string gstr;
329
 
                int code;
330
 
 
331
 
                code = pfont->procs.glyph_name((gs_font *)pfont, glyph, &gstr);
332
 
                if (code < 0)
333
 
                    return code;
334
 
                stream_puts(s, "/");
335
 
                stream_write(s, gstr.data, gstr.size);
336
 
                pprintd1(s, " %d -| ", gdata.bits.size);
337
 
                write_CharString(s, gdata.bits.data, gdata.bits.size);
338
 
                stream_puts(s, " |-\n");
339
 
                gs_glyph_data_free(&gdata, "write_Private(CharStrings)");
340
 
            }
341
 
    }
342
 
 
343
 
    /* Wrap up. */
344
 
 
345
 
    stream_puts(s, "end\nend\nreadonly put\nnoaccess put\n");
346
 
    s_release_param_printer(&rlist);
347
 
    return 0;
348
 
}
349
 
 
350
 
/* Encrypt and write a CharString. */
351
 
static int
352
 
stream_write_encrypted(stream *s, const void *ptr, uint count)
353
 
{
354
 
    const byte *const data = ptr;
355
 
    crypt_state state = crypt_charstring_seed;
356
 
    byte buf[50];               /* arbitrary */
357
 
    uint left, n;
358
 
    int code = 0;
359
 
 
360
 
    for (left = count; left > 0; left -= n) {
361
 
        n = min(left, sizeof(buf));
362
 
        gs_type1_encrypt(buf, data + count - left, n, &state);
363
 
        code = stream_write(s, buf, n);
364
 
    }
365
 
    return code;
366
 
}
367
 
 
368
 
/* Write one FontInfo entry. */
369
 
static void
370
 
write_font_info(stream *s, const char *key, const gs_const_string *pvalue,
371
 
                int do_write)
372
 
{
373
 
    if (do_write) {
374
 
        pprints1(s, "\n/%s ", key);
375
 
        s_write_ps_string(s, pvalue->data, pvalue->size, PRINT_HEX_NOT_OK);
376
 
        stream_puts(s, " def");
377
 
    }
378
 
}
379
 
 
380
 
/* Write the definition of a Type 1 font. */
381
 
int
382
 
psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options,
383
 
                      gs_glyph *orig_subset_glyphs, uint orig_subset_size,
384
 
                      const gs_const_string *alt_font_name, int lengths[3])
385
 
{
386
 
    stream *es = s;
387
 
    long start = stell(s);
388
 
    param_printer_params_t ppp;
389
 
    printer_param_list_t rlist;
390
 
    gs_param_list *const plist = (gs_param_list *)&rlist;
391
 
    stream AXE_stream;
392
 
    stream_AXE_state AXE_state;
393
 
    byte AXE_buf[200];          /* arbitrary */
394
 
    stream exE_stream;
395
 
    stream_exE_state exE_state;
396
 
    byte exE_buf[200];          /* arbitrary */
397
 
    psf_outline_glyphs_t glyphs;
398
 
    int lenIV = pfont->data.lenIV;
399
 
    int (*write_CharString)(stream *, const void *, uint) = stream_write;
400
 
    int code = psf_get_type1_glyphs(&glyphs, pfont, orig_subset_glyphs,
401
 
                                     orig_subset_size);
402
 
 
403
 
    if (code < 0)
404
 
        return code;
405
 
 
406
 
    /* Initialize the parameter printer. */
407
 
 
408
 
    ppp = param_printer_params_default;
409
 
    ppp.item_suffix = " def\n";
410
 
    ppp.print_ok =
411
 
        (options & WRITE_TYPE1_ASCIIHEX ? 0 : PRINT_BINARY_OK) |
412
 
        PRINT_HEX_NOT_OK;
413
 
    code = s_init_param_printer(&rlist, &ppp, s);
414
 
    if (code < 0)
415
 
        return code;
416
 
 
417
 
    /* Write the font header. */
418
 
 
419
 
    stream_puts(s, "%!FontType1-1.0: ");
420
 
    write_font_name(s, pfont, alt_font_name, false);
421
 
    stream_puts(s, "\n11 dict begin\n");
422
 
 
423
 
    /* Write FontInfo. */
424
 
 
425
 
    stream_puts(s, "/FontInfo 5 dict dup begin");
426
 
    {
427
 
        gs_font_info_t info;
428
 
        int code = pfont->procs.font_info((gs_font *)pfont, NULL,
429
 
                        (FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE |
430
 
                         FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME),
431
 
                                          &info);
432
 
 
433
 
        if (code >= 0) {
434
 
            write_font_info(s, "Copyright", &info.Copyright,
435
 
                            info.members & FONT_INFO_COPYRIGHT);
436
 
            write_font_info(s, "Notice", &info.Notice,
437
 
                            info.members & FONT_INFO_NOTICE);
438
 
            write_font_info(s, "FamilyName", &info.FamilyName,
439
 
                            info.members & FONT_INFO_FAMILY_NAME);
440
 
            write_font_info(s, "FullName", &info.FullName,
441
 
                            info.members & FONT_INFO_FULL_NAME);
442
 
        }
443
 
    }
444
 
    stream_puts(s, "\nend readonly def\n");
445
 
 
446
 
    /* Write the main font dictionary. */
447
 
 
448
 
    stream_puts(s, "/FontName ");
449
 
    write_font_name(s, pfont, alt_font_name, true);
450
 
    stream_puts(s, " def\n");
451
 
    code = write_Encoding(s, pfont, options, glyphs.subset_glyphs,
452
 
                          glyphs.subset_size, glyphs.notdef);
453
 
    if (code < 0)
454
 
        return code;
455
 
    pprintg6(s, "/FontMatrix [%g %g %g %g %g %g] readonly def\n",
456
 
             pfont->FontMatrix.xx, pfont->FontMatrix.xy,
457
 
             pfont->FontMatrix.yx, pfont->FontMatrix.yy,
458
 
             pfont->FontMatrix.tx, pfont->FontMatrix.ty);
459
 
    write_uid(s, &pfont->UID);
460
 
    pprintg4(s, "/FontBBox {%g %g %g %g} readonly def\n",
461
 
             pfont->FontBBox.p.x, pfont->FontBBox.p.y,
462
 
             pfont->FontBBox.q.x, pfont->FontBBox.q.y);
463
 
    {
464
 
        static const gs_param_item_t font_items[] = {
465
 
            {"FontType", gs_param_type_int,
466
 
             offset_of(gs_font_type1, FontType)},
467
 
            {"PaintType", gs_param_type_int,
468
 
             offset_of(gs_font_type1, PaintType)},
469
 
            {"StrokeWidth", gs_param_type_float,
470
 
             offset_of(gs_font_type1, StrokeWidth)},
471
 
            gs_param_item_end
472
 
        };
473
 
 
474
 
        code = gs_param_write_items(plist, pfont, NULL, font_items);
475
 
        if (code < 0)
476
 
            return code;
477
 
    }
478
 
    {
479
 
        const gs_type1_data *const pdata = &pfont->data;
480
 
 
481
 
        write_float_array(plist, "WeightVector", pdata->WeightVector.values,
482
 
                          pdata->WeightVector.count);
483
 
    }
484
 
    stream_puts(s, "currentdict end\n");
485
 
 
486
 
    /* Write the Private dictionary. */
487
 
 
488
 
    if (lenIV < 0 && (options & WRITE_TYPE1_WITH_LENIV)) {
489
 
        /* We'll have to encrypt the CharStrings. */
490
 
        lenIV = 0;
491
 
        write_CharString = stream_write_encrypted;
492
 
    }
493
 
    if (options & WRITE_TYPE1_EEXEC) {
494
 
        stream_puts(s, "currentfile eexec\n");
495
 
        lengths[0] = stell(s) - start;
496
 
        start = stell(s);
497
 
        if (options & WRITE_TYPE1_ASCIIHEX) {
498
 
            s_init(&AXE_stream, s->memory);
499
 
            s_init_state((stream_state *)&AXE_state, &s_AXE_template, NULL);
500
 
            AXE_state.EndOfData = false;
501
 
            s_init_filter(&AXE_stream, (stream_state *)&AXE_state,
502
 
                          AXE_buf, sizeof(AXE_buf), es);
503
 
            es = &AXE_stream;
504
 
        }
505
 
        s_init(&exE_stream, s->memory);
506
 
        s_init_state((stream_state *)&exE_state, &s_exE_template, NULL);
507
 
        exE_state.cstate = 55665;
508
 
        s_init_filter(&exE_stream, (stream_state *)&exE_state,
509
 
                      exE_buf, sizeof(exE_buf), es);
510
 
        es = &exE_stream;
511
 
        /*
512
 
         * Note: eexec encryption always writes/skips 4 initial bytes, not
513
 
         * the number of initial bytes given by pdata->lenIV.
514
 
         */
515
 
        stream_puts(es, "****");
516
 
    }
517
 
    code = write_Private(es, pfont, glyphs.subset_glyphs, glyphs.subset_size,
518
 
                         glyphs.notdef, lenIV, write_CharString, &ppp);
519
 
    if (code < 0)
520
 
        return code;
521
 
    stream_puts(es, "dup/FontName get exch definefont pop\n");
522
 
    if (options & WRITE_TYPE1_EEXEC) {
523
 
        if (options & (WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_EEXEC_MARK))
524
 
            stream_puts(es, "mark ");
525
 
        stream_puts(es, "currentfile closefile\n");
526
 
        s_close_filters(&es, s);
527
 
        lengths[1] = stell(s) - start;
528
 
        start = stell(s);
529
 
        if (options & WRITE_TYPE1_EEXEC_PAD) {
530
 
            int i;
531
 
 
532
 
            for (i = 0; i < 8; ++i)
533
 
                stream_puts(s, "\n0000000000000000000000000000000000000000000000000000000000000000");
534
 
            stream_puts(s, "\ncleartomark\n");
535
 
        }
536
 
        lengths[2] = stell(s) - start;
537
 
    } else {
538
 
        lengths[0] = stell(s) - start;
539
 
        lengths[1] = lengths[2] = 0;
540
 
    }
541
 
 
542
 
    /* Wrap up. */
543
 
 
544
 
    s_release_param_printer(&rlist);
545
 
    return 0;
546
 
}