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

« back to all changes in this revision

Viewing changes to base/write_t2.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: write_t2.c 8022 2007-06-05 22:23:38Z giles $ */
 
15
 
 
16
/*
 
17
Functions to serialize a type 1 font so that it can then be
 
18
passed to FreeType via the FAPI FreeType bridge.
 
19
Started by Graham Asher, 9th August 2002.
 
20
*/
 
21
 
 
22
#include "wrfont.h"
 
23
#include "write_t2.h"
 
24
#include "ghost.h"
 
25
#include "gxfont.h"
 
26
#include "gxfont1.h"
 
27
 
 
28
/*
 
29
Public structures and functions in this file are prefixed with FF_ because they are part of
 
30
the FAPI FreeType implementation.
 
31
*/
 
32
 
 
33
static void write_4_byte_int(unsigned char* a_output,long a_int)
 
34
        {
 
35
        a_output[0] = (unsigned char)(a_int >> 24);
 
36
        a_output[1] = (unsigned char)(a_int >> 16);
 
37
        a_output[2] = (unsigned char)(a_int >> 8);
 
38
        a_output[3] = (unsigned char)(a_int & 0xFF);
 
39
        }
 
40
 
 
41
static void write_type2_int(WRF_output* a_output,long a_int)
 
42
        {
 
43
        if (a_int >= -107 && a_int <= 107)
 
44
                WRF_wbyte(a_output,(unsigned char)(a_int + 139));
 
45
        else if (a_int >= -32768 && a_int <= 32767)
 
46
                {
 
47
                if (a_int >= 108 && a_int <= 1131)
 
48
                        a_int += 63124;
 
49
                else if (a_int >= -1131 && a_int <= -108)
 
50
                        a_int = -a_int + 64148;
 
51
                else
 
52
                        WRF_wbyte(a_output,28);
 
53
                WRF_wbyte(a_output,(unsigned char)(a_int >> 8));
 
54
                WRF_wbyte(a_output,(unsigned char)(a_int & 0xFF));
 
55
                }
 
56
        else
 
57
                {
 
58
                unsigned char buffer[4];
 
59
                WRF_wbyte(a_output,29);
 
60
                write_4_byte_int(buffer,a_int);
 
61
                WRF_wtext(a_output,buffer,4);
 
62
                }
 
63
        }
 
64
 
 
65
static void write_type2_float(WRF_output* a_output,double a_float)
 
66
        {
 
67
        char buffer[32];
 
68
        const char* p = buffer;
 
69
        int high = true;
 
70
        char c = 0;
 
71
        sprintf(buffer,"%f",a_float);
 
72
        WRF_wbyte(a_output,30);
 
73
        for (;;)
 
74
                {
 
75
                char n = 0;
 
76
                if (*p >= '0' && *p <= '9')
 
77
                        n = (char)(*p - '0');
 
78
                else if (*p == '.')
 
79
                        n = 0xA;
 
80
                else if (*p == 'e' || *p == 'E')
 
81
                        {
 
82
                        if (p[1] == '-')
 
83
                                {
 
84
                                p++;
 
85
                                n = 0xC;
 
86
                                }
 
87
                        else
 
88
                                n = 0xB;
 
89
                        }
 
90
                else if (*p == '-')
 
91
                        n = 0xE;
 
92
                else if (*p == 0)
 
93
                        n = 0xF;
 
94
                if (high)
 
95
                        {
 
96
                        if (*p == 0)
 
97
                                WRF_wbyte(a_output,0xFF);
 
98
                        else
 
99
                                c = (char)(n << 4);
 
100
                        }
 
101
                else
 
102
                        {
 
103
                        c |= n;
 
104
                        WRF_wbyte(a_output,c);
 
105
                        }
 
106
 
 
107
                if (*p == 0)
 
108
                        break;
 
109
 
 
110
                high = !high;
 
111
                p++;
 
112
                }
 
113
        }
 
114
 
 
115
static void write_header(WRF_output* a_output)
 
116
        {
 
117
        WRF_wtext(a_output,(const unsigned char*)"\x1\x0\x4\x1",4);
 
118
        }
 
119
 
 
120
static void write_name_index(WRF_output* a_output)
 
121
        {
 
122
        /* Write a dummy name of 'x'. */
 
123
        WRF_wtext(a_output,(const unsigned char*)"\x0\x1\x1\x1\x2""x",6);
 
124
        }
 
125
 
 
126
static void write_word_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,
 
127
                                                         int a_feature_count,bool a_two_byte_op,int a_op,int a_divisor)
 
128
        {
 
129
        if (a_feature_count > 0)
 
130
                {
 
131
                int i;
 
132
                for (i = 0; i < a_feature_count; i++)
 
133
                        {
 
134
                        /* Get the value and convert it from unsigned to signed. */
 
135
                        short x = a_fapi_font->get_word(a_fapi_font,a_feature_id,i);
 
136
                        /* Divide by the divisor to bring it back to font units. */
 
137
                        x = (short)(x / a_divisor);
 
138
                        write_type2_int(a_output,x);
 
139
                        }
 
140
                if (a_two_byte_op)
 
141
                        WRF_wbyte(a_output,12);
 
142
                WRF_wbyte(a_output,(unsigned char)a_op);
 
143
                }
 
144
        }
 
145
 
 
146
static void write_delta_array_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,
 
147
                                                                        bool a_two_byte_op,int a_op,int a_divisor)
 
148
        {
 
149
        int i;
 
150
        /* NOTE that the feature index (a_feature_id) must be preceded by the count index for this to work. */
 
151
        int count = a_fapi_font->get_word(a_fapi_font,a_feature_id - 1,0);
 
152
        if (count > 0)
 
153
                {
 
154
                short prev_value = 0;
 
155
                for (i = 0; i < count; i++)
 
156
                        {
 
157
                        /* Get the value and convert it from unsigned to signed. */
 
158
                        short value = a_fapi_font->get_word(a_fapi_font,a_feature_id,i); 
 
159
                        /* Divide by the divisor to bring it back to font units. */
 
160
                        value = (short)(value / a_divisor);
 
161
                        write_type2_int(a_output,value - prev_value);
 
162
                        prev_value = value;
 
163
                        }
 
164
                if (a_two_byte_op)
 
165
                        WRF_wbyte(a_output,12);
 
166
                WRF_wbyte(a_output,(unsigned char)a_op);
 
167
                }
 
168
        }
 
169
 
 
170
static void write_float_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,int a_feature_count,bool a_two_byte_op,int a_op)
 
171
        {
 
172
        if (a_feature_count > 0)
 
173
                {
 
174
                int i;
 
175
                for (i = 0; i < a_feature_count; i++)
 
176
                        {
 
177
                        double x = a_fapi_font->get_float(a_fapi_font,a_feature_id,i);
 
178
                        write_type2_float(a_output,x);
 
179
                        }
 
180
                if (a_two_byte_op)
 
181
                        WRF_wbyte(a_output,12);
 
182
                WRF_wbyte(a_output,(unsigned char)a_op);
 
183
                }
 
184
        }
 
185
 
 
186
static void write_font_dict_index(FAPI_font* a_fapi_font,WRF_output* a_output,
 
187
                unsigned char** a_charset_offset_ptr,
 
188
                unsigned char** a_charstrings_offset_ptr,
 
189
                unsigned char** a_private_dict_length_ptr)
 
190
        {
 
191
        unsigned char* data_start = 0;
 
192
        WRF_wtext(a_output,(const unsigned char *)"\x0\x1\x2\x0\x1\x0\x0",7); /* count = 1, offset size = 2, first offset = 1, last offset = 0 (to be filled in later). */
 
193
        if (a_output->m_pos)
 
194
                data_start = a_output->m_pos;
 
195
        write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FontBBox,4,false,5,1);
 
196
        write_float_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FontMatrix,6,true,7);
 
197
        write_type2_int(a_output,0); /* 0 = Standard Encoding. */
 
198
        WRF_wbyte(a_output,16); /* 16 = opcode for 'encoding'. */
 
199
        *a_charset_offset_ptr = a_output->m_pos;
 
200
        WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx",5); /* placeholder for the offset to the charset, which will be a 5-byte integer. */
 
201
        WRF_wbyte(a_output,15); /* opcode for 'charset' */
 
202
        *a_charstrings_offset_ptr = a_output->m_pos;
 
203
        WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx",5); /* placeholder for the offset to the Charstrings index, which will be a 5-byte integer. */
 
204
        WRF_wbyte(a_output,17); /* opcode for 'Charstrings' */
 
205
        *a_private_dict_length_ptr = a_output->m_pos;
 
206
        WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx\x1d""yyyy",10); /* placeholder for size and offset of Private dictionary, which will be 5-byte integers. */
 
207
        WRF_wbyte(a_output,18); /* opcode for 'Private' */
 
208
        if (a_output->m_pos)
 
209
                {
 
210
                int last_offset = a_output->m_pos - data_start + 1;
 
211
                data_start[-2] = (unsigned char)(last_offset >> 8);
 
212
                data_start[-1] = (unsigned char)(last_offset & 0xFF);
 
213
                }
 
214
        }
 
215
 
 
216
/**
 
217
Write the character set. Return the number of characters.
 
218
For the moment this is always 1. The number cannot be obtained
 
219
via the FAPI interface, and FreeType doesn't need to know anything more
 
220
than the fact that there is at least one character.
 
221
*/
 
222
static int write_charset(WRF_output* a_output,unsigned char* a_charset_offset_ptr)
 
223
        {
 
224
        const int characters = 1;
 
225
        int i = 0;
 
226
 
 
227
        /* Write the offset to the start of the charset to the top dictionary. */
 
228
        if (a_output->m_pos)
 
229
                write_4_byte_int(a_charset_offset_ptr + 1,a_output->m_count);
 
230
 
 
231
        /*
 
232
        Write the charset. Write one less than the number of characters,
 
233
        because the first one is assumed to be .notdef. For the moment
 
234
        write all the others as .notdef (SID = 0) because we don't actually
 
235
        need the charset at the moment.
 
236
        */
 
237
        WRF_wbyte(a_output,0); /* format = 0 */
 
238
        for (i = 1; i < characters; i++)
 
239
                {
 
240
                WRF_wbyte(a_output,0);
 
241
                WRF_wbyte(a_output,0);
 
242
                }
 
243
 
 
244
        return characters;
 
245
        }
 
246
 
 
247
/**
 
248
Write a set of empty charstrings. The only reason for the existence of the charstrings index is to tell
 
249
FreeType how many glyphs there are.
 
250
*/
 
251
static void write_charstrings_index(WRF_output* a_output,int a_characters,unsigned char* a_charstrings_offset_ptr)
 
252
        {
 
253
        /* Write the offset to the charstrings index to the top dictionary. */
 
254
        if (a_output->m_pos)
 
255
                write_4_byte_int(a_charstrings_offset_ptr + 1,a_output->m_count);
 
256
 
 
257
        /* Write the index. */
 
258
        WRF_wbyte(a_output,(unsigned char)(a_characters >> 8));
 
259
        WRF_wbyte(a_output,(unsigned char)(a_characters & 0xFF));
 
260
        WRF_wbyte(a_output,1); /* offset size = 1. */
 
261
        while (a_characters-- >= 0)
 
262
                WRF_wbyte(a_output,1); /* offset = 1 */
 
263
        }
 
264
 
 
265
static void write_subrs_index(FAPI_font* a_fapi_font,WRF_output* a_output)
 
266
        {
 
267
        unsigned char* cur_offset = 0;
 
268
        unsigned char* data_start = 0;
 
269
        int i;
 
270
        int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
 
271
 
 
272
        WRF_wbyte(a_output,(unsigned char)(count >> 8));
 
273
        WRF_wbyte(a_output,(unsigned char)(count & 0xFF));
 
274
 
 
275
        if (count <= 0)
 
276
                return;
 
277
 
 
278
        WRF_wbyte(a_output,4); /* offset size = 4 bytes */
 
279
        WRF_wtext(a_output,(const unsigned char *)"\x0\x0\x0\x1",4); /* first offset = 1 */
 
280
 
 
281
        if (a_output->m_pos)
 
282
                cur_offset = a_output->m_pos;
 
283
 
 
284
        /* Write dummy bytes for the offsets at the end of each data item. */
 
285
        for (i = 0; i < count; i++)
 
286
                WRF_wtext(a_output,(const unsigned char *)"xxxx",4);
 
287
 
 
288
        if (a_output->m_pos)
 
289
                data_start = a_output->m_pos;
 
290
 
 
291
        for (i = 0; i < count; i++)
 
292
                {
 
293
                long buffer_size = a_output->m_limit - a_output->m_count;
 
294
                long length = a_fapi_font->get_subr(a_fapi_font,i,a_output->m_pos,(ushort)buffer_size);
 
295
                if (a_output->m_pos)
 
296
                        WRF_wtext(a_output,a_output->m_pos,length);
 
297
                else
 
298
                        a_output->m_count += length;
 
299
                if (cur_offset)
 
300
                        {
 
301
                        long pos = a_output->m_pos - data_start + 1;
 
302
                        write_4_byte_int(cur_offset,pos);
 
303
                        cur_offset += 4;
 
304
                        }
 
305
                }
 
306
        }
 
307
 
 
308
static void write_private_dict(FAPI_font* a_fapi_font,WRF_output* a_output,unsigned char* a_private_dict_length_ptr)
 
309
        {
 
310
        /* Write the offset to the start of the private dictionary to the top dictionary. */
 
311
        unsigned char* start = a_output->m_pos;
 
312
        if (a_output->m_pos)
 
313
                write_4_byte_int(a_private_dict_length_ptr + 6,a_output->m_count);
 
314
 
 
315
        write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueFuzz,1,true,11,16);
 
316
 
 
317
        write_type2_float(a_output,a_fapi_font->get_long(a_fapi_font,FAPI_FONT_FEATURE_BlueScale,0) / 65536.0);
 
318
        WRF_wbyte(a_output,12);
 
319
        WRF_wbyte(a_output,9);
 
320
        
 
321
        write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueShift,1,true,10,16);
 
322
        write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueValues,false,6,16);
 
323
        write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_OtherBlues,false,7,16);
 
324
        write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyBlues,false,8,16);
 
325
        write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyOtherBlues,false,9,16);
 
326
        write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_ForceBold,1,true,14,1);
 
327
        write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdHW,1,false,10,16);
 
328
        write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdVW,1,false,11,16);
 
329
        write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapH,true,12,16);
 
330
        write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapV,true,13,16);
 
331
 
 
332
        /*
 
333
        Write the default width and the nominal width. These values are not available via
 
334
        the FAPI interface so we have to get a pointer to the Type 1 font structure and
 
335
        extract them directly.
 
336
        */
 
337
        {
 
338
        gs_font_type1* t1 = (gs_font_type1*)a_fapi_font->client_font_data;
 
339
    write_type2_float(a_output,fixed2float(t1->data.defaultWidthX));
 
340
        WRF_wbyte(a_output,20);
 
341
    write_type2_float(a_output,fixed2float(t1->data.nominalWidthX));
 
342
        WRF_wbyte(a_output,21);
 
343
        }
 
344
 
 
345
        /* Write the length in bytes of the private dictionary to the top dictionary. */        
 
346
        if (a_output->m_pos)
 
347
                write_4_byte_int(a_private_dict_length_ptr + 1,a_output->m_pos - start);
 
348
        }
 
349
 
 
350
/**
 
351
Write a Type 2 font in binary format and return its length in bytes.
 
352
If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
 
353
length is returned correctly.
 
354
*/
 
355
long FF_serialize_type2_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size)
 
356
        {
 
357
        unsigned char* charset_offset_ptr = NULL;
 
358
        unsigned char* charstrings_offset_ptr = NULL;
 
359
        unsigned char* private_dict_length_ptr = NULL;
 
360
        int characters = 0;
 
361
 
 
362
        WRF_output output;
 
363
        WRF_init(&output,a_buffer,a_buffer_size);
 
364
 
 
365
        write_header(&output);
 
366
        write_name_index(&output);
 
367
        write_font_dict_index(a_fapi_font,&output,&charset_offset_ptr,&charstrings_offset_ptr,&private_dict_length_ptr);
 
368
 
 
369
        /* Write an empty string index. */
 
370
        WRF_wtext(&output,(const unsigned char *)"\x0\x0",2);
 
371
 
 
372
        write_subrs_index(a_fapi_font,&output);
 
373
        characters = write_charset(&output,charset_offset_ptr);
 
374
        write_charstrings_index(&output,characters,charstrings_offset_ptr);
 
375
        write_private_dict(a_fapi_font,&output,private_dict_length_ptr);
 
376
 
 
377
        return output.m_count;
 
378
        }