Coverage Report

Created: 2026-09-14 07:34

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