Coverage Report

Created: 2022-10-31 07:00

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