Coverage Report

Created: 2025-11-16 07:40

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