Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/base/write_t2.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
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
#include "stdpre.h"
22
#include "gzstate.h"
23
#include "wrfont.h"
24
#include "write_t2.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
34
write_4_byte_int(unsigned char *a_output, long a_int)
35
4.26M
{
36
4.26M
    a_output[0] = (unsigned char)(a_int >> 24);
37
4.26M
    a_output[1] = (unsigned char)(a_int >> 16);
38
4.26M
    a_output[2] = (unsigned char)(a_int >> 8);
39
4.26M
    a_output[3] = (unsigned char)(a_int & 0xFF);
40
4.26M
}
41
42
static void
43
write_type2_int(gs_fapi_font * a_fapi_font, WRF_output * a_output, long a_int)
44
586k
{
45
586k
    if (a_int >= -107 && a_int <= 107)
46
400k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int + 139));
47
185k
    else if (a_int >= -32768 && a_int <= 32767) {
48
185k
        if (a_int >= 108 && a_int <= 1131)
49
92.9k
            a_int += 63124;
50
92.3k
        else if (a_int >= -1131 && a_int <= -108)
51
72.1k
            a_int = -a_int + 64148;
52
20.2k
        else
53
20.2k
            WRF_wbyte(a_fapi_font->memory, a_output, 28);
54
185k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int >> 8));
55
185k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int & 0xFF));
56
185k
    } else {
57
0
        unsigned char buffer[4];
58
59
0
        WRF_wbyte(a_fapi_font->memory, a_output, 29);
60
0
        write_4_byte_int(buffer, a_int);
61
0
        WRF_wtext(a_fapi_font->memory, a_output, buffer, 4);
62
0
    }
63
586k
}
64
65
static void
66
write_type2_float(gs_fapi_font * a_fapi_font, WRF_output * a_output, float a_float)
67
244k
{
68
244k
    char buffer[32];
69
244k
    const char *p = buffer;
70
244k
    int high = true;
71
244k
    char c = 0;
72
73
244k
    gs_snprintf(buffer, sizeof(buffer), "%f", a_float);
74
244k
    WRF_wbyte(a_fapi_font->memory, a_output, 30);
75
2.25M
    for (;;) {
76
2.25M
        char n = 0;
77
78
2.25M
        if (*p >= '0' && *p <= '9')
79
1.76M
            n = (char)(*p - '0');
80
488k
        else if (*p == '.')
81
244k
            n = 0xA;
82
244k
        else if (*p == 'e' || *p == 'E') {
83
0
            if (p[1] == '-') {
84
0
                p++;
85
0
                n = 0xC;
86
0
            } else
87
0
                n = 0xB;
88
244k
        } else if (*p == '-')
89
242
            n = 0xE;
90
244k
        else if (*p == 0)
91
244k
            n = 0xF;
92
2.25M
        if (high) {
93
1.24M
            if (*p == 0)
94
240k
                WRF_wbyte(a_fapi_font->memory, a_output, 0xFF);
95
1.00M
            else
96
1.00M
                c = (char)(n << 4);
97
1.24M
        } else {
98
1.00M
            c |= n;
99
1.00M
            WRF_wbyte(a_fapi_font->memory, a_output, c);
100
1.00M
        }
101
102
2.25M
        if (*p == 0)
103
244k
            break;
104
105
2.01M
        high = !high;
106
2.01M
        p++;
107
2.01M
    }
108
244k
}
109
110
static void
111
write_header(gs_fapi_font * a_fapi_font, WRF_output * a_output)
112
27.1k
{
113
27.1k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1\x0\x4\x1", 4);
114
27.1k
}
115
116
static void
117
write_name_index(gs_fapi_font * a_fapi_font, WRF_output * a_output)
118
27.1k
{
119
    /* Write a dummy name of 'x'. */
120
27.1k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x1\x1\x1\x2" "x", 6);
121
27.1k
}
122
123
static int
124
write_word_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
125
                 int a_feature_id, int a_feature_count, bool a_two_byte_op,
126
                 int a_op, int a_divisor)
127
162k
{
128
162k
    int code = 0;
129
130
162k
    if (a_feature_count > 0) {
131
162k
        int i;
132
133
406k
        for (i = 0; i < a_feature_count; i++) {
134
            /* Get the value and convert it from unsigned to signed. */
135
244k
            short x;
136
244k
            code = a_fapi_font->get_word(a_fapi_font, a_feature_id, i, (unsigned short *)&x);
137
244k
            if (code < 0)
138
0
                return code;
139
140
            /* Divide by the divisor to bring it back to font units. */
141
244k
            x = (short)(x / a_divisor);
142
244k
            write_type2_int(a_fapi_font, a_output, x);
143
244k
        }
144
162k
        if (a_two_byte_op)
145
81.3k
            WRF_wbyte(a_fapi_font->memory, a_output, 12);
146
162k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op);
147
162k
    }
148
162k
    return code;
149
162k
}
150
151
static int
152
write_delta_array_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
153
                        int a_feature_id, bool a_two_byte_op, int a_op,
154
                        int a_divisor)
155
162k
{
156
162k
    int i, code;
157
158
    /* NOTE that the feature index (a_feature_id) must be preceded by the count index for this to work. */
159
162k
    unsigned short count;
160
161
162k
    code = a_fapi_font->get_word(a_fapi_font, a_feature_id - 1, 0, &count);
162
163
162k
    if (code >= 0 && count > 0) {
164
61.7k
        short prev_value = 0;
165
166
375k
        for (i = 0; i < count; i++) {
167
            /* Get the value and convert it from unsigned to signed. */
168
313k
            short value;
169
313k
            code = a_fapi_font->get_word(a_fapi_font, a_feature_id, i, (unsigned short *)&value);
170
313k
            if (code < 0)
171
0
                return code;
172
173
            /* Divide by the divisor to bring it back to font units. */
174
313k
            value = (short)(value / a_divisor);
175
313k
            write_type2_int(a_fapi_font, a_output, value - prev_value);
176
313k
            prev_value = value;
177
313k
        }
178
61.7k
        if (a_two_byte_op)
179
19.6k
            WRF_wbyte(a_fapi_font->memory, a_output, 12);
180
61.7k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op);
181
61.7k
    }
182
162k
    return code;
183
162k
}
184
185
static int
186
write_float_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
187
                  int a_feature_id, int a_feature_count, bool a_two_byte_op,
188
                  int a_op)
189
27.1k
{
190
27.1k
    if (a_feature_count > 0) {
191
27.1k
        int i, code;
192
27.1k
        float x;
193
194
189k
        for (i = 0; i < a_feature_count; i++) {
195
162k
            code = a_fapi_font->get_float(a_fapi_font, a_feature_id, i, &x);
196
162k
            if (code < 0)
197
0
                return code;
198
199
162k
            write_type2_float(a_fapi_font, a_output, x);
200
162k
        }
201
27.1k
        if (a_two_byte_op)
202
27.1k
            WRF_wbyte(a_fapi_font->memory, a_output, 12);
203
27.1k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op);
204
27.1k
    }
205
27.1k
    return 0;
206
27.1k
}
207
208
static int
209
write_font_dict_index(gs_fapi_font * a_fapi_font, WRF_output * a_output,
210
                      unsigned char **a_charset_offset_ptr,
211
                      unsigned char **a_charstrings_offset_ptr,
212
                      unsigned char **a_private_dict_length_ptr)
213
27.1k
{
214
27.1k
    unsigned char *data_start = 0;
215
27.1k
    int code;
216
217
27.1k
    WRF_wtext(a_fapi_font->memory, 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). */
218
27.1k
    if (a_output->m_pos)
219
13.5k
        data_start = a_output->m_pos;
220
27.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontBBox, 4, false, 5, 1);
221
27.1k
    if (code < 0)
222
0
        return code;
223
224
27.1k
    code = write_float_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontMatrix, 6, true, 7);
225
27.1k
    if (code < 0)
226
0
        return code;
227
228
27.1k
    write_type2_int(a_fapi_font, a_output, 0);       /* 0 = Standard Encoding. */
229
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 16);    /* 16 = opcode for 'encoding'. */
230
27.1k
    *a_charset_offset_ptr = a_output->m_pos;
231
27.1k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx", 5);       /* placeholder for the offset to the charset, which will be a 5-byte integer. */
232
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 15);    /* opcode for 'charset' */
233
27.1k
    *a_charstrings_offset_ptr = a_output->m_pos;
234
27.1k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx", 5);       /* placeholder for the offset to the Charstrings index, which will be a 5-byte integer. */
235
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 17);    /* opcode for 'Charstrings' */
236
27.1k
    *a_private_dict_length_ptr = a_output->m_pos;
237
27.1k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx\x1d" "yyyy", 10);   /* placeholder for size and offset of Private dictionary, which will be 5-byte integers. */
238
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 18);    /* opcode for 'Private' */
239
27.1k
    if (a_output->m_pos) {
240
13.5k
        int last_offset = a_output->m_pos - data_start + 1;
241
242
13.5k
        data_start[-2] = (unsigned char)(last_offset >> 8);
243
13.5k
        data_start[-1] = (unsigned char)(last_offset & 0xFF);
244
13.5k
    }
245
27.1k
    return 0;
246
27.1k
}
247
248
/**
249
Write the character set. Return the number of characters.
250
For the moment this is always 1. The number cannot be obtained
251
via the FAPI interface, and FreeType doesn't need to know anything more
252
than the fact that there is at least one character.
253
*/
254
static int
255
write_charset(gs_fapi_font * a_fapi_font, WRF_output * a_output, unsigned char *a_charset_offset_ptr)
256
27.1k
{
257
27.1k
    const int characters = 2; /* .notdef + one other */
258
27.1k
    int i = 0;
259
260
    /* Write the offset to the start of the charset to the top dictionary. */
261
27.1k
    if (a_output->m_pos) {
262
13.5k
        write_4_byte_int(a_charset_offset_ptr + 1, a_output->m_count);
263
13.5k
    }
264
    /*
265
       Write the charset. Write one less than the number of characters,
266
       because the first one is assumed to be .notdef. For the moment
267
       write all the others as .notdef (SID = 0) because we don't actually
268
       need the charset at the moment.
269
     */
270
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 0);     /* format = 0 */
271
54.2k
    for (i = 1; i < characters; i++) {
272
27.1k
        WRF_wbyte(a_fapi_font->memory, a_output, 0);
273
27.1k
        WRF_wbyte(a_fapi_font->memory, a_output, 0);
274
27.1k
    }
275
276
27.1k
    return characters;
277
27.1k
}
278
279
/**
280
Write a set of empty charstrings. The only reason for the existence of the charstrings index is to tell
281
FreeType how many glyphs there are.
282
*/
283
static void
284
write_charstrings_index(gs_fapi_font * a_fapi_font, WRF_output * a_output, int a_characters,
285
                        unsigned char *a_charstrings_offset_ptr)
286
27.1k
{
287
    /* Write the offset to the charstrings index to the top dictionary. */
288
27.1k
    if (a_output->m_pos) {
289
13.5k
        write_4_byte_int(a_charstrings_offset_ptr + 1, a_output->m_count);
290
13.5k
    }
291
292
    /* Write the index. */
293
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_characters >> 8));
294
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_characters & 0xFF));
295
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 1);     /* offset size = 1. */
296
108k
    while (a_characters-- >= 0)
297
81.3k
        WRF_wbyte(a_fapi_font->memory, a_output, 1); /* offset = 1 */
298
27.1k
}
299
300
static int
301
write_gsubrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output)
302
27.1k
{
303
27.1k
    unsigned char *cur_offset = 0;
304
27.1k
    unsigned char *data_start = 0;
305
27.1k
    int i;
306
27.1k
    unsigned short count;
307
27.1k
    int code = a_fapi_font->get_word(a_fapi_font,
308
27.1k
                                      gs_fapi_font_feature_GlobalSubrs_count,
309
27.1k
                                      0, &count);
310
311
27.1k
    if (code < 0)
312
0
        return code;
313
314
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count >> 8));
315
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count & 0xFF));
316
317
27.1k
    if (count <= 0)
318
24.1k
        return 0;
319
320
3.01k
    WRF_wbyte(a_fapi_font->memory, a_output, 4);     /* offset size = 4 bytes */
321
3.01k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x0\x0\x1", 4);      /* first offset = 1 */
322
323
3.01k
    if (a_output->m_pos)
324
1.47k
        cur_offset = a_output->m_pos;
325
326
    /* Write dummy bytes for the offsets at the end of each data item. */
327
8.33M
    for (i = 0; i < count; i++)
328
8.32M
        WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"xxxx", 4);
329
330
3.01k
    if (a_output->m_pos)
331
1.47k
        data_start = a_output->m_pos;
332
333
8.31M
    for (i = 0; i < count; i++) {
334
8.30M
        long buffer_size = a_output->m_limit - a_output->m_count < 0 ? 0 : a_output->m_limit - a_output->m_count;
335
8.30M
        int length = a_fapi_font->get_gsubr(a_fapi_font, i, a_output->m_pos, buffer_size);
336
337
8.30M
        if (length < 0)
338
104
            return length;
339
340
8.30M
        if (a_output->m_pos)
341
4.14M
            a_output->m_pos += length;
342
343
8.30M
        a_output->m_count += length;
344
8.30M
        if (cur_offset) {
345
4.14M
            long pos = a_output->m_pos - data_start + 1;
346
347
4.14M
            write_4_byte_int(cur_offset, pos);
348
4.14M
            cur_offset += 4;
349
4.14M
        }
350
8.30M
    }
351
2.91k
    return 0;
352
3.01k
}
353
354
static int
355
write_subrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output)
356
27.1k
{
357
27.1k
    unsigned char *cur_offset = 0;
358
27.1k
    unsigned char *data_start = 0;
359
27.1k
    int i;
360
27.1k
    unsigned short count;
361
27.1k
    int code =
362
27.1k
        a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
363
27.1k
                              0, &count);
364
365
27.1k
    if (code < 0)
366
0
        return code;
367
368
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count >> 8));
369
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count & 0xFF));
370
371
27.1k
    if (count <= 0)
372
26.2k
        return 0;
373
374
890
    WRF_wbyte(a_fapi_font->memory, a_output, 4);     /* offset size = 4 bytes */
375
890
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x0\x0\x1", 4);      /* first offset = 1 */
376
377
890
    if (a_output->m_pos)
378
410
        cur_offset = a_output->m_pos;
379
380
    /* Write dummy bytes for the offsets at the end of each data item. */
381
157k
    for (i = 0; i < count; i++)
382
156k
        WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"xxxx", 4);
383
384
890
    if (a_output->m_pos)
385
410
        data_start = a_output->m_pos;
386
387
144k
    for (i = 0; i < count; i++) {
388
143k
        long buffer_size = a_output->m_limit - a_output->m_count;
389
143k
        int length = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos, buffer_size);
390
391
143k
        if (length < 0)
392
70
            return length;
393
394
143k
        if (a_output->m_pos)
395
69.5k
            a_output->m_pos += length;
396
397
143k
        a_output->m_count += length;
398
143k
        if (cur_offset) {
399
69.5k
            long pos = a_output->m_pos - data_start + 1;
400
401
69.5k
            write_4_byte_int(cur_offset, pos);
402
69.5k
            cur_offset += 4;
403
69.5k
        }
404
143k
    }
405
820
    return 0;
406
890
}
407
408
static int
409
write_private_dict(gs_fapi_font * a_fapi_font, WRF_output * a_output,
410
                   unsigned char *a_private_dict_length_ptr)
411
27.1k
{
412
27.1k
    int code, initial = a_output->m_count;
413
27.1k
    unsigned short count;
414
    /* Write the offset to the start of the private dictionary to the top dictionary. */
415
27.1k
    unsigned char *start = a_output->m_pos;
416
27.1k
    unsigned long lval;
417
27.1k
    gs_font_type1 *t1 = (gs_font_type1 *) a_fapi_font->client_font_data;
418
419
27.1k
    if (a_output->m_pos)
420
13.5k
        write_4_byte_int(a_private_dict_length_ptr + 6, a_output->m_count);
421
422
27.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueFuzz, 1,
423
27.1k
                     true, 11, 16);
424
27.1k
    if (code < 0)
425
0
        return code;
426
27.1k
    code = a_fapi_font->get_long(a_fapi_font, gs_fapi_font_feature_BlueScale, 0, &lval);
427
27.1k
    if (code < 0)
428
0
        return code;
429
430
27.1k
    write_type2_float(a_fapi_font, a_output, (float)((double)lval/65536.0));
431
432
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 12);
433
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 9);
434
435
27.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueShift, 1,
436
27.1k
                     true, 10, 16);
437
27.1k
    if (code < 0)
438
0
        return code;
439
440
27.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
441
27.1k
                            gs_fapi_font_feature_BlueValues, false, 6, 16);
442
27.1k
    if (code < 0)
443
0
        return code;
444
445
27.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
446
27.1k
                            gs_fapi_font_feature_OtherBlues, false, 7, 16);
447
27.1k
    if (code < 0)
448
0
        return code;
449
450
27.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
451
27.1k
                            gs_fapi_font_feature_FamilyBlues, false, 8, 16);
452
27.1k
    if (code < 0)
453
0
        return code;
454
455
27.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
456
27.1k
                            gs_fapi_font_feature_FamilyOtherBlues, false, 9,
457
27.1k
                            16);
458
27.1k
    if (code < 0)
459
0
        return code;
460
461
27.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_ForceBold, 1,
462
27.1k
                     true, 14, 1);
463
27.1k
    if (code < 0)
464
0
        return code;
465
466
27.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_StdHW, 1,
467
27.1k
                     false, 10, 16);
468
27.1k
    if (code < 0)
469
0
        return code;
470
471
27.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_StdVW, 1,
472
27.1k
                     false, 11, 16);
473
27.1k
    if (code < 0)
474
0
        return code;
475
476
27.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
477
27.1k
                            gs_fapi_font_feature_StemSnapH, true, 12, 16);
478
27.1k
    if (code < 0)
479
0
        return code;
480
481
27.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
482
27.1k
                            gs_fapi_font_feature_StemSnapV, true, 13, 16);
483
27.1k
    if (code < 0)
484
0
        return code;
485
486
    /*
487
       Write the default width and the nominal width. These values are not available via
488
       the FAPI interface so we have to get a pointer to the Type 1 font structure and
489
       extract them directly.
490
     */
491
27.1k
    write_type2_float(a_fapi_font, a_output, fixed2float(t1->data.defaultWidthX));
492
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 20);
493
494
27.1k
    write_type2_float(a_fapi_font, a_output, fixed2float(t1->data.nominalWidthX));
495
27.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 21);
496
497
27.1k
    code =
498
27.1k
        a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
499
27.1k
                              0, &count);
500
27.1k
    if (code < 0)
501
0
        return code;
502
503
    /* If we have local /Subrs we need to make a new dict ( see calling routine) and
504
     * we also need to add an entry to the Provate dict with an offset to the /Subrs
505
     * dict. This is complicated by the fact that the offset includes the data for
506
     * the offset (its contained in the Private dict) and the size of the data depends
507
     * on its value (because of number representation).
508
     */
509
27.1k
    if (count) {
510
890
        int n = 1, n1;
511
512
924
        do {
513
924
            n1 = a_output->m_count - initial + 1 + n;   /* one for the operator, plus the size needed for the representation */
514
924
            switch (n) {
515
890
                case 1:
516
890
                    if (n1 >= -107 && n1 <= 107) {
517
856
                        write_type2_int(a_fapi_font, a_output, n1);
518
856
                        n = 5;
519
856
                    }
520
890
                    break;
521
34
                case 2:
522
34
                    if ((n1 >= 108 && n1 <= 1131)
523
34
                        || (n1 >= -1131 && n1 <= -108)) {
524
34
                        write_type2_int(a_fapi_font, a_output, n1);
525
34
                        n = 5;
526
34
                    }
527
34
                    break;
528
0
                case 3:
529
0
                    if (n1 >= -32768 && n1 <= 32767) {
530
0
                        write_type2_int(a_fapi_font, a_output, n1);
531
0
                        n = 5;
532
0
                    }
533
0
                    break;
534
0
                case 4:
535
0
                    break;
536
0
                case 5:
537
0
                    write_type2_int(a_fapi_font, a_output, n1);
538
0
                    break;
539
924
            }
540
924
            n++;
541
924
        }
542
924
        while (n < 5);
543
544
890
        WRF_wbyte(a_fapi_font->memory, a_output, 19);
545
890
    }
546
547
    /* Write the length in bytes of the private dictionary to the top dictionary. */
548
27.1k
    if (a_output->m_pos)
549
13.5k
        write_4_byte_int(a_private_dict_length_ptr + 1,
550
13.5k
                         a_output->m_pos - start);
551
27.1k
    return 0;
552
27.1k
}
553
554
/**
555
Write a Type 2 font in binary format and return its length in bytes.
556
If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
557
length is returned correctly.
558
*/
559
long
560
gs_fapi_serialize_type2_font(gs_fapi_font * a_fapi_font,
561
                             unsigned char *a_buffer, long a_buffer_size)
562
27.1k
{
563
27.1k
    unsigned char *charset_offset_ptr = NULL;
564
27.1k
    unsigned char *charstrings_offset_ptr = NULL;
565
27.1k
    unsigned char *private_dict_length_ptr = NULL;
566
27.1k
    int characters = 0;
567
27.1k
    int code;
568
569
27.1k
    WRF_output output;
570
571
27.1k
    WRF_init(&output, a_buffer, a_buffer_size);
572
573
27.1k
    write_header(a_fapi_font, &output);
574
27.1k
    write_name_index(a_fapi_font, &output);
575
27.1k
    code = write_font_dict_index(a_fapi_font, &output, &charset_offset_ptr,
576
27.1k
                          &charstrings_offset_ptr, &private_dict_length_ptr);
577
27.1k
    if (code < 0)
578
0
        return (long)code;
579
580
    /* Write an empty string index. */
581
27.1k
    WRF_wtext(a_fapi_font->memory, &output, (const unsigned char *)"\x0\x0", 2);
582
583
27.1k
    write_gsubrs_index(a_fapi_font, &output);
584
27.1k
    code = characters = write_charset(a_fapi_font, &output, charset_offset_ptr);
585
27.1k
    if (code < 0)
586
0
        return (long)code;
587
588
27.1k
    write_charstrings_index(a_fapi_font, &output, characters, charstrings_offset_ptr);
589
590
27.1k
    code = write_private_dict(a_fapi_font, &output, private_dict_length_ptr);
591
27.1k
    if (code < 0)
592
0
        return (long)code;
593
594
27.1k
    code = write_subrs_index(a_fapi_font, &output);
595
596
27.1k
    if (code < 0)
597
70
        return (long)code;
598
599
27.0k
    return output.m_count;
600
27.1k
}