Coverage Report

Created: 2025-12-31 07:31

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