Coverage Report

Created: 2026-04-01 07:17

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