Coverage Report

Created: 2025-06-24 07:01

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