Coverage Report

Created: 2025-06-10 07:27

/src/ghostpdl/base/write_t1.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 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 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
321k
{
35
321k
    short x;
36
321k
    int code;
37
38
321k
    WRF_wbyte(a_fapi_font->memory, a_output, '/');
39
321k
    WRF_wstring(a_fapi_font->memory, a_output, a_name);
40
321k
    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
321k
    code = a_fapi_font->get_word(a_fapi_font, a_index, 0, (unsigned short *)&x);
44
321k
    if (code < 0)
45
0
        return code;
46
47
    /* Divide by the divisor to bring it back to font units. */
48
321k
    x = (short)(x / a_divisor);
49
321k
    WRF_wint(a_fapi_font->memory, a_output, x);
50
321k
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
51
52
321k
    return 0;
53
321k
}
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
856k
{
60
856k
    int i, code;;
61
62
856k
    if (a_count <= 0)
63
323k
        return 0;
64
65
532k
    WRF_wbyte(a_fapi_font->memory, a_output, '/');
66
532k
    WRF_wstring(a_fapi_font->memory, a_output, a_name);
67
532k
    WRF_wstring(a_fapi_font->memory, a_output, " [");
68
3.77M
    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
3.24M
        short x;
71
3.24M
        code = a_fapi_font->get_word(a_fapi_font, a_index, i, (unsigned short *)&x);
72
3.24M
        if (code < 0)
73
0
            return code;
74
75
        /* Divide by the divisor to bring it back to font units. */
76
3.24M
        x = (short)(x / a_divisor);
77
3.24M
        WRF_wint(a_fapi_font->memory, a_output, x);
78
3.24M
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == a_count - 1 ? ']' : ' '));
79
3.24M
    }
80
532k
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
81
82
532k
    return 0;
83
532k
}
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
642k
{
89
    /* NOTE that the feature index must be preceded by the count index for this to work. */
90
642k
    unsigned short count;
91
642k
    int code = a_fapi_font->get_word(a_fapi_font, a_index - 1, 0, &count);
92
93
642k
    if (code < 0)
94
0
        return code;
95
96
642k
    return write_array_entry_with_count(a_fapi_font, a_output, a_name, a_index,
97
642k
                                 count, a_divisor);
98
642k
}
99
100
static int
101
write_subrs(gs_fapi_font * a_fapi_font, WRF_output * a_output, int raw)
102
107k
{
103
107k
    int i;
104
107k
    unsigned short count;
105
107k
    int code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
106
107k
                              0, &count);
107
107k
    if (code < 0)
108
0
        return code;
109
110
107k
    if (count > 0) {
111
106k
        WRF_wstring(a_fapi_font->memory, a_output, "/Subrs ");
112
106k
        WRF_wint(a_fapi_font->memory, a_output, count);
113
106k
        WRF_wstring(a_fapi_font->memory, a_output, " array\n");
114
115
746k
        for (i = 0; i < count; i++) {
116
640k
            int length;
117
640k
            int buffer_size;
118
119
120
640k
            if (raw)
121
0
                length = a_fapi_font->get_raw_subr(a_fapi_font, i, 0, 0);
122
640k
            else
123
640k
                length = a_fapi_font->get_subr(a_fapi_font, i, 0, 0);
124
640k
            if (length < 0)
125
0
                return length;
126
127
640k
            WRF_wstring(a_fapi_font->memory, a_output, "dup ");
128
640k
            WRF_wint(a_fapi_font->memory, a_output, i);
129
640k
            WRF_wbyte(a_fapi_font->memory, a_output, ' ');
130
640k
            WRF_wint(a_fapi_font->memory, a_output, length);
131
640k
            WRF_wstring(a_fapi_font->memory, a_output, " RD ");
132
133
            /* Get the subroutine into the buffer and encrypt it in place. */
134
640k
            buffer_size = a_output->m_limit - a_output->m_count;
135
640k
            if (buffer_size >= length) {
136
320k
                int l2;
137
138
320k
                if (raw)
139
0
                    l2 = a_fapi_font->get_raw_subr(a_fapi_font, i, a_output->m_pos,
140
0
                                              (ushort) length);
141
320k
                else
142
320k
                    l2 = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos,
143
320k
                                          (ushort) length);
144
320k
                if (l2 < 0)
145
0
                    return l2;
146
147
320k
                WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length);
148
320k
            } else
149
320k
                a_output->m_count += length;
150
151
640k
            WRF_wstring(a_fapi_font->memory, a_output, " NP\n");
152
640k
        }
153
154
106k
        WRF_wstring(a_fapi_font->memory, a_output, "ND\n");
155
106k
    }
156
107k
    return 0;
157
107k
}
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
214k
{
219
214k
    unsigned short db;
220
214k
    int code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_DollarBlend, 0, &db);
221
222
214k
    if (code >= 0 && db == 1)
223
0
        return true;
224
225
214k
    return false;
226
214k
}
227
228
static int
229
write_private_blend_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output)
230
107k
{
231
107k
    short x, x1, x2, i, j, acc;
232
107k
    int code;
233
234
107k
    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
107k
    return 0;
490
107k
}
491
492
static int
493
write_private_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
494
                         int Write_CharStrings)
495
107k
{
496
107k
    int code;
497
107k
    unsigned long ulval;
498
107k
    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
107k
    WRF_wstring(a_fapi_font->memory, a_output, "XXXX");
502
503
    /*+ to do: correct size of dictionary from 8. */
504
107k
    WRF_wstring(a_fapi_font->memory, a_output, "dup /Private 8 dict dup begin\n");
505
506
107k
    WRF_wstring(a_fapi_font->memory, a_output, "/MinFeature {16 16} def\n");
507
107k
    WRF_wstring(a_fapi_font->memory, a_output, "/password 5839 def\n");
508
107k
    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
107k
    else {
514
107k
        WRF_wstring(a_fapi_font->memory, a_output, "/lenIV -1 def\n");       /* indicate that /subrs are not encoded. */
515
107k
    }
516
107k
    code = write_word_entry(a_fapi_font, a_output, "BlueFuzz", gs_fapi_font_feature_BlueFuzz, 16);
517
107k
    if (code < 0)
518
0
        return code;
519
520
107k
    WRF_wstring(a_fapi_font->memory, a_output, "/BlueScale ");
521
107k
    code = a_fapi_font->get_long(a_fapi_font,gs_fapi_font_feature_BlueScale, 0, &ulval);
522
107k
    if (code < 0)
523
0
        return code;
524
525
107k
    WRF_wfloat(a_fapi_font->memory, a_output, (float)ulval/65536.0);
526
527
107k
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
528
529
107k
    code = write_word_entry(a_fapi_font, a_output, "BlueShift", gs_fapi_font_feature_BlueShift, 16);
530
107k
    if (code < 0)
531
0
        return code;
532
533
107k
    code = write_array_entry(a_fapi_font, a_output, "BlueValues",
534
107k
                      gs_fapi_font_feature_BlueValues, 16);
535
107k
    if (code < 0)
536
0
        return code;
537
538
107k
    code = write_array_entry(a_fapi_font, a_output, "OtherBlues",
539
107k
                      gs_fapi_font_feature_OtherBlues, 16);
540
107k
    if (code < 0)
541
0
        return code;
542
543
107k
    code = write_array_entry(a_fapi_font, a_output, "FamilyBlues",
544
107k
                      gs_fapi_font_feature_FamilyBlues, 16);
545
107k
    if (code < 0)
546
0
        return code;
547
548
107k
    code = write_array_entry(a_fapi_font, a_output, "FamilyOtherBlues",
549
107k
                      gs_fapi_font_feature_FamilyOtherBlues, 16);
550
107k
    if (code < 0)
551
0
        return code;
552
553
107k
    code = write_word_entry(a_fapi_font, a_output, "ForceBold", gs_fapi_font_feature_ForceBold, 1);
554
107k
    if (code < 0)
555
0
        return code;
556
557
107k
    code = write_array_entry_with_count(a_fapi_font, a_output, "StdHW",
558
107k
                                 gs_fapi_font_feature_StdHW, 1, 16);
559
107k
    if (code < 0)
560
0
        return code;
561
562
107k
    code = write_array_entry_with_count(a_fapi_font, a_output, "StdVW",
563
107k
                                 gs_fapi_font_feature_StdVW, 1, 16);
564
107k
    if (code < 0)
565
0
        return code;
566
567
107k
    code = write_array_entry(a_fapi_font, a_output, "StemSnapH",
568
107k
                      gs_fapi_font_feature_StemSnapH, 16);
569
107k
    if (code < 0)
570
0
        return code;
571
572
107k
    code = write_array_entry(a_fapi_font, a_output, "StemSnapV",
573
107k
                      gs_fapi_font_feature_StemSnapV, 16);
574
107k
    if (code < 0)
575
0
        return code;
576
577
107k
    code = write_private_blend_dictionary(a_fapi_font, a_output);
578
107k
    if (code < 0)
579
0
        return code;
580
581
107k
    if (Write_CharStrings)
582
0
        code = write_subrs(a_fapi_font, a_output, 1);
583
107k
    else
584
107k
        code = write_subrs(a_fapi_font, a_output, 0);
585
107k
    if (code < 0)
586
0
        return code;
587
588
107k
    if (Write_CharStrings)
589
0
        code = write_charstrings(a_fapi_font, a_output);
590
591
107k
    return code;
592
107k
}
593
594
static int
595
write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output, int Write_CharStrings)
596
107k
{
597
107k
    int i, code;
598
107k
    float fval;
599
600
107k
    WRF_wstring(a_fapi_font->memory, a_output, "5 dict begin\n");
601
602
107k
    WRF_wstring(a_fapi_font->memory, a_output, "/FontType 1 def\n");
603
604
107k
    WRF_wstring(a_fapi_font->memory, a_output, "/FontMatrix [");
605
749k
    for (i = 0; i < 6; i++) {
606
642k
        code = a_fapi_font->get_float(a_fapi_font, gs_fapi_font_feature_FontMatrix, i, &fval);
607
642k
        if (code < 0)
608
0
            return code;
609
610
642k
        WRF_wfloat(a_fapi_font->memory, a_output, fval);
611
642k
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == 5 ? ']' : ' '));
612
642k
    }
613
107k
    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
107k
    WRF_wstring(a_fapi_font->memory, a_output, "/Encoding StandardEncoding def\n");
616
617
107k
    WRF_wstring(a_fapi_font->memory, a_output, "/FontBBox {");
618
535k
    for (i = 0; i < 4; i++) {
619
428k
        short x;
620
428k
        code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_FontBBox,
621
428k
                                  i, (unsigned short *)&x);
622
428k
        if (code < 0)
623
0
            return code;
624
625
428k
        WRF_wint(a_fapi_font->memory, a_output, x);
626
428k
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == 3 ? '}' : ' '));
627
428k
    }
628
107k
    WRF_wbyte(a_fapi_font->memory, a_output, '\n');
629
107k
    if (is_MM_font(a_fapi_font)) {
630
0
        short x, x2;
631
0
        unsigned short ux;
632
0
        float x1;
633
0
        uint i, j, entries;
634
0
        char Buffer[255];
635
636
0
        entries = 0;
637
0
        code = a_fapi_font->get_word(a_fapi_font,
638
0
                                  gs_fapi_font_feature_BlendAxisTypes_count,
639
0
                                  0, (unsigned short *)&x);
640
0
        if (code < 0)
641
0
            return code;
642
643
0
        if (x)
644
0
            entries++;
645
646
0
        code = a_fapi_font->get_word(a_fapi_font,
647
0
                                  gs_fapi_font_feature_BlendDesignPositionsArrays_count,
648
0
                                  0, (unsigned short *)&x);
649
0
        if (code < 0)
650
0
            return code;
651
652
0
        if (x)
653
0
            entries++;
654
0
        code = a_fapi_font->get_word(a_fapi_font,
655
0
                                  gs_fapi_font_feature_BlendDesignMapArrays_count,
656
0
                                  0, (unsigned short *)&x);
657
0
        if (code < 0)
658
0
            return code;
659
0
        if (x)
660
661
0
            entries++;
662
663
0
        gs_snprintf(Buffer, sizeof(Buffer), "/FontInfo %d dict dup begin\n", entries);
664
0
        WRF_wstring(a_fapi_font->memory, a_output, Buffer);
665
0
        code = a_fapi_font->get_word(a_fapi_font,
666
0
                                  gs_fapi_font_feature_BlendAxisTypes_count,
667
0
                                  0, (unsigned short *)&x);
668
0
        if (code < 0)
669
0
            return code;
670
671
0
        if (x) {
672
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlendAxisTypes [");
673
0
            for (i = 0; i < x; i++) {
674
0
                WRF_wstring(a_fapi_font->memory, a_output, " /");
675
0
                code = a_fapi_font->get_name(a_fapi_font,
676
0
                                      gs_fapi_font_feature_BlendAxisTypes, i,
677
0
                                      (char *)&Buffer, 255);
678
0
                if (code < 0)
679
0
                    return code;
680
681
0
                WRF_wstring(a_fapi_font->memory, a_output, Buffer);
682
0
            }
683
0
            WRF_wstring(a_fapi_font->memory, a_output, "] def\n");
684
0
        }
685
0
        code = a_fapi_font->get_word(a_fapi_font,
686
0
                                  gs_fapi_font_feature_BlendDesignPositionsArrays_count,
687
0
                                  0, (unsigned short *)&x);
688
0
        if (code < 0)
689
0
            return code;
690
691
0
        if (x) {
692
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlendDesignPositions [");
693
0
            code = a_fapi_font->get_word(a_fapi_font,
694
0
                                       gs_fapi_font_feature_BlendAxisTypes_count,
695
0
                                       0, (unsigned short *)&x2);
696
0
            if (code < 0)
697
0
                return code;
698
699
0
            for (i = 0; i < x; i++) {
700
0
                WRF_wstring(a_fapi_font->memory, a_output, "[");
701
0
                for (j = 0; j < x2; j++) {
702
0
                    code = a_fapi_font->get_float(a_fapi_font,
703
0
                                                gs_fapi_font_feature_BlendDesignPositionsArrayValue,
704
0
                                                i * 8 + j, &x1);
705
0
                    if (code < 0)
706
0
                        return code;
707
708
0
                    gs_snprintf(Buffer, sizeof(Buffer), "%f ", x1);
709
0
                    WRF_wstring(a_fapi_font->memory, a_output, Buffer);
710
0
                }
711
0
                WRF_wstring(a_fapi_font->memory, a_output, "]");
712
0
            }
713
0
            WRF_wstring(a_fapi_font->memory, a_output, "] def\n");
714
0
        }
715
0
        code = a_fapi_font->get_word(a_fapi_font,
716
0
                                  gs_fapi_font_feature_BlendDesignMapArrays_count,
717
0
                                  0, (unsigned short *)&x);
718
0
        if (code < 0)
719
0
            return code;
720
0
        if (x) {
721
0
            WRF_wstring(a_fapi_font->memory, a_output, "/BlendDesignMap [");
722
0
            for (i = 0; i < x; i++) {
723
0
                code = a_fapi_font->get_word(a_fapi_font,
724
0
                                           gs_fapi_font_feature_BlendDesignMapSubArrays_count,
725
0
                                           i, (unsigned short *)&x2);
726
0
                if (code < 0)
727
0
                    return code;
728
729
0
                WRF_wstring(a_fapi_font->memory, a_output, "[");
730
0
                for (j = 0; j < x2; j++) {
731
0
                    WRF_wstring(a_fapi_font->memory, a_output, "[");
732
0
                    code = a_fapi_font->get_float(a_fapi_font,
733
0
                                                gs_fapi_font_feature_BlendDesignPositionsArrayValue,
734
0
                                                i * 64 + j * 64, &x1);
735
0
                    if (code < 0)
736
0
                        return code;
737
738
0
                    gs_snprintf(Buffer, sizeof(Buffer), "%f ", x1);
739
0
                    WRF_wstring(a_fapi_font->memory, a_output, Buffer);
740
0
                    code = a_fapi_font->get_float(a_fapi_font,
741
0
                                                gs_fapi_font_feature_BlendDesignPositionsArrayValue,
742
0
                                                i * 64 + j * 64 + 1, &x1);
743
0
                    if (code < 0)
744
0
                        return code;
745
0
                    gs_snprintf(Buffer, sizeof(Buffer), "%f ", x1);
746
0
                    WRF_wstring(a_fapi_font->memory, a_output, Buffer);
747
0
                    WRF_wstring(a_fapi_font->memory, a_output, "]");
748
0
                }
749
0
                WRF_wstring(a_fapi_font->memory, a_output, "]");
750
0
            }
751
0
            WRF_wstring(a_fapi_font->memory, a_output, "] def\n");
752
0
        }
753
0
        WRF_wstring(a_fapi_font->memory, a_output, "end readonly def\n");
754
755
        /* Previously we tried to write $Blend twice - the "real" one from the font,
756
         * and the boiler plate one below.
757
         * For now, I assume there was a good reason for including the second, but it may
758
         * be because the "get_proc" method below was missing the code to handle PS name
759
         * objects.
760
         */
761
0
        code = a_fapi_font->get_word(a_fapi_font,
762
0
                                   gs_fapi_font_feature_DollarBlend_length,
763
0
                                   0, &ux);
764
0
        if (code < 0)
765
0
            return code;
766
767
0
        if (ux > 0) {
768
0
            int len;
769
0
            WRF_wstring(a_fapi_font->memory, a_output, "/$Blend {");
770
771
0
            if (a_output->m_count)
772
0
                a_output->m_count += ux;
773
0
            len = a_fapi_font->get_proc(a_fapi_font,
774
0
                                      gs_fapi_font_feature_DollarBlend, 0,
775
0
                                      (char *)a_output->m_pos);
776
0
            if (a_output->m_pos && len > 0)
777
0
                a_output->m_pos += len;
778
0
            WRF_wstring(a_fapi_font->memory, a_output, "} def\n");
779
0
        } else {
780
0
            WRF_wstring(a_fapi_font->memory, a_output,
781
0
                        "/$Blend {0.1 mul exch 0.45 mul add exch 0.17 mul add add} def\n");
782
0
        }
783
0
        WRF_wstring(a_fapi_font->memory, a_output, "/WeightVector [");
784
0
        code = a_fapi_font->get_word(a_fapi_font,
785
0
                                  gs_fapi_font_feature_WeightVector_count, 0, (unsigned short *)&x);
786
0
        if (code < 0)
787
0
            return code;
788
789
0
        for (i = 0; i < x; i++) {
790
0
            code = a_fapi_font->get_float(a_fapi_font,
791
0
                                        gs_fapi_font_feature_WeightVector, i, &x1);
792
0
            if (code < 0)
793
0
                return code;
794
795
0
            gs_snprintf(Buffer, sizeof(Buffer), "%f ", x1);
796
0
            WRF_wstring(a_fapi_font->memory, a_output, Buffer);
797
0
        }
798
0
        WRF_wstring(a_fapi_font->memory, a_output, "] def\n");
799
800
0
        WRF_wstring(a_fapi_font->memory, a_output, "/Blend 3 dict dup begin\n");
801
0
        WRF_wstring(a_fapi_font->memory, a_output, "/FontBBox {");
802
0
        code = a_fapi_font->get_word(a_fapi_font,
803
0
                                 gs_fapi_font_feature_BlendFontBBox_length , 0, (unsigned short *)&x);
804
0
        if (code < 0)
805
0
            return code;
806
807
0
        for (i = 0; i < 4; i++) {
808
0
            int j;
809
0
            WRF_wstring(a_fapi_font->memory, a_output, " {");
810
0
            for (j = 0; j < x; j++) {
811
0
                code = a_fapi_font->get_word(a_fapi_font,
812
0
                                  gs_fapi_font_feature_BlendFontBBox,
813
0
                                  j + (i * 4), (unsigned short *)&x2);
814
0
                if (code < 0)
815
0
                    return code;
816
817
0
                WRF_wint(a_fapi_font->memory, a_output, x2);
818
0
                WRF_wbyte(a_fapi_font->memory, a_output, (byte)' ');
819
0
            }
820
0
            WRF_wstring(a_fapi_font->memory, a_output, "}");
821
0
        }
822
0
        WRF_wstring(a_fapi_font->memory, a_output, " } def\n");
823
0
        WRF_wstring(a_fapi_font->memory, a_output, "/Private 14 dict def\n");
824
0
        WRF_wstring(a_fapi_font->memory, a_output, "end def\n");
825
0
#undef TEMP_BUF_LEN
826
0
    }
827
107k
    WRF_wstring(a_fapi_font->memory, a_output, "currentdict end\ncurrentfile eexec\n");
828
829
107k
    return write_private_dictionary(a_fapi_font, a_output, Write_CharStrings);
830
107k
}
831
832
/**
833
Write a Type 1 font in textual format and return its length in bytes.
834
If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
835
length is returned correctly.
836
837
The PostScript is non-standard. The main dictionary contains no /Charstrings dictionary. This
838
is supplied to FreeType using the incremental interface, There is also no /PaintType entry. This is required
839
by PostScript but FreeType doesn't use it.
840
*/
841
long
842
gs_fapi_serialize_type1_font(gs_fapi_font * a_fapi_font,
843
                             unsigned char *a_buffer, long a_buffer_size)
844
107k
{
845
107k
    int code;
846
107k
    WRF_output output;
847
848
107k
    WRF_init(&output, a_buffer, a_buffer_size);
849
850
    /* Leading comment identifying a Type 1 font. */
851
107k
    WRF_wstring(a_fapi_font->memory, &output, "%!PS-AdobeFont-1\n");
852
853
107k
    code = write_main_dictionary(a_fapi_font, &output, 0);
854
107k
    if (code < 0)
855
0
        return (long)code;
856
#if 0
857
    {
858
        extern FILE *stdout;
859
        if (a_buffer && a_buffer_size >= output.m_count) {
860
            fwrite(a_buffer, 1, output.m_count, stdout);
861
        }
862
    }
863
#endif
864
865
107k
    return output.m_count;
866
107k
}
867
868
long
869
gs_fapi_serialize_type1_font_complete(gs_fapi_font * a_fapi_font,
870
                                      unsigned char *a_buffer,
871
                                      long a_buffer_size)
872
0
{
873
0
    int code;
874
0
    WRF_output output;
875
876
0
    WRF_init(&output, a_buffer, a_buffer_size);
877
878
    /* Leading comment identifying a Type 1 font. */
879
0
    WRF_wstring(a_fapi_font->memory, &output, "%!PS-AdobeFont-1\n");
880
881
0
    code = write_main_dictionary(a_fapi_font, &output, 1);
882
0
    if (code < 0)
883
0
        return (long)code;
884
885
0
    return output.m_count;
886
0
}