Coverage Report

Created: 2025-04-22 06:20

/src/libspectre/ghostscript/base/write_t1.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2020 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 as PostScript code that can then be
18
passed to FreeType via the FAPI FreeType bridge.
19
Started by Graham Asher, 26th July 2002.
20
*/
21
22
#include <stdio.h>
23
#include "wrfont.h"
24
#include "write_t1.h"
25
26
/*
27
Public structures and functions in this file are prefixed with FF_ because they are part of
28
the FAPI FreeType implementation.
29
*/
30
31
static int
32
write_word_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
33
                 const char *a_name, int a_index, int a_divisor)
34
0
{
35
0
    short x;
36
0
    int code;
37
38
0
    WRF_wbyte(a_fapi_font->memory, a_output, '/');
39
0
    WRF_wstring(a_fapi_font->memory, a_output, a_name);
40
0
    WRF_wbyte(a_fapi_font->memory, a_output, ' ');
41
42
    /* Get the value and convert it from unsigned to signed by assigning it to a short. */
43
0
    code = a_fapi_font->get_word(a_fapi_font, a_index, 0, (unsigned short *)&x);
44
0
    if (code < 0)
45
0
        return code;
46
47
    /* Divide by the divisor to bring it back to font units. */
48
0
    x = (short)(x / a_divisor);
49
0
    WRF_wint(a_fapi_font->memory, a_output, x);
50
0
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
51
52
0
    return 0;
53
0
}
54
55
static int
56
write_array_entry_with_count(gs_fapi_font * a_fapi_font,
57
                             WRF_output * a_output, const char *a_name,
58
                             int a_index, int a_count, int a_divisor)
59
0
{
60
0
    int i, code;;
61
62
0
    if (a_count <= 0)
63
0
        return 0;
64
65
0
    WRF_wbyte(a_fapi_font->memory, a_output, '/');
66
0
    WRF_wstring(a_fapi_font->memory, a_output, a_name);
67
0
    WRF_wstring(a_fapi_font->memory, a_output, " [");
68
0
    for (i = 0; i < a_count; i++) {
69
        /* Get the value and convert it from unsigned to signed by assigning it to a short. */
70
0
        short x;
71
0
        code = a_fapi_font->get_word(a_fapi_font, a_index, i, (unsigned short *)&x);
72
0
        if (code < 0)
73
0
            return code;
74
75
        /* Divide by the divisor to bring it back to font units. */
76
0
        x = (short)(x / a_divisor);
77
0
        WRF_wint(a_fapi_font->memory, a_output, x);
78
0
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == a_count - 1 ? ']' : ' '));
79
0
    }
80
0
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
81
82
0
    return 0;
83
0
}
84
85
static int
86
write_array_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output,
87
                  const char *a_name, int a_index, int a_divisor)
88
0
{
89
    /* NOTE that the feature index must be preceded by the count index for this to work. */
90
0
    unsigned short count;
91
0
    int code = a_fapi_font->get_word(a_fapi_font, a_index - 1, 0, &count);
92
93
0
    if (code < 0)
94
0
        return code;
95
96
0
    return write_array_entry_with_count(a_fapi_font, a_output, a_name, a_index,
97
0
                                 count, a_divisor);
98
0
}
99
100
static int
101
write_subrs(gs_fapi_font * a_fapi_font, WRF_output * a_output, int raw)
102
0
{
103
0
    int i;
104
0
    unsigned short count;
105
0
    int code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
106
0
                              0, &count);
107
0
    if (code < 0)
108
0
        return code;
109
110
0
    if (count > 0) {
111
0
        WRF_wstring(a_fapi_font->memory, a_output, "/Subrs ");
112
0
        WRF_wint(a_fapi_font->memory, a_output, count);
113
0
        WRF_wstring(a_fapi_font->memory, a_output, " array\n");
114
115
0
        for (i = 0; i < count; i++) {
116
0
            int length;
117
0
            int buffer_size;
118
119
120
0
            if (raw)
121
0
                length = a_fapi_font->get_raw_subr(a_fapi_font, i, 0, 0);
122
0
            else
123
0
                length = a_fapi_font->get_subr(a_fapi_font, i, 0, 0);
124
0
            if (length < 0)
125
0
                return length;
126
127
0
            WRF_wstring(a_fapi_font->memory, a_output, "dup ");
128
0
            WRF_wint(a_fapi_font->memory, a_output, i);
129
0
            WRF_wbyte(a_fapi_font->memory, a_output, ' ');
130
0
            WRF_wint(a_fapi_font->memory, a_output, length);
131
0
            WRF_wstring(a_fapi_font->memory, a_output, " RD ");
132
133
            /* Get the subroutine into the buffer and encrypt it in place. */
134
0
            buffer_size = a_output->m_limit - a_output->m_count;
135
0
            if (buffer_size >= length) {
136
0
                int l2;
137
138
0
                if (raw)
139
0
                    l2 = a_fapi_font->get_raw_subr(a_fapi_font, i, a_output->m_pos,
140
0
                                              (ushort) length);
141
0
                else
142
0
                    l2 = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos,
143
0
                                          (ushort) length);
144
0
                if (l2 < 0)
145
0
                    return l2;
146
147
0
                WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length);
148
0
            } else
149
0
                a_output->m_count += length;
150
151
0
            WRF_wstring(a_fapi_font->memory, a_output, " NP\n");
152
0
        }
153
154
0
        WRF_wstring(a_fapi_font->memory, a_output, "ND\n");
155
0
    }
156
0
    return 0;
157
0
}
158
159
static int
160
write_charstrings(gs_fapi_font * a_fapi_font, WRF_output * a_output)
161
0
{
162
0
    int length;
163
0
    int buffer_size;
164
0
    int i;
165
0
    unsigned short count;
166
0
    int code = a_fapi_font->get_word(a_fapi_font,
167
0
                                         gs_fapi_font_feature_CharStrings_count,
168
0
                                         0, &count);
169
0
    char NameBuf[256];
170
171
0
    if (code < 0)
172
0
        return code;
173
174
0
    if (count > 0) {
175
0
        WRF_wstring(a_fapi_font->memory, a_output, "2 index /CharStrings ");
176
0
        WRF_wint(a_fapi_font->memory, a_output, count);
177
0
        WRF_wstring(a_fapi_font->memory, a_output, " dict dup begin\n");
178
0
        for (i = 0; i < count; i++) {
179
0
            length =
180
0
                a_fapi_font->get_charstring_name(a_fapi_font, i,
181
0
                                                 (byte *) & NameBuf, 256);
182
0
            if (length < 0)
183
0
                return length;
184
185
0
            if (length > 0) {
186
0
                length = a_fapi_font->get_charstring(a_fapi_font, i, 0, 0);
187
0
                if (length < 0)
188
0
                    return length;
189
190
0
                WRF_wbyte(a_fapi_font->memory, a_output, '/');
191
0
                WRF_wstring(a_fapi_font->memory, a_output, (const char *)&NameBuf);
192
0
                WRF_wbyte(a_fapi_font->memory, a_output, ' ');
193
0
                WRF_wint(a_fapi_font->memory, a_output, length);
194
0
                WRF_wstring(a_fapi_font->memory, a_output, " RD ");
195
196
                /* Get the CharString into the buffer and encrypt it in place. */
197
0
                buffer_size = a_output->m_limit - a_output->m_count;
198
0
                if (buffer_size >= length) {
199
0
                    int l2;
200
0
                    l2 = a_fapi_font->get_charstring(a_fapi_font, i, a_output->m_pos,
201
0
                                                (ushort) length);
202
0
                    if (l2 < 0)
203
0
                        return l2;
204
205
0
                    WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length);
206
0
                } else
207
0
                    a_output->m_count += length;
208
0
                WRF_wstring(a_fapi_font->memory, a_output, " ND\n");
209
0
            }
210
0
        }
211
0
        WRF_wstring(a_fapi_font->memory, a_output, " end");
212
0
    }
213
0
    return 0;
214
0
}
215
216
static bool
217
is_MM_font(gs_fapi_font * a_fapi_font)
218
0
{
219
0
    unsigned short db;
220
0
    int code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_DollarBlend, 0, &db);
221
222
0
    if (code >= 0 && db == 1)
223
0
        return true;
224
225
0
    return false;
226
0
}
227
228
static int
229
write_private_blend_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output)
230
0
{
231
0
    short x, x1, x2, i, j, acc;
232
0
    int code;
233
234
0
    if (is_MM_font(a_fapi_font)) {
235
236
0
        WRF_wstring(a_fapi_font->memory, a_output, "3 index /Blend get /Private get begin\n");
237
0
        code = a_fapi_font->get_word(a_fapi_font,
238
0
                                  gs_fapi_font_feature_BlendBlueValues_length, 0, (unsigned short *)&x);
239
0
        if (code < 0)
240
0
            return code;
241
242
0
        if (x > 0) {
243
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlueValues [");
244
0
            acc = 0;
245
0
            for (i = 0; i < x; i++) {
246
0
                WRF_wstring(a_fapi_font->memory, a_output, " [");
247
0
                code = a_fapi_font->get_word(a_fapi_font,
248
0
                                      gs_fapi_font_feature_BlendBlueValues_count, i, (unsigned short *)&x1);
249
0
                if (code < 0)
250
0
                    return code;
251
252
0
                for (j = 0; j < x1; j++) {
253
0
                    code = a_fapi_font->get_word(a_fapi_font,
254
0
                                      gs_fapi_font_feature_BlendBlueValues, acc++, (unsigned short *)&x2);
255
0
                    if (code < 0)
256
0
                        return code;
257
258
0
                    WRF_wint(a_fapi_font->memory, a_output, x2);
259
0
                    WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
260
0
                }
261
0
                WRF_wstring(a_fapi_font->memory, a_output, " ]");
262
0
            }
263
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
264
0
        }
265
266
0
        code = a_fapi_font->get_word(a_fapi_font,
267
0
                                  gs_fapi_font_feature_BlendOtherBlues_length, 0, (unsigned short *)&x);
268
0
        if (code < 0)
269
0
            return code;
270
271
0
        if (x > 0) {
272
0
            WRF_wstring(a_fapi_font->memory, a_output, "/OtherBlues [");
273
0
            acc = 0;
274
0
            for (i = 0; i < x; i++) {
275
0
                WRF_wstring(a_fapi_font->memory, a_output, " [");
276
0
                code = a_fapi_font->get_word(a_fapi_font,
277
0
                                      gs_fapi_font_feature_BlendOtherBlues_count, i, (unsigned short *)&x1);
278
0
                if (code < 0)
279
0
                    return code;
280
281
0
                for (j = 0; j < x1; j++) {
282
0
                    code = a_fapi_font->get_word(a_fapi_font,
283
0
                                      gs_fapi_font_feature_BlendOtherBlues, acc++, (unsigned short *)&x2);
284
0
                    if (code < 0)
285
0
                        return code;
286
287
0
                    WRF_wint(a_fapi_font->memory, a_output, x2);
288
0
                    WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
289
0
                }
290
0
                WRF_wstring(a_fapi_font->memory, a_output, " ]");
291
0
            }
292
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
293
0
        }
294
0
        code = a_fapi_font->get_word(a_fapi_font,
295
0
                                  gs_fapi_font_feature_BlendBlueScale_count, 0, (unsigned short *)&x);
296
0
        if (code < 0)
297
0
            return 0;
298
299
0
        if (x > 0) {
300
0
            float v;
301
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlueScale [");
302
0
            for (i =0; i < x; i++) {
303
0
                code = a_fapi_font->get_float(a_fapi_font,
304
0
                                      gs_fapi_font_feature_BlendBlueScale, i, &v);
305
0
                if (code < 0)
306
0
                    return code;
307
308
0
                WRF_wfloat(a_fapi_font->memory, a_output, v);
309
0
                WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
310
0
            }
311
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
312
0
        }
313
314
0
        code = a_fapi_font->get_word(a_fapi_font,
315
0
                                  gs_fapi_font_feature_BlendBlueShift_count, 0, (unsigned short *)&x);
316
0
        if (code < 0)
317
0
            return code;
318
319
0
        if (x > 0) {
320
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlueShift [");
321
0
            for (i =0; i < x; i++) {
322
0
                code = a_fapi_font->get_word(a_fapi_font,
323
0
                                      gs_fapi_font_feature_BlendBlueShift, i, (unsigned short *)&x2);
324
0
                if (code < 0)
325
0
                    return code;
326
327
0
                WRF_wint(a_fapi_font->memory, a_output, x2);
328
0
                WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
329
0
            }
330
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
331
0
        }
332
333
0
        code = a_fapi_font->get_word(a_fapi_font,
334
0
                                  gs_fapi_font_feature_BlendBlueFuzz_count, 0, (unsigned short *)&x);
335
0
        if (code < 0)
336
0
            return code;
337
338
0
        if (x > 0) {
339
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlueFuzz [");
340
0
            for (i =0; i < x; i++) {
341
0
                code = a_fapi_font->get_word(a_fapi_font,
342
0
                                      gs_fapi_font_feature_BlendBlueFuzz, i, (unsigned short *)&x2);
343
0
                if (code < 0)
344
0
                    return code;
345
346
0
                WRF_wint(a_fapi_font->memory, a_output, x2);
347
0
                WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
348
0
            }
349
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
350
0
        }
351
352
0
        code = a_fapi_font->get_word(a_fapi_font,
353
0
                                  gs_fapi_font_feature_BlendForceBold_count, 0, (unsigned short *)&x);
354
0
        if (code < 0)
355
0
            return code;
356
357
0
        if (x > 0) {
358
0
            WRF_wstring(a_fapi_font->memory, a_output, "/ForceBold [");
359
0
            for (i =0; i < x; i++) {
360
0
                code = a_fapi_font->get_word(a_fapi_font,
361
0
                                      gs_fapi_font_feature_BlendForceBold, i, (unsigned short *)&x2);
362
0
                if (code < 0)
363
0
                    return code;
364
365
0
                WRF_wstring(a_fapi_font->memory, a_output, x2 ? "/true" : "/false");
366
0
                WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
367
0
            }
368
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
369
0
        }
370
371
0
        code = a_fapi_font->get_word(a_fapi_font,
372
0
                                  gs_fapi_font_feature_BlendStdHW_length, 0, (unsigned short *)&x);
373
0
        if (code < 0)
374
0
            return code;
375
376
0
        if (x > 0) {
377
0
            WRF_wstring(a_fapi_font->memory, a_output, "/StdHW [");
378
0
            acc = 0;
379
0
            for (i = 0; i < x; i++) {
380
0
                WRF_wstring(a_fapi_font->memory, a_output, " [");
381
0
                code = a_fapi_font->get_word(a_fapi_font,
382
0
                                      gs_fapi_font_feature_BlendStdHW_count, i, (unsigned short *)&x1);
383
0
                if (code < 0)
384
0
                    return code;
385
386
0
                for (j = 0; j < x1; j++) {
387
0
                    code = a_fapi_font->get_word(a_fapi_font,
388
0
                                      gs_fapi_font_feature_BlendStdHW, acc++, (unsigned short *)&x2);
389
0
                    if (code < 0)
390
0
                        return code;
391
392
0
                    WRF_wint(a_fapi_font->memory, a_output, x2);
393
0
                    WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
394
0
                }
395
0
                WRF_wstring(a_fapi_font->memory, a_output, " ]");
396
0
            }
397
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
398
0
        }
399
400
0
        code = a_fapi_font->get_word(a_fapi_font,
401
0
                                  gs_fapi_font_feature_BlendStdVW_length, 0, (unsigned short *)&x);
402
0
        if (code < 0)
403
0
            return code;
404
405
0
        if (x > 0) {
406
0
            WRF_wstring(a_fapi_font->memory, a_output, "/StdVW [");
407
0
            acc = 0;
408
0
            for (i = 0; i < x; i++) {
409
0
                WRF_wstring(a_fapi_font->memory, a_output, " [");
410
0
                code = a_fapi_font->get_word(a_fapi_font,
411
0
                                      gs_fapi_font_feature_BlendStdVW_count, i, (unsigned short *)&x1);
412
0
                if (code < 0)
413
0
                    return code;
414
415
0
                for (j = 0; j < x1; j++) {
416
0
                    code = a_fapi_font->get_word(a_fapi_font,
417
0
                                      gs_fapi_font_feature_BlendStdVW, acc++, (unsigned short *)&x2);
418
0
                    if (code < 0)
419
0
                        return code;
420
421
0
                    WRF_wint(a_fapi_font->memory, a_output, x2);
422
0
                    WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
423
0
                }
424
0
                WRF_wstring(a_fapi_font->memory, a_output, " ]");
425
0
            }
426
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
427
0
        }
428
429
0
        code = a_fapi_font->get_word(a_fapi_font,
430
0
                                  gs_fapi_font_feature_BlendStemSnapH_length, 0, (unsigned short *)&x);
431
0
        if (code < 0)
432
0
            return code;
433
434
0
        if (x > 0) {
435
0
            WRF_wstring(a_fapi_font->memory, a_output, "/StemSnapH [");
436
0
            acc = 0;
437
0
            for (i = 0; i < x; i++) {
438
0
                WRF_wstring(a_fapi_font->memory, a_output, " [");
439
0
                code = a_fapi_font->get_word(a_fapi_font,
440
0
                                      gs_fapi_font_feature_BlendStemSnapH_count, i, (unsigned short *)&x1);
441
0
                if (code < 0)
442
0
                    return code;
443
444
0
                for (j = 0; j < x1; j++) {
445
0
                    code = a_fapi_font->get_word(a_fapi_font,
446
0
                                      gs_fapi_font_feature_BlendStemSnapH, acc++, (unsigned short *)&x2);
447
0
                    if (code < 0)
448
0
                        return code;
449
450
0
                    WRF_wint(a_fapi_font->memory, a_output, x2);
451
0
                    WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
452
0
                }
453
0
                WRF_wstring(a_fapi_font->memory, a_output, " ]");
454
0
            }
455
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
456
0
        }
457
458
0
        code = a_fapi_font->get_word(a_fapi_font,
459
0
                                  gs_fapi_font_feature_BlendStemSnapV_length, 0, (unsigned short *)&x);
460
0
        if (code < 0)
461
0
            return code;
462
463
0
        if (x > 0) {
464
0
            WRF_wstring(a_fapi_font->memory, a_output, "/StemSnapV [");
465
0
            acc = 0;
466
0
            for (i = 0; i < x; i++) {
467
0
                WRF_wstring(a_fapi_font->memory, a_output, " [");
468
0
                code = a_fapi_font->get_word(a_fapi_font,
469
0
                                      gs_fapi_font_feature_BlendStemSnapV_count, i, (unsigned short *)&x1);
470
0
                if (code < 0)
471
0
                    return code;
472
473
0
                for (j = 0; j < x1; j++) {
474
0
                    code = a_fapi_font->get_word(a_fapi_font,
475
0
                                      gs_fapi_font_feature_BlendStemSnapV, acc++, (unsigned short *)&x2);
476
0
                    if (code < 0)
477
0
                        return code;
478
479
0
                    WRF_wint(a_fapi_font->memory, a_output, x2);
480
0
                    WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
481
0
                }
482
0
                WRF_wstring(a_fapi_font->memory, a_output, " ]");
483
0
            }
484
0
            WRF_wstring(a_fapi_font->memory, a_output, " ]\n");
485
0
        }
486
487
0
        WRF_wstring(a_fapi_font->memory, a_output, "end\n");
488
0
    }
489
0
    return 0;
490
0
}
491
492
static int
493
write_private_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
494
                         int Write_CharStrings)
495
0
{
496
0
    int code;
497
0
    unsigned long ulval;
498
0
    a_output->m_encrypt = true;
499
500
    /* Write 4 bytes that must encrypt to at least one character that cannot be a valid hexadecimal character. */
501
0
    WRF_wstring(a_fapi_font->memory, a_output, "XXXX");
502
503
    /*+ to do: correct size of dictionary from 8. */
504
0
    WRF_wstring(a_fapi_font->memory, a_output, "dup /Private 8 dict dup begin\n");
505
506
0
    WRF_wstring(a_fapi_font->memory, a_output, "/MinFeature {16 16} def\n");
507
0
    WRF_wstring(a_fapi_font->memory, a_output, "/password 5839 def\n");
508
0
    if (Write_CharStrings) {
509
0
        code = write_word_entry(a_fapi_font, a_output, "lenIV", gs_fapi_font_feature_lenIV, 1);
510
0
        if (code < 0)
511
0
            return code;
512
0
    }
513
0
    else {
514
0
        WRF_wstring(a_fapi_font->memory, a_output, "/lenIV -1 def\n");       /* indicate that /subrs are not encoded. */
515
0
    }
516
0
    code = write_word_entry(a_fapi_font, a_output, "BlueFuzz", gs_fapi_font_feature_BlueFuzz, 16);
517
0
    if (code < 0)
518
0
        return code;
519
520
0
    WRF_wstring(a_fapi_font->memory, a_output, "/BlueScale ");
521
0
    code = a_fapi_font->get_long(a_fapi_font,gs_fapi_font_feature_BlueScale, 0, &ulval);
522
0
    if (code < 0)
523
0
        return code;
524
525
0
    WRF_wfloat(a_fapi_font->memory, a_output, (float)ulval/65536.0);
526
527
0
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
528
529
0
    code = write_word_entry(a_fapi_font, a_output, "BlueShift", gs_fapi_font_feature_BlueShift, 16);
530
0
    if (code < 0)
531
0
        return code;
532
533
0
    code = write_array_entry(a_fapi_font, a_output, "BlueValues",
534
0
                      gs_fapi_font_feature_BlueValues, 16);
535
0
    if (code < 0)
536
0
        return code;
537
538
0
    code = write_array_entry(a_fapi_font, a_output, "OtherBlues",
539
0
                      gs_fapi_font_feature_OtherBlues, 16);
540
0
    if (code < 0)
541
0
        return code;
542
543
0
    code = write_array_entry(a_fapi_font, a_output, "FamilyBlues",
544
0
                      gs_fapi_font_feature_FamilyBlues, 16);
545
0
    if (code < 0)
546
0
        return code;
547
548
0
    code = write_array_entry(a_fapi_font, a_output, "FamilyOtherBlues",
549
0
                      gs_fapi_font_feature_FamilyOtherBlues, 16);
550
0
    if (code < 0)
551
0
        return code;
552
553
0
    code = write_word_entry(a_fapi_font, a_output, "ForceBold", gs_fapi_font_feature_ForceBold, 1);
554
0
    if (code < 0)
555
0
        return code;
556
557
0
    code = write_array_entry_with_count(a_fapi_font, a_output, "StdHW",
558
0
                                 gs_fapi_font_feature_StdHW, 1, 16);
559
0
    if (code < 0)
560
0
        return code;
561
562
0
    code = write_array_entry_with_count(a_fapi_font, a_output, "StdVW",
563
0
                                 gs_fapi_font_feature_StdVW, 1, 16);
564
0
    if (code < 0)
565
0
        return code;
566
567
0
    code = write_array_entry(a_fapi_font, a_output, "StemSnapH",
568
0
                      gs_fapi_font_feature_StemSnapH, 16);
569
0
    if (code < 0)
570
0
        return code;
571
572
0
    code = write_array_entry(a_fapi_font, a_output, "StemSnapV",
573
0
                      gs_fapi_font_feature_StemSnapV, 16);
574
0
    if (code < 0)
575
0
        return code;
576
577
0
    code = write_private_blend_dictionary(a_fapi_font, a_output);
578
0
    if (code < 0)
579
0
        return code;
580
581
0
    if (Write_CharStrings)
582
0
        code = write_subrs(a_fapi_font, a_output, 1);
583
0
    else
584
0
        code = write_subrs(a_fapi_font, a_output, 0);
585
0
    if (code < 0)
586
0
        return code;
587
588
0
    if (Write_CharStrings)
589
0
        code = write_charstrings(a_fapi_font, a_output);
590
591
0
    return code;
592
0
}
593
594
static int
595
write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output, int Write_CharStrings)
596
0
{
597
0
    int i, code;
598
0
    float fval;
599
600
0
    WRF_wstring(a_fapi_font->memory, a_output, "5 dict begin\n");
601
602
0
    WRF_wstring(a_fapi_font->memory, a_output, "/FontType 1 def\n");
603
604
0
    WRF_wstring(a_fapi_font->memory, a_output, "/FontMatrix [");
605
0
    for (i = 0; i < 6; i++) {
606
0
        code = a_fapi_font->get_float(a_fapi_font, gs_fapi_font_feature_FontMatrix, i, &fval);
607
0
        if (code < 0)
608
0
            return code;
609
610
0
        WRF_wfloat(a_fapi_font->memory, a_output, fval);
611
0
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == 5 ? ']' : ' '));
612
0
    }
613
0
    WRF_wbyte(a_fapi_font->memory, a_output, '\n');
614
    /* For now, specify standard encoding - I think GS will pass glyph indices so doesn't matter. */
615
0
    WRF_wstring(a_fapi_font->memory, a_output, "/Encoding StandardEncoding def\n");
616
617
0
    WRF_wstring(a_fapi_font->memory, a_output, "/FontBBox {");
618
0
    for (i = 0; i < 4; i++) {
619
0
        short x;
620
0
        code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_FontBBox,
621
0
                                  i, (unsigned short *)&x);
622
0
        if (code < 0)
623
0
            return code;
624
625
0
        WRF_wint(a_fapi_font->memory, a_output, x);
626
0
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == 3 ? '}' : ' '));
627
0
    }
628
0
    WRF_wbyte(a_fapi_font->memory, a_output, '\n');
629
0
    if (is_MM_font(a_fapi_font)) {
630
0
        short x, x2;
631
0
        float x1;
632
0
        uint i, j, entries;
633
0
        char Buffer[255];
634
635
0
        entries = 0;
636
0
        code = a_fapi_font->get_word(a_fapi_font,
637
0
                                  gs_fapi_font_feature_BlendAxisTypes_count,
638
0
                                  0, (unsigned short *)&x);
639
0
        if (code < 0)
640
0
            return code;
641
642
0
        if (x)
643
0
            entries++;
644
645
0
        code = a_fapi_font->get_word(a_fapi_font,
646
0
                                  gs_fapi_font_feature_BlendDesignPositionsArrays_count,
647
0
                                  0, (unsigned short *)&x);
648
0
        if (code < 0)
649
0
            return code;
650
651
0
        if (x)
652
0
            entries++;
653
0
        code = a_fapi_font->get_word(a_fapi_font,
654
0
                                  gs_fapi_font_feature_BlendDesignMapArrays_count,
655
0
                                  0, (unsigned short *)&x);
656
0
        if (code < 0)
657
0
            return code;
658
0
        if (x)
659
660
0
            entries++;
661
662
0
        gs_sprintf(Buffer, "/FontInfo %d dict dup begin\n", entries);
663
0
        WRF_wstring(a_fapi_font->memory, a_output, Buffer);
664
0
        code = a_fapi_font->get_word(a_fapi_font,
665
0
                                  gs_fapi_font_feature_BlendAxisTypes_count,
666
0
                                  0, (unsigned short *)&x);
667
0
        if (code < 0)
668
0
            return code;
669
670
0
        if (x) {
671
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlendAxisTypes [");
672
0
            for (i = 0; i < x; i++) {
673
0
                WRF_wstring(a_fapi_font->memory, a_output, " /");
674
0
                code = a_fapi_font->get_name(a_fapi_font,
675
0
                                      gs_fapi_font_feature_BlendAxisTypes, i,
676
0
                                      (char *)&Buffer, 255);
677
0
                if (code < 0)
678
0
                    return code;
679
680
0
                WRF_wstring(a_fapi_font->memory, a_output, Buffer);
681
0
            }
682
0
            WRF_wstring(a_fapi_font->memory, a_output, "] def\n");
683
0
        }
684
0
        code = a_fapi_font->get_word(a_fapi_font,
685
0
                                  gs_fapi_font_feature_BlendDesignPositionsArrays_count,
686
0
                                  0, (unsigned short *)&x);
687
0
        if (code < 0)
688
0
            return code;
689
690
0
        if (x) {
691
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlendDesignPositions [");
692
0
            code = a_fapi_font->get_word(a_fapi_font,
693
0
                                       gs_fapi_font_feature_BlendAxisTypes_count,
694
0
                                       0, (unsigned short *)&x2);
695
0
            if (code < 0)
696
0
                return code;
697
698
0
            for (i = 0; i < x; i++) {
699
0
                WRF_wstring(a_fapi_font->memory, a_output, "[");
700
0
                for (j = 0; j < x2; j++) {
701
0
                    code = a_fapi_font->get_float(a_fapi_font,
702
0
                                                gs_fapi_font_feature_BlendDesignPositionsArrayValue,
703
0
                                                i * 8 + j, &x1);
704
0
                    if (code < 0)
705
0
                        return code;
706
707
0
                    gs_sprintf(Buffer, "%f ", x1);
708
0
                    WRF_wstring(a_fapi_font->memory, a_output, Buffer);
709
0
                }
710
0
                WRF_wstring(a_fapi_font->memory, a_output, "]");
711
0
            }
712
0
            WRF_wstring(a_fapi_font->memory, a_output, "] def\n");
713
0
        }
714
0
        code = a_fapi_font->get_word(a_fapi_font,
715
0
                                  gs_fapi_font_feature_BlendDesignMapArrays_count,
716
0
                                  0, (unsigned short *)&x);
717
0
        if (code < 0)
718
0
            return code;
719
0
        if (x) {
720
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlendDesignMap [");
721
0
            for (i = 0; i < x; i++) {
722
0
                code = a_fapi_font->get_word(a_fapi_font,
723
0
                                           gs_fapi_font_feature_BlendDesignMapSubArrays_count,
724
0
                                           i, (unsigned short *)&x2);
725
0
                if (code < 0)
726
0
                    return code;
727
728
0
                WRF_wstring(a_fapi_font->memory, a_output, "[");
729
0
                for (j = 0; j < x2; j++) {
730
0
                    WRF_wstring(a_fapi_font->memory, a_output, "[");
731
0
                    code = a_fapi_font->get_float(a_fapi_font,
732
0
                                                gs_fapi_font_feature_BlendDesignPositionsArrayValue,
733
0
                                                i * 64 + j * 64, &x1);
734
0
                    if (code < 0)
735
0
                        return code;
736
737
0
                    gs_sprintf(Buffer, "%f ", x1);
738
0
                    WRF_wstring(a_fapi_font->memory, a_output, Buffer);
739
0
                    code = a_fapi_font->get_float(a_fapi_font,
740
0
                                                gs_fapi_font_feature_BlendDesignPositionsArrayValue,
741
0
                                                i * 64 + j * 64 + 1, &x1);
742
0
                    if (code < 0)
743
0
                        return code;
744
0
                    gs_sprintf(Buffer, "%f ", x1);
745
0
                    WRF_wstring(a_fapi_font->memory, a_output, Buffer);
746
0
                    WRF_wstring(a_fapi_font->memory, a_output, "]");
747
0
                }
748
0
                WRF_wstring(a_fapi_font->memory, a_output, "]");
749
0
            }
750
0
            WRF_wstring(a_fapi_font->memory, a_output, "] def\n");
751
0
        }
752
0
        WRF_wstring(a_fapi_font->memory, a_output, "end readonly def\n");
753
754
        /* Previously we tried to write $Blend twice - the "real" one from the font,
755
         * and the boiler plate one below.
756
         * For now, I assume there was a good reason for including the second, but it may
757
         * be because the "get_proc" method below was missing the code to handle PS name
758
         * objects.
759
         */
760
0
        code = a_fapi_font->get_word(a_fapi_font,
761
0
                                   gs_fapi_font_feature_DollarBlend_length,
762
0
                                   0, (unsigned short *)&x);
763
0
        if (code < 0)
764
0
            return code;
765
766
0
        if (x > 0) {
767
0
            int len;
768
0
            WRF_wstring(a_fapi_font->memory, a_output, "/$Blend {");
769
770
0
            if (a_output->m_count)
771
0
                a_output->m_count += x;
772
0
            len = a_fapi_font->get_proc(a_fapi_font,
773
0
                                      gs_fapi_font_feature_DollarBlend, 0,
774
0
                                      (char *)a_output->m_pos);
775
0
            if (a_output->m_pos)
776
0
                a_output->m_pos += len;
777
0
            WRF_wstring(a_fapi_font->memory, a_output, "} def\n");
778
0
        } else {
779
0
            WRF_wstring(a_fapi_font->memory, a_output,
780
0
                        "/$Blend {0.1 mul exch 0.45 mul add exch 0.17 mul add add} def\n");
781
0
        }
782
0
        WRF_wstring(a_fapi_font->memory, a_output, "/WeightVector [");
783
0
        code = a_fapi_font->get_word(a_fapi_font,
784
0
                                  gs_fapi_font_feature_WeightVector_count, 0, (unsigned short *)&x);
785
0
        if (code < 0)
786
0
            return code;
787
788
0
        for (i = 0; i < x; i++) {
789
0
            code = a_fapi_font->get_float(a_fapi_font,
790
0
                                        gs_fapi_font_feature_WeightVector, i, &x1);
791
0
            if (code < 0)
792
0
                return code;
793
794
0
            gs_sprintf(Buffer, "%f ", x1);
795
0
            WRF_wstring(a_fapi_font->memory, a_output, Buffer);
796
0
        }
797
0
        WRF_wstring(a_fapi_font->memory, a_output, "] def\n");
798
799
0
        WRF_wstring(a_fapi_font->memory, a_output, "/Blend 3 dict dup begin\n");
800
0
        WRF_wstring(a_fapi_font->memory, a_output, "/FontBBox {");
801
0
        code = a_fapi_font->get_word(a_fapi_font,
802
0
                                 gs_fapi_font_feature_BlendFontBBox_length , 0, (unsigned short *)&x);
803
0
        if (code < 0)
804
0
            return code;
805
806
0
        for (i = 0; i < x; i++) {
807
0
            int j;
808
0
            WRF_wstring(a_fapi_font->memory, a_output, " {");
809
0
            for (j = 0; j < 4; j++) {
810
0
                code = a_fapi_font->get_word(a_fapi_font,
811
0
                                  gs_fapi_font_feature_BlendFontBBox,
812
0
                                  j + (i * 4), (unsigned short *)&x2);
813
0
                if (code < 0)
814
0
                    return code;
815
816
0
                WRF_wint(a_fapi_font->memory, a_output, x2);
817
0
                WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
818
0
            }
819
0
            WRF_wstring(a_fapi_font->memory, a_output, "}");
820
0
        }
821
0
        WRF_wstring(a_fapi_font->memory, a_output, " } def\n");
822
0
        WRF_wstring(a_fapi_font->memory, a_output, "/Private 14 dict def\n");
823
0
        WRF_wstring(a_fapi_font->memory, a_output, "end def\n");
824
0
    }
825
0
    WRF_wstring(a_fapi_font->memory, a_output, "currentdict end\ncurrentfile eexec\n");
826
827
0
    return write_private_dictionary(a_fapi_font, a_output, Write_CharStrings);
828
0
}
829
830
/**
831
Write a Type 1 font in textual format and return its length in bytes.
832
If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
833
length is returned correctly.
834
835
The PostScript is non-standard. The main dictionary contains no /Charstrings dictionary. This
836
is supplied to FreeType using the incremental interface, There is also no /PaintType entry. This is required
837
by PostScript but FreeType doesn't use it.
838
*/
839
long
840
gs_fapi_serialize_type1_font(gs_fapi_font * a_fapi_font,
841
                             unsigned char *a_buffer, long a_buffer_size)
842
0
{
843
0
    int code;
844
0
    WRF_output output;
845
846
0
    WRF_init(&output, a_buffer, a_buffer_size);
847
848
    /* Leading comment identifying a Type 1 font. */
849
0
    WRF_wstring(a_fapi_font->memory, &output, "%!PS-AdobeFont-1\n");
850
851
0
    code = write_main_dictionary(a_fapi_font, &output, 0);
852
0
    if (code < 0)
853
0
        return (long)code;
854
#if 0
855
    {
856
        extern FILE *stdout;
857
        if (a_buffer && a_buffer_size >= output.m_count) {
858
            fwrite(a_buffer, 1, output.m_count, stdout);
859
        }
860
    }
861
#endif
862
863
0
    return output.m_count;
864
0
}
865
866
long
867
gs_fapi_serialize_type1_font_complete(gs_fapi_font * a_fapi_font,
868
                                      unsigned char *a_buffer,
869
                                      long a_buffer_size)
870
0
{
871
0
    int code;
872
0
    WRF_output output;
873
874
0
    WRF_init(&output, a_buffer, a_buffer_size);
875
876
    /* Leading comment identifying a Type 1 font. */
877
0
    WRF_wstring(a_fapi_font->memory, &output, "%!PS-AdobeFont-1\n");
878
879
0
    code = write_main_dictionary(a_fapi_font, &output, 1);
880
0
    if (code < 0)
881
0
        return (long)code;
882
883
0
    return output.m_count;
884
0
}