Coverage Report

Created: 2025-06-10 07:27

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