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

« back to all changes in this revision

Viewing changes to base/gdevpsfm.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: gdevpsfm.c 8250 2007-09-25 13:31:24Z giles $ */
 
15
/* Write a CMap */
 
16
#include "gx.h"
 
17
#include "gserrors.h"
 
18
#include "gxfcmap.h"
 
19
#include "stream.h"
 
20
#include "spprint.h"
 
21
#include "spsdf.h"
 
22
#include "gdevpsf.h"
 
23
#include "memory_.h"
 
24
 
 
25
/* ---------------- Utilities ---------------- */
 
26
 
 
27
typedef struct cmap_operators_s {
 
28
    const char *beginchar;
 
29
    const char *endchar;
 
30
    const char *beginrange;
 
31
    const char *endrange;
 
32
} cmap_operators_t;
 
33
static const cmap_operators_t
 
34
  cmap_cid_operators = {
 
35
    "begincidchar\n", "endcidchar\n",
 
36
    "begincidrange\n", "endcidrange\n"
 
37
  },
 
38
  cmap_notdef_operators = {
 
39
    "beginnotdefchar\n", "endnotdefchar\n",
 
40
    "beginnotdefrange\n", "endnotdefrange\n"
 
41
  };
 
42
 
 
43
/* Write a gs_string with a prefix. */
 
44
static void
 
45
pput_string_entry(stream *s, const char *prefix, const gs_const_string *pstr)
 
46
{
 
47
    stream_puts(s, prefix);
 
48
    stream_write(s, pstr->data, pstr->size);
 
49
}
 
50
 
 
51
/* Write a hex string. */
 
52
static void
 
53
pput_hex(stream *s, const byte *pcid, int size)
 
54
{
 
55
    int i;
 
56
    static const char *const hex_digits = "0123456789abcdef";
 
57
 
 
58
    for (i = 0; i < size; ++i) {
 
59
        stream_putc(s, hex_digits[pcid[i] >> 4]);
 
60
        stream_putc(s, hex_digits[pcid[i] & 0xf]);
 
61
    }
 
62
}
 
63
 
 
64
/* Write a list of code space ranges. */
 
65
static void
 
66
cmap_put_ranges(stream *s, const gx_code_space_range_t *pcsr, int count)
 
67
{
 
68
    int i;
 
69
 
 
70
    pprintd1(s, "%d begincodespacerange\n", count);
 
71
    for (i = 0; i < count; ++i, ++pcsr) {
 
72
        stream_puts(s, "<");
 
73
        pput_hex(s, pcsr->first, pcsr->size);
 
74
        stream_puts(s, "><");
 
75
        pput_hex(s, pcsr->last, pcsr->size);
 
76
        stream_puts(s, ">\n");
 
77
    }
 
78
    stream_puts(s, "endcodespacerange\n");
 
79
}
 
80
 
 
81
/* Write one CIDSystemInfo dictionary. */
 
82
static void
 
83
cmap_put_system_info(stream *s, const gs_cid_system_info_t *pcidsi)
 
84
{
 
85
    if (cid_system_info_is_null(pcidsi)) {
 
86
        stream_puts(s, " null ");
 
87
    } else {
 
88
        stream_puts(s, " 3 dict dup begin\n");
 
89
        stream_puts(s, "/Registry ");
 
90
        s_write_ps_string(s, pcidsi->Registry.data, pcidsi->Registry.size, 0);
 
91
        stream_puts(s, " def\n/Ordering ");
 
92
        s_write_ps_string(s, pcidsi->Ordering.data, pcidsi->Ordering.size, 0);
 
93
        pprintd1(s, " def\n/Supplement %d def\nend ", pcidsi->Supplement);
 
94
    }
 
95
}
 
96
 
 
97
/* Write one code map. */
 
98
static int
 
99
cmap_put_code_map(const gs_memory_t *mem,
 
100
                  stream *s, int which, const gs_cmap_t *pcmap,
 
101
                  const cmap_operators_t *pcmo,
 
102
                  psf_put_name_chars_proc_t put_name_chars, 
 
103
                  int font_index_only)
 
104
{
 
105
    /* For simplicity, produce one entry for each lookup range. */
 
106
    gs_cmap_lookups_enum_t lenum;
 
107
    int font_index = (pcmap->num_fonts <= 1 ? 0 : -1);
 
108
    int code;
 
109
 
 
110
    for (gs_cmap_lookups_enum_init(pcmap, which, &lenum);
 
111
         (code = gs_cmap_enum_next_lookup(&lenum)) == 0; ) {
 
112
        gs_cmap_lookups_enum_t counter;
 
113
        int num_entries = 0;
 
114
        int gi;
 
115
 
 
116
        if (font_index_only >= 0 && lenum.entry.font_index != font_index_only)
 
117
            continue;
 
118
        if (font_index_only < 0 && lenum.entry.font_index != font_index) {
 
119
            pprintd1(s, "%d usefont\n", lenum.entry.font_index);
 
120
            font_index = lenum.entry.font_index;
 
121
        }
 
122
        /* Count the number of entries in this lookup range. */
 
123
        counter = lenum;
 
124
        while (gs_cmap_enum_next_entry(&counter) == 0)
 
125
            ++num_entries;
 
126
        for (gi = 0; gi < num_entries; gi += 100) {
 
127
            int i = gi, ni = min(i + 100, num_entries);
 
128
            const char *end;
 
129
 
 
130
            pprintd1(s, "%d ", ni - i);
 
131
            if (lenum.entry.key_is_range) {
 
132
                if (lenum.entry.value_type == CODE_VALUE_CID || lenum.entry.value_type == CODE_VALUE_NOTDEF) {
 
133
                    stream_puts(s, pcmo->beginrange);
 
134
                    end = pcmo->endrange;
 
135
                } else {        /* must be def, not notdef */
 
136
                    stream_puts(s, "beginbfrange\n");
 
137
                    end = "endbfrange\n";
 
138
                }
 
139
            } else {
 
140
                if (lenum.entry.value_type == CODE_VALUE_CID || lenum.entry.value_type == CODE_VALUE_NOTDEF) {
 
141
                    stream_puts(s, pcmo->beginchar);
 
142
                    end = pcmo->endchar;
 
143
                } else {        /* must be def, not notdef */
 
144
                    stream_puts(s, "beginbfchar\n");
 
145
                    end = "endbfchar\n";
 
146
                }
 
147
            }
 
148
            for (; i < ni; ++i) {
 
149
                int j;
 
150
                long value;
 
151
                int value_size;
 
152
 
 
153
                DISCARD(gs_cmap_enum_next_entry(&lenum)); /* can't fail */
 
154
                value_size = lenum.entry.value.size;
 
155
                for (j = 0; j <= lenum.entry.key_is_range; ++j) {
 
156
                    stream_putc(s, '<');
 
157
                    pput_hex(s, lenum.entry.key[j], lenum.entry.key_size);
 
158
                    stream_putc(s, '>');
 
159
                }
 
160
                for (j = 0, value = 0; j < value_size; ++j)
 
161
                    value = (value << 8) + lenum.entry.value.data[j];
 
162
                switch (lenum.entry.value_type) {
 
163
                case CODE_VALUE_CID:
 
164
                case CODE_VALUE_NOTDEF:
 
165
                    pprintld1(s, "%ld", value);
 
166
                    break;
 
167
                case CODE_VALUE_CHARS:
 
168
                    stream_putc(s, '<');
 
169
                    pput_hex(s, lenum.entry.value.data, value_size);
 
170
                    stream_putc(s, '>');
 
171
                    break;
 
172
                case CODE_VALUE_GLYPH: {
 
173
                    gs_const_string str;
 
174
                    int code = pcmap->glyph_name(mem, (gs_glyph)value, &str,
 
175
                                                 pcmap->glyph_name_data);
 
176
 
 
177
                    if (code < 0)
 
178
                        return code;
 
179
                    stream_putc(s, '/');
 
180
                    code = put_name_chars(s, str.data, str.size);
 
181
                    if (code < 0)
 
182
                        return code;
 
183
                }
 
184
                    break;
 
185
                default:        /* not possible */
 
186
                    return_error(gs_error_unregistered);
 
187
                }
 
188
                stream_putc(s, '\n');
 
189
            }
 
190
            stream_puts(s, end);
 
191
        }
 
192
    }
 
193
    return code;
 
194
}
 
195
 
 
196
/* ---------------- Main program ---------------- */
 
197
 
 
198
/* Write a CMap in its standard (source) format. */
 
199
int
 
200
psf_write_cmap(const gs_memory_t *mem, 
 
201
               stream *s, const gs_cmap_t *pcmap,
 
202
               psf_put_name_chars_proc_t put_name_chars,
 
203
               const gs_const_string *alt_cmap_name, int font_index_only)
 
204
{
 
205
    const gs_const_string *const cmap_name =
 
206
        (alt_cmap_name ? alt_cmap_name : &pcmap->CMapName);
 
207
    const gs_cid_system_info_t *const pcidsi = pcmap->CIDSystemInfo;
 
208
 
 
209
    switch (pcmap->CMapType) {
 
210
    case 0: case 1: case 2:
 
211
        break;
 
212
    default:
 
213
        return_error(gs_error_rangecheck);
 
214
    }
 
215
 
 
216
    /* Write the header. */
 
217
 
 
218
    if (!pcmap->ToUnicode) {
 
219
        stream_puts(s, "%!PS-Adobe-3.0 Resource-CMap\n");
 
220
        stream_puts(s, "%%DocumentNeededResources: ProcSet (CIDInit)\n");
 
221
        stream_puts(s, "%%IncludeResource: ProcSet (CIDInit)\n");
 
222
        pput_string_entry(s, "%%BeginResource: CMap (", cmap_name);
 
223
        pput_string_entry(s, ")\n%%Title: (", cmap_name);
 
224
        pput_string_entry(s, " ", &pcidsi->Registry);
 
225
        pput_string_entry(s, " ", &pcidsi->Ordering);
 
226
        pprintd1(s, " %d)\n", pcidsi->Supplement);
 
227
        pprintg1(s, "%%%%Version: %g\n", pcmap->CMapVersion);
 
228
    }
 
229
    stream_puts(s, "/CIDInit /ProcSet findresource begin\n");
 
230
    stream_puts(s, "12 dict begin\nbegincmap\n");
 
231
 
 
232
    /* Write the fixed entries. */
 
233
 
 
234
    pprintd1(s, "/CMapType %d def\n", pcmap->CMapType);
 
235
    stream_puts(s, "/CMapName/");
 
236
    put_name_chars(s, cmap_name->data, cmap_name->size);
 
237
    stream_puts(s, " def\n");
 
238
    if (!pcmap->ToUnicode) {
 
239
        pprintg1(s, "/CMapVersion %g def\n", pcmap->CMapVersion);
 
240
        stream_puts(s, "/CIDSystemInfo");
 
241
        if (font_index_only >= 0 && font_index_only < pcmap->num_fonts) {
 
242
            cmap_put_system_info(s, pcidsi + font_index_only);
 
243
        } else if (pcmap->num_fonts == 1) {
 
244
            cmap_put_system_info(s, pcidsi);
 
245
        } else {
 
246
            int i;
 
247
 
 
248
            pprintd1(s, " %d array\n", pcmap->num_fonts);
 
249
            for (i = 0; i < pcmap->num_fonts; ++i) {
 
250
                pprintd1(s, "dup %d", i);
 
251
                cmap_put_system_info(s, pcidsi + i);
 
252
                stream_puts(s, "put\n");
 
253
            }
 
254
        }
 
255
        stream_puts(s, " def\n");
 
256
        if (uid_is_XUID(&pcmap->uid)) {
 
257
            uint i, n = uid_XUID_size(&pcmap->uid);
 
258
            const long *values = uid_XUID_values(&pcmap->uid);
 
259
 
 
260
            stream_puts(s, "/XUID [");
 
261
            for (i = 0; i < n; ++i)
 
262
                pprintld1(s, " %ld", values[i]);
 
263
            stream_puts(s, "] def\n");
 
264
        }
 
265
        pprintld1(s, "/UIDOffset %ld def\n", pcmap->UIDOffset);
 
266
        pprintd1(s, "/WMode %d def\n", pcmap->WMode);
 
267
    }
 
268
 
 
269
    /* Write the code space ranges. */
 
270
 
 
271
    {
 
272
        gs_cmap_ranges_enum_t renum;
 
273
#define MAX_RANGES 100
 
274
        gx_code_space_range_t ranges[MAX_RANGES];
 
275
        int code, count = 0;
 
276
 
 
277
        for (gs_cmap_ranges_enum_init(pcmap, &renum);
 
278
             (code = gs_cmap_enum_next_range(&renum)) == 0; ) {
 
279
            if (count == MAX_RANGES) {
 
280
                cmap_put_ranges(s, ranges, count);
 
281
                count = 0;
 
282
            }
 
283
            ranges[count++] = renum.range;
 
284
        }
 
285
        if (code < 0)
 
286
            return code;
 
287
        if (count)
 
288
            cmap_put_ranges(s, ranges, count);
 
289
#undef MAX_RANGES
 
290
    }
 
291
 
 
292
    /* Write the code and notdef data. */
 
293
 
 
294
    {
 
295
        int code;
 
296
 
 
297
        code = cmap_put_code_map(mem, s, 1, pcmap, &cmap_notdef_operators,
 
298
                                 put_name_chars, font_index_only);
 
299
        if (code < 0)
 
300
            return code;
 
301
        code = cmap_put_code_map(mem, s, 0, pcmap, &cmap_cid_operators,
 
302
                                 put_name_chars, font_index_only);
 
303
        if (code < 0)
 
304
            return code;
 
305
    }
 
306
 
 
307
    /* Write the trailer. */
 
308
 
 
309
    stream_puts(s, "endcmap\n");
 
310
    stream_puts(s, "CMapName currentdict /CMap defineresource pop\nend end\n");
 
311
    if (!pcmap->ToUnicode) {
 
312
        stream_puts(s, "%%EndResource\n");
 
313
        stream_puts(s, "%%EOF\n");
 
314
    }
 
315
 
 
316
    return 0;
 
317
}
 
318