Coverage Report

Created: 2026-07-24 07:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/write_t2.c
Line
Count
Source
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.62M
{
36
4.62M
    a_output[0] = (unsigned char)(a_int >> 24);
37
4.62M
    a_output[1] = (unsigned char)(a_int >> 16);
38
4.62M
    a_output[2] = (unsigned char)(a_int >> 8);
39
4.62M
    a_output[3] = (unsigned char)(a_int & 0xFF);
40
4.62M
}
41
42
static void
43
write_type2_int(gs_fapi_font * a_fapi_font, WRF_output * a_output, long a_int)
44
420k
{
45
420k
    if (a_int >= -107 && a_int <= 107)
46
290k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int + 139));
47
130k
    else if (a_int >= -32768 && a_int <= 32767) {
48
130k
        if (a_int >= 108 && a_int <= 1131)
49
63.5k
            a_int += 63124;
50
66.5k
        else if (a_int >= -1131 && a_int <= -108)
51
49.4k
            a_int = -a_int + 64148;
52
17.1k
        else
53
17.1k
            WRF_wbyte(a_fapi_font->memory, a_output, 28);
54
130k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int >> 8));
55
130k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int & 0xFF));
56
130k
    } 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
420k
}
64
65
static void
66
write_type2_float(gs_fapi_font * a_fapi_font, WRF_output * a_output, float a_float)
67
190k
{
68
190k
    char buffer[32];
69
190k
    const char *p = buffer;
70
190k
    int high = true;
71
190k
    char c = 0;
72
73
190k
    gs_snprintf(buffer, sizeof(buffer), "%f", a_float);
74
190k
    WRF_wbyte(a_fapi_font->memory, a_output, 30);
75
1.75M
    for (;;) {
76
1.75M
        char n = 0;
77
78
1.75M
        if (*p >= '0' && *p <= '9')
79
1.37M
            n = (char)(*p - '0');
80
380k
        else if (*p == '.')
81
190k
            n = 0xA;
82
190k
        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
190k
        } else if (*p == '-')
89
228
            n = 0xE;
90
190k
        else if (*p == 0)
91
190k
            n = 0xF;
92
1.75M
        if (high) {
93
970k
            if (*p == 0)
94
187k
                WRF_wbyte(a_fapi_font->memory, a_output, 0xFF);
95
783k
            else
96
783k
                c = (char)(n << 4);
97
970k
        } else {
98
783k
            c |= n;
99
783k
            WRF_wbyte(a_fapi_font->memory, a_output, c);
100
783k
        }
101
102
1.75M
        if (*p == 0)
103
190k
            break;
104
105
1.56M
        high = !high;
106
1.56M
        p++;
107
1.56M
    }
108
190k
}
109
110
static void
111
write_header(gs_fapi_font * a_fapi_font, WRF_output * a_output)
112
21.1k
{
113
21.1k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1\x0\x4\x1", 4);
114
21.1k
}
115
116
static void
117
write_name_index(gs_fapi_font * a_fapi_font, WRF_output * a_output)
118
21.1k
{
119
    /* Write a dummy name of 'x'. */
120
21.1k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x1\x1\x1\x2" "x", 6);
121
21.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
126k
{
128
126k
    int code = 0;
129
130
126k
    if (a_feature_count > 0) {
131
126k
        int i;
132
133
316k
        for (i = 0; i < a_feature_count; i++) {
134
            /* Get the value and convert it from unsigned to signed. */
135
190k
            short x;
136
190k
            code = a_fapi_font->get_word(a_fapi_font, a_feature_id, i, (unsigned short *)&x);
137
190k
            if (code < 0)
138
0
                return code;
139
140
            /* Divide by the divisor to bring it back to font units. */
141
190k
            x = (short)(x / a_divisor);
142
190k
            write_type2_int(a_fapi_font, a_output, x);
143
190k
        }
144
126k
        if (a_two_byte_op)
145
63.3k
            WRF_wbyte(a_fapi_font->memory, a_output, 12);
146
126k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op);
147
126k
    }
148
126k
    return code;
149
126k
}
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
126k
{
156
126k
    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
126k
    unsigned short count;
160
161
126k
    code = a_fapi_font->get_word(a_fapi_font, a_feature_id - 1, 0, &count);
162
163
126k
    if (code >= 0 && count > 0) {
164
42.4k
        short prev_value = 0;
165
166
250k
        for (i = 0; i < count; i++) {
167
            /* Get the value and convert it from unsigned to signed. */
168
208k
            short value;
169
208k
            code = a_fapi_font->get_word(a_fapi_font, a_feature_id, i, (unsigned short *)&value);
170
208k
            if (code < 0)
171
0
                return code;
172
173
            /* Divide by the divisor to bring it back to font units. */
174
208k
            value = (short)(value / a_divisor);
175
208k
            write_type2_int(a_fapi_font, a_output, value - prev_value);
176
208k
            prev_value = value;
177
208k
        }
178
42.4k
        if (a_two_byte_op)
179
14.5k
            WRF_wbyte(a_fapi_font->memory, a_output, 12);
180
42.4k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op);
181
42.4k
    }
182
126k
    return code;
183
126k
}
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
21.1k
{
190
21.1k
    if (a_feature_count > 0) {
191
21.1k
        int i, code;
192
21.1k
        float x;
193
194
147k
        for (i = 0; i < a_feature_count; i++) {
195
126k
            code = a_fapi_font->get_float(a_fapi_font, a_feature_id, i, &x);
196
126k
            if (code < 0)
197
0
                return code;
198
199
126k
            write_type2_float(a_fapi_font, a_output, x);
200
126k
        }
201
21.1k
        if (a_two_byte_op)
202
21.1k
            WRF_wbyte(a_fapi_font->memory, a_output, 12);
203
21.1k
        WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op);
204
21.1k
    }
205
21.1k
    return 0;
206
21.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
21.1k
{
214
21.1k
    unsigned char *data_start = 0;
215
21.1k
    int code;
216
217
21.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
21.1k
    if (a_output->m_pos)
219
10.5k
        data_start = a_output->m_pos;
220
21.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontBBox, 4, false, 5, 1);
221
21.1k
    if (code < 0)
222
0
        return code;
223
224
21.1k
    code = write_float_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontMatrix, 6, true, 7);
225
21.1k
    if (code < 0)
226
0
        return code;
227
228
21.1k
    write_type2_int(a_fapi_font, a_output, 0);       /* 0 = Standard Encoding. */
229
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 16);    /* 16 = opcode for 'encoding'. */
230
21.1k
    *a_charset_offset_ptr = a_output->m_pos;
231
21.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
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 15);    /* opcode for 'charset' */
233
21.1k
    *a_charstrings_offset_ptr = a_output->m_pos;
234
21.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
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 17);    /* opcode for 'Charstrings' */
236
21.1k
    *a_private_dict_length_ptr = a_output->m_pos;
237
21.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
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 18);    /* opcode for 'Private' */
239
21.1k
    if (a_output->m_pos) {
240
10.5k
        int last_offset = a_output->m_pos - data_start + 1;
241
242
10.5k
        data_start[-2] = (unsigned char)(last_offset >> 8);
243
10.5k
        data_start[-1] = (unsigned char)(last_offset & 0xFF);
244
10.5k
    }
245
21.1k
    return 0;
246
21.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
21.1k
{
257
21.1k
    const int characters = 2; /* .notdef + one other */
258
21.1k
    int i = 0;
259
260
    /* Write the offset to the start of the charset to the top dictionary. */
261
21.1k
    if (a_output->m_pos) {
262
10.5k
        write_4_byte_int(a_charset_offset_ptr + 1, a_output->m_count);
263
10.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
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 0);     /* format = 0 */
271
42.2k
    for (i = 1; i < characters; i++) {
272
21.1k
        WRF_wbyte(a_fapi_font->memory, a_output, 0);
273
21.1k
        WRF_wbyte(a_fapi_font->memory, a_output, 0);
274
21.1k
    }
275
276
21.1k
    return characters;
277
21.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
21.1k
{
287
    /* Write the offset to the charstrings index to the top dictionary. */
288
21.1k
    if (a_output->m_pos) {
289
10.5k
        write_4_byte_int(a_charstrings_offset_ptr + 1, a_output->m_count);
290
10.5k
    }
291
292
    /* Write the index. */
293
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_characters >> 8));
294
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_characters & 0xFF));
295
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 1);     /* offset size = 1. */
296
84.4k
    while (a_characters-- >= 0)
297
63.3k
        WRF_wbyte(a_fapi_font->memory, a_output, 1); /* offset = 1 */
298
21.1k
}
299
300
static int
301
write_gsubrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output)
302
21.1k
{
303
21.1k
    unsigned char *cur_offset = 0;
304
21.1k
    unsigned char *data_start = 0;
305
21.1k
    int i;
306
21.1k
    unsigned short count;
307
21.1k
    int code = a_fapi_font->get_word(a_fapi_font,
308
21.1k
                                      gs_fapi_font_feature_GlobalSubrs_count,
309
21.1k
                                      0, &count);
310
311
21.1k
    if (code < 0)
312
0
        return code;
313
314
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count >> 8));
315
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count & 0xFF));
316
317
21.1k
    if (count <= 0)
318
17.9k
        return 0;
319
320
3.13k
    WRF_wbyte(a_fapi_font->memory, a_output, 4);     /* offset size = 4 bytes */
321
3.13k
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x0\x0\x1", 4);      /* first offset = 1 */
322
323
3.13k
    if (a_output->m_pos)
324
1.53k
        cur_offset = a_output->m_pos;
325
326
    /* Write dummy bytes for the offsets at the end of each data item. */
327
9.06M
    for (i = 0; i < count; i++)
328
9.06M
        WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"xxxx", 4);
329
330
3.13k
    if (a_output->m_pos)
331
1.53k
        data_start = a_output->m_pos;
332
333
9.04M
    for (i = 0; i < count; i++) {
334
9.03M
        long buffer_size = a_output->m_limit - a_output->m_count < 0 ? 0 : a_output->m_limit - a_output->m_count;
335
9.03M
        int length = a_fapi_font->get_gsubr(a_fapi_font, i, a_output->m_pos, buffer_size);
336
337
9.03M
        if (length < 0)
338
114
            return length;
339
340
9.03M
        if (a_output->m_pos)
341
4.51M
            a_output->m_pos += length;
342
343
9.03M
        a_output->m_count += length;
344
9.03M
        if (cur_offset) {
345
4.51M
            long pos = a_output->m_pos - data_start + 1;
346
347
4.51M
            write_4_byte_int(cur_offset, pos);
348
4.51M
            cur_offset += 4;
349
4.51M
        }
350
9.03M
    }
351
3.02k
    return 0;
352
3.13k
}
353
354
static int
355
write_subrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output)
356
21.1k
{
357
21.1k
    unsigned char *cur_offset = 0;
358
21.1k
    unsigned char *data_start = 0;
359
21.1k
    int i;
360
21.1k
    unsigned short count;
361
21.1k
    int code =
362
21.1k
        a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
363
21.1k
                              0, &count);
364
365
21.1k
    if (code < 0)
366
0
        return code;
367
368
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count >> 8));
369
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count & 0xFF));
370
371
21.1k
    if (count <= 0)
372
20.3k
        return 0;
373
374
814
    WRF_wbyte(a_fapi_font->memory, a_output, 4);     /* offset size = 4 bytes */
375
814
    WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x0\x0\x1", 4);      /* first offset = 1 */
376
377
814
    if (a_output->m_pos)
378
378
        cur_offset = a_output->m_pos;
379
380
    /* Write dummy bytes for the offsets at the end of each data item. */
381
151k
    for (i = 0; i < count; i++)
382
151k
        WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"xxxx", 4);
383
384
814
    if (a_output->m_pos)
385
378
        data_start = a_output->m_pos;
386
387
141k
    for (i = 0; i < count; i++) {
388
140k
        long buffer_size = a_output->m_limit - a_output->m_count;
389
140k
        int length = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos, buffer_size);
390
391
140k
        if (length < 0)
392
58
            return length;
393
394
140k
        if (a_output->m_pos)
395
68.6k
            a_output->m_pos += length;
396
397
140k
        a_output->m_count += length;
398
140k
        if (cur_offset) {
399
68.6k
            long pos = a_output->m_pos - data_start + 1;
400
401
68.6k
            write_4_byte_int(cur_offset, pos);
402
68.6k
            cur_offset += 4;
403
68.6k
        }
404
140k
    }
405
756
    return 0;
406
814
}
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
21.1k
{
412
21.1k
    int code, initial = a_output->m_count;
413
21.1k
    unsigned short count;
414
    /* Write the offset to the start of the private dictionary to the top dictionary. */
415
21.1k
    unsigned char *start = a_output->m_pos;
416
21.1k
    unsigned long lval;
417
21.1k
    gs_font_type1 *t1 = (gs_font_type1 *) a_fapi_font->client_font_data;
418
419
21.1k
    if (a_output->m_pos)
420
10.5k
        write_4_byte_int(a_private_dict_length_ptr + 6, a_output->m_count);
421
422
21.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueFuzz, 1,
423
21.1k
                     true, 11, 16);
424
21.1k
    if (code < 0)
425
0
        return code;
426
21.1k
    code = a_fapi_font->get_long(a_fapi_font, gs_fapi_font_feature_BlueScale, 0, &lval);
427
21.1k
    if (code < 0)
428
0
        return code;
429
430
21.1k
    write_type2_float(a_fapi_font, a_output, (float)((double)lval/65536.0));
431
432
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 12);
433
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 9);
434
435
21.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueShift, 1,
436
21.1k
                     true, 10, 16);
437
21.1k
    if (code < 0)
438
0
        return code;
439
440
21.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
441
21.1k
                            gs_fapi_font_feature_BlueValues, false, 6, 16);
442
21.1k
    if (code < 0)
443
0
        return code;
444
445
21.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
446
21.1k
                            gs_fapi_font_feature_OtherBlues, false, 7, 16);
447
21.1k
    if (code < 0)
448
0
        return code;
449
450
21.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
451
21.1k
                            gs_fapi_font_feature_FamilyBlues, false, 8, 16);
452
21.1k
    if (code < 0)
453
0
        return code;
454
455
21.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
456
21.1k
                            gs_fapi_font_feature_FamilyOtherBlues, false, 9,
457
21.1k
                            16);
458
21.1k
    if (code < 0)
459
0
        return code;
460
461
21.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_ForceBold, 1,
462
21.1k
                     true, 14, 1);
463
21.1k
    if (code < 0)
464
0
        return code;
465
466
21.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_StdHW, 1,
467
21.1k
                     false, 10, 16);
468
21.1k
    if (code < 0)
469
0
        return code;
470
471
21.1k
    code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_StdVW, 1,
472
21.1k
                     false, 11, 16);
473
21.1k
    if (code < 0)
474
0
        return code;
475
476
21.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
477
21.1k
                            gs_fapi_font_feature_StemSnapH, true, 12, 16);
478
21.1k
    if (code < 0)
479
0
        return code;
480
481
21.1k
    code = write_delta_array_entry(a_fapi_font, a_output,
482
21.1k
                            gs_fapi_font_feature_StemSnapV, true, 13, 16);
483
21.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
21.1k
    write_type2_float(a_fapi_font, a_output, fixed2float(t1->data.defaultWidthX));
492
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 20);
493
494
21.1k
    write_type2_float(a_fapi_font, a_output, fixed2float(t1->data.nominalWidthX));
495
21.1k
    WRF_wbyte(a_fapi_font->memory, a_output, 21);
496
497
21.1k
    code =
498
21.1k
        a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
499
21.1k
                              0, &count);
500
21.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
21.1k
    if (count) {
510
814
        int n = 1, n1;
511
512
850
        do {
513
850
            n1 = a_output->m_count - initial + 1 + n;   /* one for the operator, plus the size needed for the representation */
514
850
            switch (n) {
515
814
                case 1:
516
814
                    if (n1 >= -107 && n1 <= 107) {
517
778
                        write_type2_int(a_fapi_font, a_output, n1);
518
778
                        n = 5;
519
778
                    }
520
814
                    break;
521
36
                case 2:
522
36
                    if ((n1 >= 108 && n1 <= 1131)
523
36
                        || (n1 >= -1131 && n1 <= -108)) {
524
36
                        write_type2_int(a_fapi_font, a_output, n1);
525
36
                        n = 5;
526
36
                    }
527
36
                    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
850
            }
540
850
            n++;
541
850
        }
542
850
        while (n < 5);
543
544
814
        WRF_wbyte(a_fapi_font->memory, a_output, 19);
545
814
    }
546
547
    /* Write the length in bytes of the private dictionary to the top dictionary. */
548
21.1k
    if (a_output->m_pos)
549
10.5k
        write_4_byte_int(a_private_dict_length_ptr + 1,
550
10.5k
                         a_output->m_pos - start);
551
21.1k
    return 0;
552
21.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
21.1k
{
563
21.1k
    unsigned char *charset_offset_ptr = NULL;
564
21.1k
    unsigned char *charstrings_offset_ptr = NULL;
565
21.1k
    unsigned char *private_dict_length_ptr = NULL;
566
21.1k
    int characters = 0;
567
21.1k
    int code;
568
569
21.1k
    WRF_output output;
570
571
21.1k
    WRF_init(&output, a_buffer, a_buffer_size);
572
573
21.1k
    write_header(a_fapi_font, &output);
574
21.1k
    write_name_index(a_fapi_font, &output);
575
21.1k
    code = write_font_dict_index(a_fapi_font, &output, &charset_offset_ptr,
576
21.1k
                          &charstrings_offset_ptr, &private_dict_length_ptr);
577
21.1k
    if (code < 0)
578
0
        return (long)code;
579
580
    /* Write an empty string index. */
581
21.1k
    WRF_wtext(a_fapi_font->memory, &output, (const unsigned char *)"\x0\x0", 2);
582
583
21.1k
    write_gsubrs_index(a_fapi_font, &output);
584
21.1k
    code = characters = write_charset(a_fapi_font, &output, charset_offset_ptr);
585
21.1k
    if (code < 0)
586
0
        return (long)code;
587
588
21.1k
    write_charstrings_index(a_fapi_font, &output, characters, charstrings_offset_ptr);
589
590
21.1k
    code = write_private_dict(a_fapi_font, &output, private_dict_length_ptr);
591
21.1k
    if (code < 0)
592
0
        return (long)code;
593
594
21.1k
    code = write_subrs_index(a_fapi_font, &output);
595
596
21.1k
    if (code < 0)
597
58
        return (long)code;
598
599
21.0k
    return output.m_count;
600
21.1k
}