Coverage Report

Created: 2026-10-28 08:05

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