Coverage Report

Created: 2026-04-09 07:06

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