Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/write_t1.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 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
1.39M
{
35
1.39M
    short x;
36
1.39M
    int code;
37
38
1.39M
    WRF_wbyte(a_fapi_font->memory, a_output, '/');
39
1.39M
    WRF_wstring(a_fapi_font->memory, a_output, a_name);
40
1.39M
    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
1.39M
    code = a_fapi_font->get_word(a_fapi_font, a_index, 0, (unsigned short *)&x);
44
1.39M
    if (code < 0)
45
0
        return code;
46
47
    /* Divide by the divisor to bring it back to font units. */
48
1.39M
    x = (short)(x / a_divisor);
49
1.39M
    WRF_wint(a_fapi_font->memory, a_output, x);
50
1.39M
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
51
52
1.39M
    return 0;
53
1.39M
}
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
3.72M
{
60
3.72M
    int i, code;;
61
62
3.72M
    if (a_count <= 0)
63
1.79M
        return 0;
64
65
1.93M
    WRF_wbyte(a_fapi_font->memory, a_output, '/');
66
1.93M
    WRF_wstring(a_fapi_font->memory, a_output, a_name);
67
1.93M
    WRF_wstring(a_fapi_font->memory, a_output, " [");
68
11.1M
    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
9.24M
        short x;
71
9.24M
        code = a_fapi_font->get_word(a_fapi_font, a_index, i, (unsigned short *)&x);
72
9.24M
        if (code < 0)
73
0
            return code;
74
75
        /* Divide by the divisor to bring it back to font units. */
76
9.24M
        x = (short)(x / a_divisor);
77
9.24M
        WRF_wint(a_fapi_font->memory, a_output, x);
78
9.24M
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == a_count - 1 ? ']' : ' '));
79
9.24M
    }
80
1.93M
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
81
82
1.93M
    return 0;
83
1.93M
}
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
2.79M
{
89
    /* NOTE that the feature index must be preceded by the count index for this to work. */
90
2.79M
    unsigned short count;
91
2.79M
    int code = a_fapi_font->get_word(a_fapi_font, a_index - 1, 0, &count);
92
93
2.79M
    if (code < 0)
94
0
        return code;
95
96
2.79M
    return write_array_entry_with_count(a_fapi_font, a_output, a_name, a_index,
97
2.79M
                                 count, a_divisor);
98
2.79M
}
99
100
static int
101
write_subrs(gs_fapi_font * a_fapi_font, WRF_output * a_output, int raw)
102
466k
{
103
466k
    int i;
104
466k
    unsigned short count;
105
466k
    int code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count,
106
466k
                              0, &count);
107
466k
    if (code < 0)
108
0
        return code;
109
110
466k
    if (count > 0) {
111
464k
        WRF_wstring(a_fapi_font->memory, a_output, "/Subrs ");
112
464k
        WRF_wint(a_fapi_font->memory, a_output, count);
113
464k
        WRF_wstring(a_fapi_font->memory, a_output, " array\n");
114
115
3.34M
        for (i = 0; i < count; i++) {
116
2.88M
            int length;
117
2.88M
            int buffer_size;
118
119
120
2.88M
            if (raw)
121
0
                length = a_fapi_font->get_raw_subr(a_fapi_font, i, 0, 0);
122
2.88M
            else
123
2.88M
                length = a_fapi_font->get_subr(a_fapi_font, i, 0, 0);
124
2.88M
            if (length < 0)
125
0
                return length;
126
127
2.88M
            WRF_wstring(a_fapi_font->memory, a_output, "dup ");
128
2.88M
            WRF_wint(a_fapi_font->memory, a_output, i);
129
2.88M
            WRF_wbyte(a_fapi_font->memory, a_output, ' ');
130
2.88M
            WRF_wint(a_fapi_font->memory, a_output, length);
131
2.88M
            WRF_wstring(a_fapi_font->memory, a_output, " RD ");
132
133
            /* Get the subroutine into the buffer and encrypt it in place. */
134
2.88M
            buffer_size = a_output->m_limit - a_output->m_count;
135
2.88M
            if (buffer_size >= length) {
136
1.43M
                int l2;
137
138
1.43M
                if (raw)
139
0
                    l2 = a_fapi_font->get_raw_subr(a_fapi_font, i, a_output->m_pos,
140
0
                                              (ushort) length);
141
1.43M
                else
142
1.43M
                    l2 = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos,
143
1.43M
                                          (ushort) length);
144
1.43M
                if (l2 < 0)
145
0
                    return l2;
146
147
1.43M
                WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length);
148
1.43M
            } else
149
1.44M
                a_output->m_count += length;
150
151
2.88M
            WRF_wstring(a_fapi_font->memory, a_output, " NP\n");
152
2.88M
        }
153
154
464k
        WRF_wstring(a_fapi_font->memory, a_output, "ND\n");
155
464k
    }
156
466k
    return 0;
157
466k
}
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
932k
{
219
932k
    unsigned short db;
220
932k
    int code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_DollarBlend, 0, &db);
221
222
932k
    if (code >= 0 && db == 1)
223
0
        return true;
224
225
932k
    return false;
226
932k
}
227
228
static int
229
write_private_blend_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output)
230
466k
{
231
466k
    short x, x1, x2, i, j, acc;
232
466k
    int code;
233
234
466k
    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
466k
    return 0;
490
466k
}
491
492
static int
493
write_private_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output,
494
                         int Write_CharStrings)
495
466k
{
496
466k
    int code;
497
466k
    unsigned long ulval;
498
466k
    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
466k
    WRF_wstring(a_fapi_font->memory, a_output, "XXXX");
502
503
    /*+ to do: correct size of dictionary from 8. */
504
466k
    WRF_wstring(a_fapi_font->memory, a_output, "dup /Private 8 dict dup begin\n");
505
506
466k
    WRF_wstring(a_fapi_font->memory, a_output, "/MinFeature {16 16} def\n");
507
466k
    WRF_wstring(a_fapi_font->memory, a_output, "/password 5839 def\n");
508
466k
    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
466k
    else {
514
466k
        WRF_wstring(a_fapi_font->memory, a_output, "/lenIV -1 def\n");       /* indicate that /subrs are not encoded. */
515
466k
    }
516
466k
    code = write_word_entry(a_fapi_font, a_output, "BlueFuzz", gs_fapi_font_feature_BlueFuzz, 16);
517
466k
    if (code < 0)
518
0
        return code;
519
520
466k
    WRF_wstring(a_fapi_font->memory, a_output, "/BlueScale ");
521
466k
    code = a_fapi_font->get_long(a_fapi_font,gs_fapi_font_feature_BlueScale, 0, &ulval);
522
466k
    if (code < 0)
523
0
        return code;
524
525
466k
    WRF_wfloat(a_fapi_font->memory, a_output, (float)ulval/65536.0);
526
527
466k
    WRF_wstring(a_fapi_font->memory, a_output, " def\n");
528
529
466k
    code = write_word_entry(a_fapi_font, a_output, "BlueShift", gs_fapi_font_feature_BlueShift, 16);
530
466k
    if (code < 0)
531
0
        return code;
532
533
466k
    code = write_array_entry(a_fapi_font, a_output, "BlueValues",
534
466k
                      gs_fapi_font_feature_BlueValues, 16);
535
466k
    if (code < 0)
536
0
        return code;
537
538
466k
    code = write_array_entry(a_fapi_font, a_output, "OtherBlues",
539
466k
                      gs_fapi_font_feature_OtherBlues, 16);
540
466k
    if (code < 0)
541
0
        return code;
542
543
466k
    code = write_array_entry(a_fapi_font, a_output, "FamilyBlues",
544
466k
                      gs_fapi_font_feature_FamilyBlues, 16);
545
466k
    if (code < 0)
546
0
        return code;
547
548
466k
    code = write_array_entry(a_fapi_font, a_output, "FamilyOtherBlues",
549
466k
                      gs_fapi_font_feature_FamilyOtherBlues, 16);
550
466k
    if (code < 0)
551
0
        return code;
552
553
466k
    code = write_word_entry(a_fapi_font, a_output, "ForceBold", gs_fapi_font_feature_ForceBold, 1);
554
466k
    if (code < 0)
555
0
        return code;
556
557
466k
    code = write_array_entry_with_count(a_fapi_font, a_output, "StdHW",
558
466k
                                 gs_fapi_font_feature_StdHW, 1, 16);
559
466k
    if (code < 0)
560
0
        return code;
561
562
466k
    code = write_array_entry_with_count(a_fapi_font, a_output, "StdVW",
563
466k
                                 gs_fapi_font_feature_StdVW, 1, 16);
564
466k
    if (code < 0)
565
0
        return code;
566
567
466k
    code = write_array_entry(a_fapi_font, a_output, "StemSnapH",
568
466k
                      gs_fapi_font_feature_StemSnapH, 16);
569
466k
    if (code < 0)
570
0
        return code;
571
572
466k
    code = write_array_entry(a_fapi_font, a_output, "StemSnapV",
573
466k
                      gs_fapi_font_feature_StemSnapV, 16);
574
466k
    if (code < 0)
575
0
        return code;
576
577
466k
    code = write_private_blend_dictionary(a_fapi_font, a_output);
578
466k
    if (code < 0)
579
0
        return code;
580
581
466k
    if (Write_CharStrings)
582
0
        code = write_subrs(a_fapi_font, a_output, 1);
583
466k
    else
584
466k
        code = write_subrs(a_fapi_font, a_output, 0);
585
466k
    if (code < 0)
586
0
        return code;
587
588
466k
    if (Write_CharStrings)
589
0
        code = write_charstrings(a_fapi_font, a_output);
590
591
466k
    return code;
592
466k
}
593
594
static int
595
write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output, int Write_CharStrings)
596
466k
{
597
466k
    int i, code;
598
466k
    float fval;
599
600
466k
    WRF_wstring(a_fapi_font->memory, a_output, "5 dict begin\n");
601
602
466k
    WRF_wstring(a_fapi_font->memory, a_output, "/FontType 1 def\n");
603
604
466k
    WRF_wstring(a_fapi_font->memory, a_output, "/FontMatrix [");
605
3.26M
    for (i = 0; i < 6; i++) {
606
2.79M
        code = a_fapi_font->get_float(a_fapi_font, gs_fapi_font_feature_FontMatrix, i, &fval);
607
2.79M
        if (code < 0)
608
0
            return code;
609
610
2.79M
        WRF_wfloat(a_fapi_font->memory, a_output, fval);
611
2.79M
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == 5 ? ']' : ' '));
612
2.79M
    }
613
466k
    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
466k
    WRF_wstring(a_fapi_font->memory, a_output, "/Encoding StandardEncoding def\n");
616
617
466k
    WRF_wstring(a_fapi_font->memory, a_output, "/FontBBox {");
618
2.33M
    for (i = 0; i < 4; i++) {
619
1.86M
        short x;
620
1.86M
        code = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_FontBBox,
621
1.86M
                                  i, (unsigned short *)&x);
622
1.86M
        if (code < 0)
623
0
            return code;
624
625
1.86M
        WRF_wint(a_fapi_font->memory, a_output, x);
626
1.86M
        WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == 3 ? '}' : ' '));
627
1.86M
    }
628
466k
    WRF_wbyte(a_fapi_font->memory, a_output, '\n');
629
466k
    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_snprintf(Buffer, sizeof(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_snprintf(Buffer, sizeof(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_snprintf(Buffer, sizeof(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_snprintf(Buffer, sizeof(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_snprintf(Buffer, sizeof(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
#undef TEMP_BUF_LEN
825
0
    }
826
466k
    WRF_wstring(a_fapi_font->memory, a_output, "currentdict end\ncurrentfile eexec\n");
827
828
466k
    return write_private_dictionary(a_fapi_font, a_output, Write_CharStrings);
829
466k
}
830
831
/**
832
Write a Type 1 font in textual format and return its length in bytes.
833
If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
834
length is returned correctly.
835
836
The PostScript is non-standard. The main dictionary contains no /Charstrings dictionary. This
837
is supplied to FreeType using the incremental interface, There is also no /PaintType entry. This is required
838
by PostScript but FreeType doesn't use it.
839
*/
840
long
841
gs_fapi_serialize_type1_font(gs_fapi_font * a_fapi_font,
842
                             unsigned char *a_buffer, long a_buffer_size)
843
466k
{
844
466k
    int code;
845
466k
    WRF_output output;
846
847
466k
    WRF_init(&output, a_buffer, a_buffer_size);
848
849
    /* Leading comment identifying a Type 1 font. */
850
466k
    WRF_wstring(a_fapi_font->memory, &output, "%!PS-AdobeFont-1\n");
851
852
466k
    code = write_main_dictionary(a_fapi_font, &output, 0);
853
466k
    if (code < 0)
854
0
        return (long)code;
855
#if 0
856
    {
857
        extern FILE *stdout;
858
        if (a_buffer && a_buffer_size >= output.m_count) {
859
            fwrite(a_buffer, 1, output.m_count, stdout);
860
        }
861
    }
862
#endif
863
864
466k
    return output.m_count;
865
466k
}
866
867
long
868
gs_fapi_serialize_type1_font_complete(gs_fapi_font * a_fapi_font,
869
                                      unsigned char *a_buffer,
870
                                      long a_buffer_size)
871
0
{
872
0
    int code;
873
0
    WRF_output output;
874
875
0
    WRF_init(&output, a_buffer, a_buffer_size);
876
877
    /* Leading comment identifying a Type 1 font. */
878
0
    WRF_wstring(a_fapi_font->memory, &output, "%!PS-AdobeFont-1\n");
879
880
0
    code = write_main_dictionary(a_fapi_font, &output, 1);
881
0
    if (code < 0)
882
0
        return (long)code;
883
884
0
    return output.m_count;
885
0
}