Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/pdf/pdf_fapi.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2019-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
/* Interface to FAPI for the PDF interpreter */
17
18
/* Include this first so that we don't get a macro redefnition of 'offsetof' */
19
#include "pdf_int.h"
20
21
#include "memory_.h"
22
#include "gsmemory.h"
23
#include "gserrors.h"
24
#include "gxdevice.h"
25
#include "gxfont.h"
26
#include "gxfont0.h"
27
#include "gxfcid.h"
28
29
#include "gzstate.h"
30
#include "gxchar.h"             /* for st_gs_show_enum */
31
#include "gdebug.h"
32
#include "gxfapi.h"
33
#include "gscoord.h"
34
#include "gspath.h"
35
#include "pdf_dict.h"
36
#include "pdf_array.h"
37
#include "pdf_font.h"
38
#include "gscencs.h"
39
#include "gsagl.h"
40
#include "gxfont1.h"        /* for gs_font_type1_s */
41
#include "gscrypt1.h"       /* for crypt_c1 */
42
43
extern single_glyph_list_t SingleGlyphList[];
44
45
46
/* forward declarations for the pdfi_ff_stub definition */
47
static int
48
pdfi_fapi_get_word(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, unsigned short *ret);
49
50
static int
51
pdfi_fapi_get_long(gs_fapi_font * ff, gs_fapi_font_feature var_id, int index, unsigned long *ret);
52
53
static int
54
pdfi_fapi_get_float(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, float *ret);
55
56
static int
57
pdfi_fapi_get_name(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, char *buffer, int len);
58
59
static int
60
pdfi_fapi_get_proc(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, char *buffer);
61
62
static int
63
pdfi_fapi_get_gsubr(gs_fapi_font *ff, int index, byte *buf, int buf_length);
64
65
static int
66
pdfi_fapi_get_subr(gs_fapi_font *ff, int index, byte *buf, int buf_length);
67
68
static int
69
pdfi_fapi_get_raw_subr(gs_fapi_font *ff, int index, byte *buf, int buf_length);
70
71
static int
72
pdfi_fapi_serialize_tt_font(gs_fapi_font * ff, void *buf, int buf_size);
73
74
static int
75
pdfi_fapi_retrieve_tt_font(gs_fapi_font * ff, void **buf, int *buf_size);
76
77
static int
78
pdfi_fapi_get_charstring(gs_fapi_font *ff, int index, byte *buf, ushort buf_length);
79
80
static int
81
pdfi_fapi_get_charstring_name(gs_fapi_font *ff, int index, byte *buf, ushort buf_length);
82
83
84
static int
85
pdfi_fapi_get_glyphname_or_cid(gs_text_enum_t *penum, gs_font_base * pbfont, gs_string * charstring,
86
                gs_string * name, gs_glyph ccode, gs_string * enc_char_name,
87
                char *font_file_path, gs_fapi_char_ref * cr, bool bCID);
88
89
static int
90
pdfi_fapi_get_glyph(gs_fapi_font * ff, gs_glyph char_code, byte * buf, int buf_length);
91
92
93
static int
94
pdfi_get_glyphdirectory_data(gs_fapi_font * ff, int char_code,
95
                           const byte ** ptr);
96
97
static int
98
pdfi_fapi_set_cache(gs_text_enum_t * penum, const gs_font_base * pbfont,
99
                  const gs_string * char_name, gs_glyph cid,
100
                  const double pwidth[2], const gs_rect * pbbox,
101
                  const double Metrics2_sbw_default[4], bool * imagenow);
102
103
static int
104
pdfi_fapi_get_metrics(gs_fapi_font * ff, gs_string * char_name, gs_glyph cid, double *m, bool vertical);
105
106
static const gs_fapi_font pdfi_ff_stub = {
107
    0,                                              /* server_font_data */
108
    0,                                              /* need_decrypt */
109
    NULL,                                           /* const gs_memory_t */
110
    0,                                              /* font_file_path */
111
    0,                                              /* full_font_buf */
112
    0,                                              /* full_font_buf_len */
113
    0,                                              /* subfont */
114
    false,                                          /* is_type1 */
115
    false,                                          /* is_cid */
116
    false,                                          /* is_outline_font */
117
    false,                                          /* is_mtx_skipped */
118
    false,                                          /* is_vertical */
119
    false,                                          /* metrics_only */
120
    {{3, 1}, {1, 0}, {3, 0}, {3, 10}, {-1, -1}},    /* ttf_cmap_req */
121
    {-1, -1},                                       /* ttf_cmap_selected */
122
    0,                                              /* client_ctx_p */
123
    0,                                              /* client_font_data */
124
    0,                                              /* client_font_data2 */
125
    0,                                              /* char_data */
126
    0,                                              /* char_data_len */
127
    0,                                              /* embolden */
128
    pdfi_fapi_get_word,                             /* get_word */
129
    pdfi_fapi_get_long,                             /* get_long */
130
    pdfi_fapi_get_float,                            /* get_float */
131
    pdfi_fapi_get_name,                             /* get_name */
132
    pdfi_fapi_get_proc,                             /* get_proc */
133
    pdfi_fapi_get_gsubr,                            /* get_gsubr */
134
    pdfi_fapi_get_subr,                             /* get_subr */
135
    pdfi_fapi_get_raw_subr,                         /* get_raw_subr */
136
    pdfi_fapi_get_glyph,                            /* get_glyph */
137
    pdfi_fapi_serialize_tt_font,                    /* serialize_tt_font */
138
    pdfi_fapi_retrieve_tt_font,                     /* retrieve_tt_font */
139
    pdfi_fapi_get_charstring,                       /* get_charstring */
140
    pdfi_fapi_get_charstring_name,                  /* get_charstring_name */
141
    pdfi_get_glyphdirectory_data,                   /* get_GlyphDirectory_data_ptr */
142
    pdfi_fapi_get_glyphname_or_cid,                 /* get_glyphname_or_cid */
143
    pdfi_fapi_get_metrics,                          /* fapi_get_metrics */
144
    pdfi_fapi_set_cache                             /* fapi_set_cache */
145
};
146
147
static inline ushort
148
float_to_ushort(float v)
149
8.89M
{
150
8.89M
    return ((ushort) (v * 16)); /* fixme : the scale may depend on renderer */
151
8.89M
}
152
153
static int
154
pdfi_fapi_get_word(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, unsigned short *ret)
155
14.4M
{
156
14.4M
    int code = 0;
157
14.4M
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
158
159
14.4M
    switch ((int)var_id) {
160
0
        case gs_fapi_font_feature_Weight:
161
0
            *ret = 0;           /* wrong */
162
0
            break;
163
0
        case gs_fapi_font_feature_ItalicAngle:
164
0
            *ret = 0;           /* wrong */
165
0
            break;
166
0
        case gs_fapi_font_feature_IsFixedPitch:
167
0
            *ret = 0;           /* wrong */
168
0
            break;
169
0
        case gs_fapi_font_feature_UnderLinePosition:
170
0
            *ret = 0;           /* wrong */
171
0
            break;
172
0
        case gs_fapi_font_feature_UnderlineThickness:
173
0
            *ret = 0;           /* wrong */
174
0
            break;
175
192k
        case gs_fapi_font_feature_FontType:
176
192k
            *ret = (pfont->FontType == 2 ? 2 : 1);
177
192k
            break;
178
1.53M
        case gs_fapi_font_feature_FontBBox:
179
1.53M
            switch (index) {
180
384k
                case 0:
181
384k
                    *ret = ((ushort) pfont->FontBBox.p.x);
182
384k
                    break;
183
384k
                case 1:
184
384k
                    *ret = ((ushort) pfont->FontBBox.p.y);
185
384k
                    break;
186
384k
                case 2:
187
384k
                    *ret = ((ushort) pfont->FontBBox.q.x);
188
384k
                    break;
189
384k
                case 3:
190
384k
                    *ret = ((ushort) pfont->FontBBox.q.y);
191
384k
                    break;
192
0
                default:
193
0
                    code = gs_note_error(gs_error_rangecheck);
194
1.53M
            }
195
1.53M
            break;
196
1.53M
        case gs_fapi_font_feature_BlueValues_count:
197
384k
            *ret = pfont->data.BlueValues.count;
198
384k
            break;
199
2.98M
        case gs_fapi_font_feature_BlueValues:
200
2.98M
            *ret =  (float_to_ushort(pfont->data.BlueValues.values[index]));
201
2.98M
            break;
202
384k
        case gs_fapi_font_feature_OtherBlues_count:
203
384k
            *ret = pfont->data.OtherBlues.count;
204
384k
            break;
205
14.7k
        case gs_fapi_font_feature_OtherBlues:
206
14.7k
            *ret = (float_to_ushort(pfont->data.OtherBlues.values[index]));
207
14.7k
            break;
208
384k
        case gs_fapi_font_feature_FamilyBlues_count:
209
384k
            *ret = pfont->data.FamilyBlues.count;
210
384k
            break;
211
7.91k
        case gs_fapi_font_feature_FamilyBlues:
212
7.91k
            *ret = (float_to_ushort(pfont->data.FamilyBlues.values[index]));
213
7.91k
            break;
214
384k
        case gs_fapi_font_feature_FamilyOtherBlues_count:
215
384k
            *ret = pfont->data.FamilyOtherBlues.count;
216
384k
            break;
217
6.42k
        case gs_fapi_font_feature_FamilyOtherBlues:
218
6.42k
            *ret = (float_to_ushort(pfont->data.FamilyOtherBlues.values[index]));
219
6.42k
            break;
220
384k
        case gs_fapi_font_feature_BlueShift:
221
384k
            *ret = float_to_ushort(pfont->data.BlueShift);
222
384k
            break;
223
384k
        case gs_fapi_font_feature_BlueFuzz:
224
384k
            *ret = float_to_ushort(pfont->data.BlueShift);
225
384k
            break;
226
384k
        case gs_fapi_font_feature_StdHW:
227
384k
            *ret = (pfont->data.StdHW.count == 0 ? 0 : float_to_ushort(pfont->data.StdHW.values[0]));   /* UFST bug ? */
228
384k
            break;
229
384k
        case gs_fapi_font_feature_StdVW:
230
384k
            *ret = (pfont->data.StdVW.count == 0 ? 0 : float_to_ushort(pfont->data.StdVW.values[0]));   /* UFST bug ? */
231
384k
            break;
232
384k
        case gs_fapi_font_feature_StemSnapH_count:
233
384k
            *ret = pfont->data.StemSnapH.count;
234
384k
            break;
235
4.33M
        case gs_fapi_font_feature_StemSnapH:
236
4.33M
            *ret = float_to_ushort(pfont->data.StemSnapH.values[index]);
237
4.33M
            break;
238
384k
        case gs_fapi_font_feature_StemSnapV_count:
239
384k
            *ret = pfont->data.StemSnapV.count;
240
384k
            break;
241
7.88k
        case gs_fapi_font_feature_StemSnapV:
242
7.88k
            *ret = float_to_ushort(pfont->data.StemSnapV.values[index]);
243
7.88k
            break;
244
384k
        case gs_fapi_font_feature_ForceBold:
245
384k
            *ret = pfont->data.ForceBold;
246
384k
            break;
247
0
        case gs_fapi_font_feature_LanguageGroup:
248
0
            *ret = pfont->data.LanguageGroup;
249
0
            break;
250
0
        case gs_fapi_font_feature_lenIV:
251
0
            *ret = ff->need_decrypt ? 0 : pfont->data.lenIV;
252
0
            break;
253
5.90k
        case gs_fapi_font_feature_GlobalSubrs_count:
254
5.90k
            {
255
5.90k
                if (pfont->FontType == ft_encrypted2) {
256
5.90k
                    pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
257
5.90k
                    *ret = pdffont2->GlobalSubrs == NULL ? 0 : pdfi_array_size(pdffont2->GlobalSubrs);
258
5.90k
                }
259
0
                else {
260
0
                    *ret = 0;
261
0
                    code = gs_note_error(gs_error_invalidaccess);
262
0
                }
263
5.90k
                break;
264
1.53M
            }
265
390k
        case gs_fapi_font_feature_Subrs_count:
266
390k
            {
267
390k
                if (pfont->FontType == ft_encrypted) {
268
378k
                    pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
269
378k
                    *ret = pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs);
270
378k
                }
271
11.8k
                else if (pfont->FontType == ft_encrypted2) {
272
11.8k
                    pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
273
11.8k
                    *ret = pdffont2->Subrs == NULL ? 0 : pdfi_array_size(pdffont2->Subrs);
274
11.8k
                }
275
0
                else {
276
0
                    *ret = 0;
277
0
                    code = gs_note_error(gs_error_invalidaccess);
278
0
                }
279
390k
                break;
280
1.53M
            }
281
0
        case gs_fapi_font_feature_CharStrings_count:
282
0
            {
283
0
                if (pfont->FontType == ft_encrypted) {
284
0
                    pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
285
0
                    *ret = pdffont1->CharStrings->entries;
286
0
                }
287
0
                break;
288
1.53M
            }
289
0
        case gs_fapi_font_feature_BlendBlueValues_length:
290
0
        case gs_fapi_font_feature_BlendOtherBlues_length:
291
0
        case gs_fapi_font_feature_BlendOtherBlues_count:
292
0
        case gs_fapi_font_feature_BlendBlueScale_count:
293
0
        case gs_fapi_font_feature_BlendBlueShift_count:
294
0
        case gs_fapi_font_feature_BlendBlueShift:
295
0
        case gs_fapi_font_feature_BlendBlueFuzz_count:
296
0
        case gs_fapi_font_feature_BlendBlueFuzz:
297
0
        case gs_fapi_font_feature_BlendForceBold_count:
298
0
        case gs_fapi_font_feature_BlendForceBold:
299
0
        case gs_fapi_font_feature_BlendStdHW_length:
300
0
        case gs_fapi_font_feature_BlendStdHW_count:
301
0
        case gs_fapi_font_feature_BlendStdHW:
302
0
        case gs_fapi_font_feature_BlendStdVW_length:
303
0
        case gs_fapi_font_feature_BlendStdVW_count:
304
0
        case gs_fapi_font_feature_BlendStdVW:
305
0
        case gs_fapi_font_feature_BlendStemSnapH_length:
306
0
        case gs_fapi_font_feature_BlendStemSnapH_count:
307
0
        case gs_fapi_font_feature_BlendStemSnapH:
308
0
        case gs_fapi_font_feature_BlendStemSnapV_length:
309
0
        case gs_fapi_font_feature_BlendStemSnapV_count:
310
0
        case gs_fapi_font_feature_BlendStemSnapV:
311
0
            {
312
0
                code = 0;
313
0
                *ret = 0;
314
0
            }
315
0
            break;
316
756k
        case gs_fapi_font_feature_DollarBlend:
317
756k
            {
318
756k
                if (pfont->data.WeightVector.count > 0) { /* If count > 0, it's MM font, and we "have" a $Blend */
319
0
                    *ret = 1;
320
0
                }
321
756k
                else {
322
756k
                    *ret = 0;
323
756k
                }
324
756k
            }
325
756k
            break;
326
0
        case gs_fapi_font_feature_DollarBlend_length:
327
0
            {
328
                /* Use the built-in boiler plate */
329
0
                *ret = 0;
330
0
            }
331
0
            break;
332
0
        case gs_fapi_font_feature_BlendAxisTypes_count:
333
0
            {
334
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
335
0
                if (pdffont1->blendaxistypes != NULL) {
336
0
                    *ret = (unsigned short)pdffont1->blendaxistypes->size;
337
0
                }
338
0
                else {
339
0
                    *ret = 0;
340
0
                }
341
0
            }
342
0
            break;
343
0
        case gs_fapi_font_feature_WeightVector_count:
344
0
            {
345
0
                *ret = (unsigned short)pfont->data.WeightVector.count;
346
0
            }
347
0
            break;
348
0
        case gs_fapi_font_feature_BlendDesignPositionsArrays_count:
349
0
            {
350
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
351
0
                if (pdffont1->blenddesignpositions != NULL) {
352
0
                    *ret = (unsigned short)pdffont1->blenddesignpositions->size;
353
0
                }
354
0
                else {
355
0
                    *ret = 0;
356
0
                }
357
0
            }
358
0
            break;
359
0
        case gs_fapi_font_feature_BlendDesignMapArrays_count:
360
0
            {
361
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
362
0
                if (pdffont1->blenddesignmap != NULL) {
363
0
                    *ret = (unsigned short)pdffont1->blenddesignmap->size;
364
0
                }
365
0
                else {
366
0
                    *ret = 0;
367
0
                }
368
0
            }
369
0
            break;
370
0
        case gs_fapi_font_feature_BlendDesignMapSubArrays_count:
371
0
            {
372
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
373
0
                if (pdffont1->blenddesignmap != NULL) {
374
0
                    pdf_array *suba;
375
0
                    code = pdfi_array_get(pdffont1->ctx, pdffont1->blenddesignmap, index, (pdf_obj **)&suba);
376
0
                    if (code < 0) {
377
0
                        *ret = 0;
378
0
                        break;
379
0
                    }
380
0
                    *ret = (unsigned short)suba->size;
381
0
                    pdfi_countdown(suba);
382
0
                }
383
0
                else {
384
0
                    *ret = 0;
385
0
                }
386
0
            }
387
0
            break;
388
0
        case gs_fapi_font_feature_BlendFontBBox_length:
389
0
            {
390
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
391
0
                if (pdffont1->blendfontbbox != NULL) {
392
0
                    *ret = (unsigned short)pdffont1->blendfontbbox->size;
393
0
                }
394
0
                else {
395
0
                    *ret = 0;
396
0
                }
397
0
            }
398
0
            break;
399
0
        case gs_fapi_font_feature_BlendFontBBox:
400
0
            {
401
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
402
0
                if (pdffont1->blendfontbbox != NULL) {
403
0
                    pdf_array *suba;
404
0
                    double d;
405
0
                    int ind, aind;
406
0
                    ind = index % 4;
407
0
                    aind = (index - ind) / 4;
408
0
                    code = pdfi_array_get(pdffont1->ctx, pdffont1->blendfontbbox, aind, (pdf_obj **)&suba);
409
0
                    if (code < 0) {
410
0
                        *ret = 0;
411
0
                        break;
412
0
                    }
413
0
                    code = pdfi_array_get_number(pdffont1->ctx, suba, ind, &d);
414
0
                    pdfi_countdown(suba);
415
0
                    if (code < 0) {
416
0
                        *ret = 0;
417
0
                        break;
418
0
                    }
419
0
                    *ret = (unsigned short)d;
420
0
                }
421
0
                else {
422
0
                    *ret = 0;
423
0
                }
424
0
            }
425
0
            break;
426
0
        default:
427
0
            code = gs_error_undefined;
428
0
            *ret = -1;
429
14.4M
    }
430
14.4M
    return code;
431
14.4M
}
432
433
static int
434
pdfi_fapi_get_long(gs_fapi_font * ff, gs_fapi_font_feature var_id, int index, unsigned long *ret)
435
384k
{
436
384k
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
437
384k
    int code = 0;
438
439
384k
    switch ((int)var_id) {
440
0
        case gs_fapi_font_feature_UniqueID:
441
0
            *ret = pfont->UID.id;
442
0
            break;
443
384k
        case gs_fapi_font_feature_BlueScale:
444
384k
            *ret = (ulong) (pfont->data.BlueScale * 65536);
445
384k
            break;
446
0
        case gs_fapi_font_feature_Subrs_total_size:
447
0
            {
448
0
                if (pfont->FontType == ft_encrypted) {
449
0
                    pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
450
0
                    int i;
451
0
                    *ret = 0;
452
0
                    for (i = 0; i < (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs)); i++) {
453
0
                        pdf_string *subr_str = NULL;
454
0
                        code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, i, PDF_STRING, (pdf_obj **)&subr_str);
455
0
                        if (code >= 0) {
456
0
                             *ret += subr_str->length;
457
0
                        }
458
0
                        pdfi_countdown(subr_str);
459
0
                    }
460
0
                }
461
0
            }
462
0
            break;
463
0
        default:
464
0
            code = gs_error_undefined;
465
0
            break;
466
384k
    }
467
384k
    return code;
468
384k
}
469
470
static int
471
pdfi_fapi_get_float(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, float *ret)
472
2.30M
{
473
2.30M
    gs_font_base *pbfont = (gs_font_base *) ff->client_font_data2;
474
2.30M
    int code = 0;
475
2.30M
    gs_fapi_server *I = pbfont->FAPI;
476
477
2.30M
    switch ((int)var_id) {
478
2.30M
        case gs_fapi_font_feature_FontMatrix:
479
2.30M
            {
480
2.30M
                double FontMatrix_div;
481
2.30M
                gs_matrix m, *mptr;
482
483
2.30M
                if (I && I->get_fontmatrix) {
484
2.30M
                    FontMatrix_div = 1;
485
2.30M
                    mptr = &m;
486
2.30M
                    I->get_fontmatrix(I, mptr);
487
2.30M
                }
488
0
                else {
489
0
                    FontMatrix_div = ((ff->is_cid && (!FAPI_ISCIDFONT(pbfont))) ? 1000 : 1);
490
0
                    mptr = &(pbfont->base->FontMatrix);
491
0
                }
492
2.30M
                switch (index) {
493
384k
                    case 0:
494
384k
                    default:
495
384k
                        *ret = (mptr->xx / FontMatrix_div);
496
384k
                        break;
497
384k
                    case 1:
498
384k
                        *ret = (mptr->xy / FontMatrix_div);
499
384k
                        break;
500
384k
                    case 2:
501
384k
                        *ret = (mptr->yx / FontMatrix_div);
502
384k
                        break;
503
384k
                    case 3:
504
384k
                        *ret = (mptr->yy / FontMatrix_div);
505
384k
                        break;
506
384k
                    case 4:
507
384k
                        *ret = (mptr->tx / FontMatrix_div);
508
384k
                        break;
509
384k
                    case 5:
510
384k
                        *ret = (mptr->ty / FontMatrix_div);
511
384k
                        break;
512
2.30M
                }
513
2.30M
                break;
514
2.30M
            }
515
2.30M
        case gs_fapi_font_feature_WeightVector:
516
0
            {
517
0
                gs_font_type1 *pfont1 = (gs_font_type1 *) pbfont;
518
0
                if (index < pfont1->data.WeightVector.count) {
519
0
                    *ret = pfont1->data.WeightVector.values[index];
520
0
                }
521
0
                else {
522
0
                    *ret = 0;
523
0
                }
524
0
            }
525
0
            break;
526
0
        case gs_fapi_font_feature_BlendDesignPositionsArrayValue:
527
0
            {
528
0
                int array_index, subind;
529
0
                pdf_array *suba;
530
0
                double d;
531
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pbfont->client_data;
532
0
                *ret = 0;
533
534
0
                code = pdfi_array_get(pdffont1->ctx, pdffont1->blenddesignpositions, 0, (pdf_obj **)&suba);
535
0
                if (code < 0)
536
0
                    break;
537
538
                /* The FAPI code assumes gs style storage - i.e. it allocates the maximum number of entries
539
                   permissable by the spec, and fills in only those required.
540
                   pdfi doesn't, so we unpick that here
541
                 */
542
0
                index = (index % 8) + (suba->size * index / 8);
543
544
0
                array_index = index / suba->size;
545
0
                subind = index % suba->size;
546
0
                pdfi_countdown(suba);
547
0
                code = pdfi_array_get(pdffont1->ctx, pdffont1->blenddesignpositions, array_index, (pdf_obj**)&suba);
548
0
                if (code < 0) {
549
0
                    code = 0;
550
0
                    break;
551
0
                }
552
553
0
                code = pdfi_array_get_number(pdffont1->ctx, suba, subind, &d);
554
0
                pdfi_countdown(suba);
555
0
                if (code < 0) {
556
0
                    code = 0;
557
0
                    break;
558
0
                }
559
0
                *ret = (float)d;
560
0
            }
561
0
            break;
562
0
        case gs_fapi_font_feature_BlendDesignMapArrayValue:
563
0
            {
564
0
                int i, j, k;
565
0
                pdf_array *suba, *subsuba;
566
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pbfont->client_data;
567
0
                *ret = (float)0;
568
0
                code = 0;
569
570
0
                for (i = 0; i < pdffont1->blenddesignmap->size && code >= 0; i++) {
571
0
                    code = pdfi_array_get(pdffont1->ctx, pdffont1->blenddesignmap, i, (pdf_obj **)&suba);
572
0
                    if (code < 0)
573
0
                        continue;
574
0
                    for (j = 0; j < suba->size && code >= 0; j++) {
575
0
                        code = pdfi_array_get(pdffont1->ctx, suba, i, (pdf_obj **)&subsuba);
576
0
                        if (code < 0)
577
0
                            continue;
578
0
                        for (k = 0; k < subsuba->size && code >= 0; k++) {
579
                            /* The FAPI code assumes gs style storage - i.e. it allocates the maximum number of entries
580
                               permissable by the spec, and fills in only those required.
581
                               pdfi doesn't, hence the multiplications by 64.
582
                             */
583
0
                            if ((i * 64) + (j * 64) + k  == index) {
584
0
                                double d;
585
0
                                code = pdfi_array_get_number(pdffont1->ctx, suba, i, &d);
586
0
                                if (code < 0)
587
0
                                    continue;
588
0
                                *ret = (float)d;
589
0
                                pdfi_countdown(subsuba);
590
0
                                pdfi_countdown(suba);
591
0
                                goto gotit;
592
0
                            }
593
0
                        }
594
0
                        pdfi_countdown(subsuba);
595
0
                    }
596
0
                    pdfi_countdown(suba);
597
0
                }
598
0
                code = 0;
599
0
            }
600
0
gotit:
601
0
            break;
602
603
0
        default:
604
0
            code = gs_error_undefined;
605
2.30M
    }
606
607
2.30M
    return code;
608
2.30M
}
609
610
/* Only required for multiple masters, I believe. Buffer is guaranteed to exist */
611
static int
612
pdfi_fapi_get_name(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, char *buffer, int len)
613
0
{
614
0
    gs_font_base *pbfont = (gs_font_base *) ff->client_font_data2;
615
0
    int code = 0;
616
617
0
    switch ((int)var_id) {
618
0
        case gs_fapi_font_feature_BlendAxisTypes:
619
0
            {
620
0
                pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pbfont->client_data;
621
0
                pdf_name *n;
622
0
                code = pdfi_array_get(pdffont1->ctx, pdffont1->blendaxistypes, index, (pdf_obj **)&n);
623
0
                if (code < 0)
624
0
                    break;
625
0
                if (n->length <= len - 1) {
626
0
                    memcpy(buffer, n->data, n->length);
627
0
                    buffer[n->length] = '\0';
628
0
                }
629
0
                else
630
0
                    code = gs_error_limitcheck;
631
0
                pdfi_countdown(n);
632
0
            }
633
0
            break;
634
0
        default:
635
0
            code = gs_error_undefined;
636
0
    }
637
0
    return code;
638
0
}
639
640
/* Only required for multiple masters, I believe */
641
static int
642
pdfi_fapi_get_proc(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, char *buffer)
643
0
{
644
0
    int code = 0;
645
646
0
    (void)index;
647
0
    (void)buffer;
648
649
0
    switch ((int)var_id) {
650
0
        case gs_fapi_font_feature_DollarBlend:
651
0
            break;
652
0
        default:
653
0
            code = gs_error_undefined;
654
0
    }
655
0
    return code;
656
0
}
657
658
static inline void
659
decode_bytes(byte *p, const byte *s, int l, int lenIV)
660
3.37M
{
661
3.37M
    ushort state = 4330;
662
663
202M
    for (; l; s++, l--) {
664
199M
        uchar c = (*s ^ (state >> 8));
665
666
199M
        state = (*s + state) * crypt_c1 + crypt_c2;
667
199M
        if (lenIV > 0)
668
13.3M
            lenIV--;
669
185M
        else {
670
185M
            *p = c;
671
185M
            p++;
672
185M
        }
673
199M
    }
674
3.37M
}
675
676
static int
677
pdfi_fapi_get_gsubr(gs_fapi_font *ff, int index, byte *buf, int buf_length)
678
320k
{
679
320k
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
680
320k
    int code = 0;
681
320k
    if (pfont->FontType == ft_encrypted2) {
682
320k
        pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
683
320k
        if (index > (pdffont2->GlobalSubrs == NULL ? 0 : pdfi_array_size(pdffont2->GlobalSubrs))) {
684
0
            code = gs_error_rangecheck;
685
0
        }
686
320k
        else {
687
320k
            int leniv = (pfont->data.lenIV > 0 ? pfont->data.lenIV : 0);
688
320k
            pdf_string *subrstring = NULL;
689
690
320k
            code = pdfi_array_get(pdffont2->ctx, pdffont2->GlobalSubrs, index, (pdf_obj **)&subrstring);
691
320k
            if (code >= 0) {
692
320k
                if (pdfi_type_of(subrstring) == PDF_STRING) {
693
320k
                    code = subrstring->length - leniv;
694
320k
                    if (buf && buf_length >= code) {
695
158k
                        if (ff->need_decrypt && pfont->data.lenIV >= 0) {
696
0
                            decode_bytes(buf, subrstring->data, code + leniv, pfont->data.lenIV);
697
0
                        }
698
158k
                        else {
699
158k
                            memcpy(buf, subrstring->data, code);
700
158k
                        }
701
158k
                    }
702
320k
                }
703
12
                else {
704
12
                    code = gs_note_error(gs_error_invalidfont);
705
12
                }
706
320k
                pdfi_countdown(subrstring);
707
320k
            }
708
320k
        }
709
320k
    }
710
0
    else {
711
0
        code = gs_note_error(gs_error_invalidfont);
712
0
    }
713
320k
    return code;
714
320k
}
715
716
static int
717
pdfi_fapi_get_subr(gs_fapi_font *ff, int index, byte *buf, int buf_length)
718
3.70M
{
719
3.70M
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
720
3.70M
    int code = 0;
721
722
3.70M
    if (pfont->FontType == ft_encrypted) {
723
3.66M
        pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
724
3.66M
        if (index > (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs))) {
725
0
            code = gs_note_error(gs_error_rangecheck);
726
0
        }
727
3.66M
        else {
728
3.66M
            int leniv = (pfont->data.lenIV > 0 ? pfont->data.lenIV : 0);
729
3.66M
            pdf_string *subr_str = NULL;
730
731
3.66M
            code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, index, PDF_STRING, (pdf_obj **)&subr_str);
732
3.66M
            if (code >= 0) {
733
3.66M
                 code = subr_str->length - leniv;
734
3.66M
                 if (buf && buf_length >= code) {
735
1.21M
                     if (ff->need_decrypt && pfont->data.lenIV >= 0) {
736
1.21M
                         decode_bytes(buf, subr_str->data, code + leniv, pfont->data.lenIV);
737
1.21M
                     }
738
0
                     else {
739
0
                         memcpy(buf, subr_str->data, code);
740
0
                     }
741
1.21M
                 }
742
3.66M
            }
743
0
            else {
744
                /* Ignore invalid or missing subrs */
745
0
                code = 0;
746
0
            }
747
3.66M
            pdfi_countdown(subr_str);
748
3.66M
        }
749
3.66M
    }
750
38.5k
    else if (pfont->FontType == ft_encrypted2) {
751
38.5k
        pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
752
38.5k
        if (index > (pdffont2->Subrs == NULL ? 0 : pdfi_array_size(pdffont2->Subrs))) {
753
0
            code = gs_error_rangecheck;
754
0
        }
755
38.5k
        else {
756
38.5k
            int leniv = (pfont->data.lenIV > 0 ? pfont->data.lenIV : 0);
757
38.5k
            pdf_string *subrstring;
758
759
38.5k
            if (pdffont2->Subrs == NULL)
760
0
                code = gs_note_error(gs_error_invalidfont);
761
38.5k
            else
762
38.5k
                code = pdfi_array_get(pdffont2->ctx, pdffont2->Subrs, index, (pdf_obj **)&subrstring);
763
38.5k
            if (code >= 0) {
764
38.5k
                if (pdfi_type_of(subrstring) == PDF_STRING) {
765
38.4k
                    if (subrstring->length > 0) {
766
36.9k
                        code = subrstring->length - leniv;
767
36.9k
                        if (buf && buf_length >= code) {
768
18.1k
                            if (ff->need_decrypt && pfont->data.lenIV >= 0) {
769
0
                                decode_bytes(buf, subrstring->data, code + leniv, pfont->data.lenIV);
770
0
                            }
771
18.1k
                            else {
772
18.1k
                                memcpy(buf, subrstring->data, code);
773
18.1k
                            }
774
18.1k
                        }
775
36.9k
                    }
776
38.4k
                }
777
16
                else {
778
16
                    code = gs_note_error(gs_error_invalidfont);
779
16
                }
780
38.5k
                pdfi_countdown(subrstring);
781
38.5k
            }
782
38.5k
        }
783
38.5k
    }
784
0
    else {
785
0
        code = gs_note_error(gs_error_invalidfont);
786
0
    }
787
3.70M
    return code;
788
3.70M
}
789
790
static int
791
pdfi_fapi_get_raw_subr(gs_fapi_font *ff, int index, byte *buf, int buf_length)
792
0
{
793
0
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
794
0
    int code = 0;
795
796
0
    if (pfont->FontType == ft_encrypted) {
797
0
        pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
798
0
        if (index > (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs))) {
799
0
            code = gs_error_rangecheck;
800
0
        }
801
0
        else {
802
0
            pdf_string *subr_str = NULL;
803
0
            code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, index, PDF_STRING, (pdf_obj **)&subr_str);
804
0
            if (code >= 0) {
805
0
                code = subr_str->length;
806
0
                if (buf && buf_length >= code) {
807
0
                    memcpy(buf, subr_str->data, code);
808
0
                }
809
0
            }
810
0
            else {
811
                /* Ignore missing or invalid subrs */
812
0
                code = 0;
813
0
            }
814
0
            pdfi_countdown(subr_str);
815
0
        }
816
0
    }
817
0
    return code;
818
0
}
819
820
static int
821
pdfi_fapi_get_charstring(gs_fapi_font *ff, int index, byte *buf, ushort buf_length)
822
0
{
823
0
    return 0;
824
0
}
825
826
static int
827
pdfi_fapi_get_charstring_name(gs_fapi_font *ff, int index, byte *buf, ushort buf_length)
828
0
{
829
0
    return 0;
830
0
}
831
832
static int
833
pdfi_fapi_get_glyphname_or_cid(gs_text_enum_t *penum, gs_font_base * pbfont, gs_string * charstring,
834
                gs_string * name, gs_glyph ccode, gs_string * enc_char_name,
835
                char *font_file_path, gs_fapi_char_ref * cr, bool bCID)
836
2.84M
{
837
2.84M
    gs_fapi_server *I = pbfont->FAPI;
838
2.84M
    int code = 0;
839
2.84M
    pdf_context *ctx = (pdf_context *) ((pdf_font *)pbfont->client_data)->ctx;
840
841
2.84M
    if (pbfont->FontType == ft_CID_TrueType) {
842
298k
        pdf_cidfont_type2 *pttfont = (pdf_cidfont_type2 *)pbfont->client_data;
843
298k
        gs_glyph gid;
844
845
298k
        if (ccode >= GS_MIN_CID_GLYPH)
846
0
            ccode = ccode - GS_MIN_CID_GLYPH;
847
848
298k
        if (pttfont->substitute == false) {
849
213k
            gid = ccode;
850
213k
            if (pttfont->cidtogidmap != NULL && pttfont->cidtogidmap->length > (ccode << 1) + 1) {
851
149k
                gid = pttfont->cidtogidmap->data[ccode << 1] << 8 | pttfont->cidtogidmap->data[(ccode << 1) + 1];
852
149k
            }
853
213k
            cr->client_char_code = ccode;
854
213k
            cr->char_codes[0] = gid;
855
213k
            cr->is_glyph_index = true;
856
213k
        }
857
84.6k
        else { /* If the composite font has a decoding, then this is a subsituted CIDFont with a "known" ordering */
858
84.6k
            unsigned int gc = 0, cc = (unsigned int)ccode;
859
84.6k
            byte uc[4];
860
84.6k
            int l;
861
862
84.6k
            if (penum->text.operation & TEXT_FROM_SINGLE_CHAR) {
863
0
                cc = penum->text.data.d_char;
864
84.6k
            } else if (penum->text.operation & TEXT_FROM_SINGLE_GLYPH) {
865
0
                cc = penum->text.data.d_glyph - GS_MIN_CID_GLYPH;
866
0
            }
867
84.6k
            else {
868
84.6k
                byte *c = (byte *)&penum->text.data.bytes[penum->index - penum->bytes_decoded];
869
84.6k
                int i;
870
84.6k
                cc = 0;
871
245k
                for (i = 0; i < penum->bytes_decoded ; i++) {
872
161k
                    cc |= c[i] << ((penum->bytes_decoded - 1) - i) * 8;
873
161k
                }
874
84.6k
            }
875
876
84.6k
            l = penum->orig_font->procs.decode_glyph((gs_font *)penum->orig_font, ccode, (gs_char)cc, (ushort *)uc, 4);
877
84.6k
            if (l == 2) {
878
48.2k
                cc = uc[1] | uc[0] << 8;
879
48.2k
            }
880
36.3k
            else if (l == 4) {
881
412
                cc = uc[3] | uc[2] << 8 | uc[2] << 16 | uc[2] << 24;
882
412
            }
883
35.9k
            else
884
35.9k
                cc = ccode;
885
            /* All known cmap tables map 32 to the space glyph, so if it looks like
886
               we're going to use a notdef, then substitute the glyph for the code point 32
887
             */
888
84.6k
            if (l != 0) {
889
48.6k
                code = pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, cc, &gc);
890
48.6k
                if (code < 0 || gc == 0)
891
3.60k
                    (void)pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, 32, &gc);
892
48.6k
            }
893
35.9k
            else {
894
35.9k
                if (ccode == 0) {
895
87
                    (void)pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, 32, &gc);
896
87
                }
897
35.8k
                else {
898
35.8k
                    gc = ccode;
899
35.8k
                }
900
35.9k
            }
901
902
84.6k
            cr->client_char_code = ccode;
903
84.6k
            cr->char_codes[0] = gc;
904
84.6k
            cr->is_glyph_index = true;
905
84.6k
        }
906
298k
        return 0;
907
298k
    }
908
    /* For cff based CIDFonts (and thus "Type 1" based CIDFonts, since the code
909
     * is common to both) and cff fonts we only claim to the FAPI server that
910
     * we have one (or two?) glyphs, because it makes the "stub" font simpler.
911
     * But Freetype bounds checks the character code (or gid) against the number
912
     * of glyphs in the font *before* asking us for the glyph data. So we need
913
     * to extract the charstring here, store it in the fapi font, and unpack it
914
     * in pdfi_fapi_get_glyph(), so we can then claim we're always rendering glyph
915
     * index zero, and thus pass the bounds check.
916
     */
917
2.55M
    else if (penum->current_font->FontType == ft_CID_encrypted) {
918
8.11k
        gs_font_cid0 *pfont9 = (gs_font_cid0 *)penum->current_font;
919
8.11k
        gs_glyph_data_t gd;
920
8.11k
        int f_ind;
921
922
8.11k
        code = (*pfont9->cidata.glyph_data)((gs_font_base *)pfont9, ccode, &gd, &f_ind);
923
8.11k
        if (code < 0) {
924
4.08k
            code = (*pfont9->cidata.glyph_data)((gs_font_base *)pfont9, 0, &gd, &f_ind);
925
4.08k
        }
926
8.11k
        if (code < 0)
927
0
            return_error(gs_error_invalidfont);
928
929
8.11k
        I->ff.char_data = (void *)gd.bits.data;
930
8.11k
        I->ff.char_data_len = gd.bits.size;
931
932
8.11k
        cr->client_char_code = 0;
933
8.11k
        cr->char_codes[0] = 0;
934
8.11k
        cr->is_glyph_index = true;
935
8.11k
        I->ff.client_font_data2 = penum->fstack.items[penum->fstack.depth].font;
936
937
8.11k
        return 0;
938
8.11k
    }
939
2.54M
    else if (pbfont->FontType == ft_encrypted2) {
940
90.6k
        pdf_font_cff *cfffont = (pdf_font_cff *)pbfont->client_data;
941
90.6k
        pdf_name *glyphname = NULL;
942
90.6k
        pdf_string *charstr = NULL;
943
90.6k
        gs_const_string gname;
944
945
90.6k
        code = (*ctx->get_glyph_name)((gs_font *)pbfont, ccode, &gname);
946
90.6k
        if (code >= 0) {
947
90.6k
            code = pdfi_name_alloc(ctx, (byte *) gname.data, gname.size, (pdf_obj **) &glyphname);
948
90.6k
            if (code < 0)
949
0
                return code;
950
90.6k
            pdfi_countup(glyphname);
951
90.6k
        }
952
953
90.6k
        if (code < 0) {
954
0
            pdfi_countdown(glyphname);
955
0
            return code;
956
0
        }
957
90.6k
        code = pdfi_dict_get_by_key(cfffont->ctx, cfffont->CharStrings, glyphname, (pdf_obj **)&charstr);
958
90.6k
        if (code < 0) {
959
165
            code = pdfi_map_glyph_name_via_agl(cfffont->CharStrings, glyphname, &charstr);
960
165
            if (code < 0)
961
159
                code = pdfi_dict_get(cfffont->ctx, cfffont->CharStrings, ".notdef", (pdf_obj **)&charstr);
962
165
        }
963
90.6k
        pdfi_countdown(glyphname);
964
90.6k
        if (code < 0)
965
0
            return code;
966
967
90.6k
        I->ff.char_data = charstr->data;
968
90.6k
        I->ff.char_data_len = charstr->length;
969
970
90.6k
        cr->client_char_code = 0;
971
90.6k
        cr->char_codes[0] = 0;
972
90.6k
        cr->is_glyph_index = true;
973
974
90.6k
        pdfi_countdown(charstr);
975
90.6k
        return code;
976
90.6k
    }
977
2.45M
    else if (pbfont->FontType == ft_TrueType) {
978
        /* I'm not clear if the heavy lifting should be here or in pdfi_tt_encode_char() */
979
296k
        pdf_font_truetype *ttfont = (pdf_font_truetype *)pbfont->client_data;
980
296k
        pdf_name *GlyphName = NULL;
981
296k
        gs_const_string gname;
982
296k
        int i;
983
296k
        uint cc = 0;
984
296k
        if ((ttfont->descflags & 4) != 0) {
985
49.3k
            if (ttfont->cmap == pdfi_truetype_cmap_30) {
986
987
8.78k
                ccode = cr->client_char_code;
988
8.78k
                code = pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, (uint)ccode, &cc);
989
8.78k
                if (code < 0 || cc == 0)
990
8.73k
                    cr->char_codes[0] = ccode | 0xf0 << 8;
991
54
                else
992
54
                    cr->char_codes[0] = ccode;
993
8.78k
                cr->is_glyph_index = false;
994
8.78k
            }
995
40.6k
            else {
996
40.6k
                cr->char_codes[0] = cr->client_char_code;
997
40.6k
                cr->is_glyph_index = false;
998
40.6k
            }
999
49.3k
        }
1000
247k
        else {
1001
1002
247k
            code = (*ctx->get_glyph_name)((gs_font *)pbfont, ccode, &gname);
1003
247k
            if (code >= 0) {
1004
247k
                code = pdfi_name_alloc(ctx, (byte *) gname.data, gname.size, (pdf_obj **) &GlyphName);
1005
247k
                if (code >= 0)
1006
247k
                    pdfi_countup(GlyphName);
1007
247k
            }
1008
1009
247k
            cr->char_codes[0] = cr->client_char_code;
1010
247k
            cr->is_glyph_index = false;
1011
247k
            if (code < 0)
1012
0
                return 0;
1013
1014
247k
            if (ttfont->cmap == pdfi_truetype_cmap_10) {
1015
74.1k
                gs_glyph g;
1016
1017
74.1k
                g = gs_c_name_glyph((const byte *)GlyphName->data, GlyphName->length);
1018
74.1k
                if (g != GS_NO_GLYPH) {
1019
74.1k
                    g = (gs_glyph)gs_c_decode(g, ENCODING_INDEX_MACROMAN);
1020
74.1k
                }
1021
0
                else {
1022
0
                    g = GS_NO_CHAR;
1023
0
                }
1024
1025
74.1k
                if (g != GS_NO_CHAR) {
1026
74.1k
                    code = pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, (uint)g, &cc);
1027
74.1k
                }
1028
1029
74.1k
                if (code < 0 || cc == 0) {
1030
16.8k
                    gs_font_type42 *pfonttt = (gs_font_type42 *)pbfont;
1031
16.8k
                    gs_string gname = {0};
1032
1033
                    /* This is a very slow implementation, we may benefit from creating a
1034
                     * a reverse post table upfront */
1035
3.18M
                    for (i = 0; i < pfonttt->data.numGlyphs; i++) {
1036
3.17M
                        code = gs_type42_find_post_name(pfonttt, (gs_glyph)i, &gname);
1037
3.17M
                        if (code >= 0) {
1038
31.4k
                            if (gname.data[0] == GlyphName->data[0]
1039
31.4k
                                && gname.size == GlyphName->length
1040
31.4k
                                && !strncmp((char *)gname.data, (char *)GlyphName->data, GlyphName->length))
1041
8.97k
                            {
1042
8.97k
                                cr->char_codes[0] = i;
1043
8.97k
                                cr->is_glyph_index = true;
1044
8.97k
                                break;
1045
8.97k
                            }
1046
31.4k
                        }
1047
3.17M
                    }
1048
16.8k
                }
1049
57.2k
                else {
1050
57.2k
                    cr->char_codes[0] = g;
1051
57.2k
                    cr->is_glyph_index = false;
1052
57.2k
                }
1053
74.1k
            }
1054
173k
            else if (ttfont->cmap == pdfi_truetype_cmap_31) {
1055
157k
                    unsigned int cc;
1056
157k
                    single_glyph_list_t *sgl = (single_glyph_list_t *)&(SingleGlyphList);
1057
                    /* Not to spec, but... if we get a "uni..." formatted name, use
1058
                       the hex value from that.
1059
                     */
1060
157k
                    if (GlyphName->length > 5 && !strncmp((char *)GlyphName->data, "uni", 3)) {
1061
460
                        char gnbuf[64];
1062
460
                        int l = (GlyphName->length - 3) > 63 ? 63 : GlyphName->length - 3;
1063
1064
460
                        memcpy(gnbuf, GlyphName->data + 3, l);
1065
460
                        gnbuf[l] = '\0';
1066
460
                        l = sscanf(gnbuf, "%x", &cc);
1067
460
                        if (l > 0)
1068
460
                            cr->char_codes[0] = cc;
1069
0
                        else
1070
0
                            cr->char_codes[0] = 0;
1071
460
                    }
1072
157k
                    else {
1073
                        /* Slow linear search, we could binary chop it */
1074
282M
                        for (i = 0; sgl[i].Glyph != 0x00; i++) {
1075
282M
                            if (sgl[i].Glyph[0] == GlyphName->data[0]
1076
282M
                                && strlen(sgl[i].Glyph) == GlyphName->length
1077
282M
                                && !strncmp((char *)sgl[i].Glyph, (char *)GlyphName->data, GlyphName->length))
1078
157k
                                break;
1079
282M
                        }
1080
157k
                        if (sgl[i].Glyph != NULL) {
1081
157k
                            code = pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, (uint)sgl[i].Unicode, &cc);
1082
157k
                            if (code < 0 || cc == 0)
1083
4.26k
                                cc = 0;
1084
152k
                            else
1085
152k
                                cc = sgl[i].Unicode;
1086
157k
                        }
1087
34
                        else
1088
34
                            cc = 0;
1089
1090
157k
                        if (cc == 0) {
1091
4.29k
                            gs_font_type42 *pfonttt = (gs_font_type42 *)pbfont;
1092
4.29k
                            gs_string gname = {0};
1093
1094
                            /* This is a very slow implementation, we may benefit from creating a
1095
                             * a reverse post table upfront */
1096
12.5M
                            for (i = 0; i < pfonttt->data.numGlyphs; i++) {
1097
12.5M
                                code = gs_type42_find_post_name(pfonttt, (gs_glyph)i, &gname);
1098
12.5M
                                if (code >= 0) {
1099
8.49k
                                    if (gname.data[0] == GlyphName->data[0]
1100
8.49k
                                        && gname.size == GlyphName->length
1101
8.49k
                                        && !strncmp((char *)gname.data, (char *)GlyphName->data, GlyphName->length))
1102
75
                                    {
1103
75
                                        cr->char_codes[0] = i;
1104
75
                                        cr->is_glyph_index = true;
1105
75
                                        break;
1106
75
                                    }
1107
8.49k
                                }
1108
12.5M
                            }
1109
4.29k
                        }
1110
152k
                        else {
1111
152k
                            cr->char_codes[0] = cc;
1112
152k
                            cr->is_glyph_index = false;
1113
152k
                        }
1114
157k
                    }
1115
157k
            }
1116
247k
            pdfi_countdown(GlyphName);
1117
247k
            return 0;
1118
247k
        }
1119
296k
    }
1120
2.15M
    else if (pbfont->FontType == ft_encrypted) {
1121
2.15M
        gs_const_string gname;
1122
2.15M
        code = (*ctx->get_glyph_name)((gs_font *)pbfont, ccode, &gname);
1123
2.15M
        I->ff.char_data = enc_char_name->data = (byte *)gname.data;
1124
2.15M
        I->ff.char_data_len = enc_char_name->size = gname.size;
1125
2.15M
        cr->is_glyph_index = false;
1126
2.15M
    }
1127
2.20M
    return code;
1128
2.84M
}
1129
1130
static int
1131
pdfi_fapi_get_glyph(gs_fapi_font * ff, gs_glyph char_code, byte * buf, int buf_length)
1132
2.92M
{
1133
2.92M
    gs_font_base *pbfont = (gs_font_base *) ff->client_font_data2;
1134
2.92M
    gs_fapi_server *I = pbfont->FAPI;
1135
2.92M
    int code = 0;
1136
2.92M
    pdf_name *encn;
1137
2.92M
    int cstrlen = 0;
1138
1139
2.92M
    if (ff->is_type1) {
1140
1141
2.57M
        if (pbfont->FontType == ft_encrypted) {
1142
2.46M
            gs_font_type1 *pfont1 = (gs_font_type1 *) pbfont;
1143
2.46M
            pdf_name *glyphname = NULL;
1144
2.46M
            pdf_string *charstring = NULL;
1145
2.46M
            pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pbfont->client_data;
1146
2.46M
            int leniv = pfont1->data.lenIV > 0 ? pfont1->data.lenIV : 0;
1147
1148
2.46M
            if (I->ff.char_data != NULL) {
1149
2.46M
                code = pdfi_name_alloc(pdffont1->ctx, (byte *)I->ff.char_data, I->ff.char_data_len, (pdf_obj **)&glyphname);
1150
2.46M
                if (code < 0)
1151
0
                    return code;
1152
2.46M
                pdfi_countup(glyphname);
1153
2.46M
                code = pdfi_dict_get_by_key(pdffont1->ctx, pdffont1->CharStrings, glyphname, (pdf_obj **)&charstring);
1154
2.46M
                if (code < 0) {
1155
27.2k
                    code = pdfi_map_glyph_name_via_agl(pdffont1->CharStrings, glyphname, &charstring);
1156
27.2k
                    if (code < 0) {
1157
26.9k
                        code = pdfi_dict_get(pdffont1->ctx, pdffont1->CharStrings, ".notdef", (pdf_obj **)&charstring);
1158
26.9k
                        if (code < 0) {
1159
0
                            pdfi_countdown(glyphname);
1160
0
                            code = gs_note_error(gs_error_invalidfont);
1161
0
                            goto done;
1162
0
                        }
1163
26.9k
                    }
1164
27.2k
                }
1165
2.46M
                pdfi_countdown(glyphname);
1166
2.46M
                cstrlen = charstring->length - leniv;
1167
2.46M
                if (buf != NULL && cstrlen <= buf_length) {
1168
2.15M
                    if (ff->need_decrypt && pfont1->data.lenIV >= 0)
1169
2.15M
                        decode_bytes(buf, charstring->data, cstrlen + leniv, leniv);
1170
142
                    else
1171
142
                        memcpy(buf, charstring->data, charstring->length);
1172
2.15M
                }
1173
2.46M
                pdfi_countdown(charstring);
1174
                /* Trigger the seac case below - we can do this safely
1175
                   because I->ff.char_data points to a string managed
1176
                   by the Encoding array in the pdf_font object
1177
                 */
1178
2.46M
                if (buf != NULL)
1179
2.34M
                    I->ff.char_data = NULL;
1180
2.46M
            }
1181
0
            else { /* SEAC */
1182
0
                gs_const_string encstr;
1183
0
                gs_glyph enc_ind = gs_c_known_encode(char_code, ENCODING_INDEX_STANDARD);
1184
1185
0
                if (enc_ind == GS_NO_GLYPH) {
1186
0
                    code = gs_error_invalidfont;
1187
0
                }
1188
0
                else {
1189
0
                   gs_c_glyph_name(enc_ind, &encstr);
1190
0
                   code = pdfi_name_alloc(pdffont1->ctx, (byte *)encstr.data, encstr.size, (pdf_obj **)&encn);
1191
0
                   if (code < 0)
1192
0
                       goto done;
1193
1194
0
                   pdfi_countup(encn);
1195
0
                   code = pdfi_dict_get_by_key(pdffont1->ctx, pdffont1->CharStrings, encn, (pdf_obj **)&charstring);
1196
0
                   pdfi_countdown(encn);
1197
0
                   if (code < 0)
1198
0
                       goto done;
1199
0
                   cstrlen = charstring->length - leniv;
1200
0
                   if (buf != NULL && code <= buf_length) {
1201
0
                       if (ff->need_decrypt && leniv >= 0)
1202
0
                           decode_bytes(buf, charstring->data, cstrlen + leniv, leniv);
1203
0
                       else
1204
0
                           memcpy(buf, charstring->data, charstring->length);
1205
0
                   }
1206
0
                   pdfi_countdown(charstring);
1207
0
                }
1208
0
            }
1209
2.46M
        }
1210
113k
        else if (pbfont->FontType == ft_CID_encrypted || pbfont->FontType == ft_encrypted2) {
1211
113k
            gs_font_type1 *pfont = (gs_font_type1 *) (gs_font_base *) ff->client_font_data;
1212
113k
            int leniv = pfont->data.lenIV > 0 ? pfont->data.lenIV : 0;
1213
1214
113k
            if (I->ff.char_data_len > 0 && I->ff.char_data != NULL) {
1215
105k
                cstrlen = I->ff.char_data_len - leniv;
1216
1217
105k
                if (buf && buf_length >= cstrlen) {
1218
98.7k
                    if (ff->need_decrypt && pfont->data.lenIV >= 0)
1219
0
                        decode_bytes(buf, I->ff.char_data, cstrlen + leniv, leniv);
1220
98.7k
                    else
1221
98.7k
                        memcpy(buf, I->ff.char_data, cstrlen);
1222
1223
                    /* Trigger the seac case below - we can do this safely
1224
                       because I->ff.char_data points to a string managed
1225
                       by the charstrings dict in the pdf_font object
1226
                     */
1227
98.7k
                    I->ff.char_data = NULL;
1228
98.7k
                }
1229
105k
            }
1230
7.73k
            else {
1231
7.73k
                pdf_font_cff *pdffont = (pdf_font_cff *)pfont->client_data;
1232
7.73k
                pdf_name *encn;
1233
7.73k
                pdf_string *charstring;
1234
1235
7.73k
                if (pbfont->FontType == ft_CID_encrypted) {
1236
                    /* we're dealing with a font that's an entry in a CIDFont FDArray
1237
                       so don't try to use an Encoding
1238
                     */
1239
224
                     char indstring[33];
1240
224
                     int l;
1241
224
                     l = gs_snprintf(indstring, 32, "%u", (unsigned int)char_code);
1242
224
                     code = pdfi_name_alloc(pdffont->ctx, (byte *)indstring, l, (pdf_obj **)&encn);
1243
224
                }
1244
7.51k
                else {
1245
7.51k
                    gs_const_string encstr;
1246
7.51k
                    gs_glyph enc_ind = gs_c_known_encode(char_code, ENCODING_INDEX_STANDARD);
1247
1248
                    /* Nonsense values for char_code should probably trigger an error (as above)
1249
                       but other consumers seem tolerant, so....
1250
                     */
1251
7.51k
                    if (enc_ind == GS_NO_GLYPH)
1252
2.90k
                        enc_ind = gs_c_known_encode(0, ENCODING_INDEX_STANDARD);
1253
1254
7.51k
                    code = gs_c_glyph_name(enc_ind, &encstr);
1255
1256
7.51k
                    if (code < 0)
1257
0
                        code = pdfi_name_alloc(pdffont->ctx, (byte *)".notdef", 7, (pdf_obj **)&encn);
1258
7.51k
                    else
1259
7.51k
                        code = pdfi_name_alloc(pdffont->ctx, (byte *)encstr.data, encstr.size, (pdf_obj **)&encn);
1260
7.51k
                }
1261
7.73k
                if (code < 0)
1262
0
                    goto done;
1263
1264
7.73k
                pdfi_countup(encn);
1265
7.73k
                code = pdfi_dict_get_by_key(pdffont->ctx, pdffont->CharStrings, encn, (pdf_obj **)&charstring);
1266
7.73k
                pdfi_countdown(encn);
1267
7.73k
                if (code < 0)
1268
298
                    goto done;
1269
7.43k
                cstrlen = charstring->length - leniv;
1270
7.43k
                if (buf != NULL && cstrlen <= buf_length) {
1271
5.33k
                    if (ff->need_decrypt && pfont->data.lenIV >= 0)
1272
0
                        decode_bytes(buf, charstring->data, cstrlen + leniv, leniv);
1273
5.33k
                    else
1274
5.33k
                        memcpy(buf, charstring->data, charstring->length);
1275
5.33k
                }
1276
7.43k
                pdfi_countdown(charstring);
1277
7.43k
            }
1278
1279
113k
        }
1280
2.57M
    }
1281
341k
    else {
1282
341k
        gs_font_type42 *pfont42 = (gs_font_type42 *)pbfont;
1283
341k
        gs_glyph_data_t pgd;
1284
1285
341k
        code = pfont42->data.get_outline(pfont42, char_code, &pgd);
1286
341k
        cstrlen = pgd.bits.size;
1287
341k
        if (code >= 0) {
1288
335k
            if (buf && buf_length >= cstrlen) {
1289
281k
                memcpy(buf, pgd.bits.data, cstrlen);
1290
281k
            }
1291
335k
        }
1292
341k
    }
1293
2.92M
done:
1294
2.92M
    if (code < 0)
1295
5.84k
        return code;
1296
1297
2.91M
    return cstrlen;
1298
2.92M
}
1299
1300
static int
1301
pdfi_fapi_serialize_tt_font(gs_fapi_font * ff, void *buf, int buf_size)
1302
0
{
1303
0
    return 0;
1304
0
}
1305
1306
static int
1307
pdfi_fapi_retrieve_tt_font(gs_fapi_font * ff, void **buf, int *buf_size)
1308
14.6k
{
1309
14.6k
    gs_font_type42 *pfonttt = (gs_font_type42 *) ff->client_font_data;
1310
14.6k
    pdf_font_truetype *pdfttf = (pdf_font_truetype *)pfonttt->client_data;
1311
1312
14.6k
    *buf = pdfttf->sfnt->data;
1313
14.6k
    *buf_size = pdfttf->sfnt->length;
1314
1315
14.6k
    return 0;
1316
14.6k
}
1317
1318
1319
static int
1320
pdfi_get_glyphdirectory_data(gs_fapi_font * ff, int char_code,
1321
                           const byte ** ptr)
1322
0
{
1323
0
    return (0);
1324
0
}
1325
1326
static int
1327
pdfi_fapi_get_metrics(gs_fapi_font * ff, gs_string * char_name, gs_glyph cid, double *m, bool vertical)
1328
2.84M
{
1329
2.84M
    return 0;
1330
2.84M
}
1331
1332
static int
1333
pdfi_fapi_set_cache(gs_text_enum_t * penum, const gs_font_base * pbfont,
1334
                  const gs_string * char_name, gs_glyph cid,
1335
                  const double pwidth[2], const gs_rect * pbbox,
1336
                  const double Metrics2_sbw_default[4], bool * imagenow)
1337
2.75M
{
1338
2.75M
    int code = 0;
1339
2.75M
    int code2;
1340
2.75M
    gs_gstate *pgs = penum->pgs;
1341
2.75M
    float w2[10];
1342
2.75M
    double widths[6] = {0};
1343
2.75M
    gs_point pt;
1344
2.75M
    gs_font_base *pbfont1 = (gs_font_base *)pbfont;
1345
2.75M
    gs_matrix imat;
1346
2.75M
    gs_matrix mat1;
1347
1348
2.75M
    mat1 = pbfont1->FontMatrix;
1349
1350
2.75M
    if (penum->orig_font->FontType == ft_composite) {
1351
1352
303k
        if (cid >= GS_MIN_CID_GLYPH) {
1353
295k
            cid = cid - GS_MIN_CID_GLYPH;
1354
295k
        }
1355
1356
303k
        if (pbfont->FontType == ft_encrypted || pbfont->FontType == ft_encrypted2) {
1357
8.09k
            gs_fapi_server *I = (gs_fapi_server *)pbfont1->FAPI;
1358
8.09k
            pbfont1 = (gs_font_base *)I->ff.client_font_data2;
1359
            /* The following cannot fail - if the matrix multiplication didn't work
1360
               we'd have errored out at a higher level
1361
             */
1362
8.09k
            (void)gs_matrix_multiply(&pbfont->FontMatrix, &pbfont1->FontMatrix, &mat1);
1363
8.09k
        }
1364
1365
303k
        code = pdfi_get_cidfont_glyph_metrics((gs_font *)pbfont1, cid, widths, true);
1366
303k
        if (code < 0) {
1367
            /* Insert warning here! */
1368
456
            code = 0; /* Using the defaults */
1369
456
        }
1370
303k
    }
1371
2.44M
    else {
1372
2.44M
        code = -1;
1373
2.44M
    }
1374
1375
    /* Since we have to tranverse a few things by the inverse font matrix,
1376
       invert the matrix once upfront.
1377
     */
1378
2.75M
    code2 = gs_matrix_invert(&mat1, &imat);
1379
2.75M
    if (code2 < 0)
1380
0
        return code2; /* By this stage, this is basically impossible */
1381
1382
2.75M
    if (code < 0) {
1383
2.44M
        w2[0] = (float)pwidth[0];
1384
2.44M
        w2[1] = (float)pwidth[1];
1385
2.44M
    }
1386
303k
    else {
1387
        /* gs_distance_transform() cannot return an error */
1388
303k
        (void)gs_distance_transform(widths[GLYPH_W0_WIDTH_INDEX], widths[GLYPH_W0_HEIGHT_INDEX], &imat, &pt);
1389
1390
303k
        w2[0] = pt.x / 1000.0;
1391
303k
        w2[1] = pt.y / 1000.0;
1392
303k
    }
1393
2.75M
    w2[2] = pbbox->p.x;
1394
2.75M
    w2[3] = pbbox->p.y;
1395
2.75M
    w2[4] = pbbox->q.x;
1396
2.75M
    w2[5] = pbbox->q.y;
1397
1398
2.75M
    (void)gs_distance_transform(widths[GLYPH_W1_WIDTH_INDEX], widths[GLYPH_W1_HEIGHT_INDEX], &imat, &pt);
1399
2.75M
    w2[6] =  pt.x / 1000.0;
1400
2.75M
    w2[7] =  pt.y / 1000.0;
1401
2.75M
    (void)gs_distance_transform(widths[GLYPH_W1_V_X_INDEX], widths[GLYPH_W1_V_Y_INDEX], &imat, &pt);
1402
2.75M
    w2[8] =  pt.x / 1000.0;
1403
2.75M
    w2[9] =  pt.y / 1000.0;
1404
1405
2.75M
    if ((code = gs_setcachedevice2((gs_show_enum *) penum, pgs, w2)) < 0) {
1406
644
        return (code);
1407
644
    }
1408
1409
2.75M
    *imagenow = true;
1410
2.75M
    return (code);
1411
2.75M
}
1412
1413
1414
static int
1415
pdfi_fapi_build_char(gs_show_enum * penum, gs_gstate * pgs, gs_font * pfont,
1416
                   gs_char chr, gs_glyph glyph)
1417
2.75M
{
1418
2.75M
    int code = 0;
1419
2.75M
    gs_font_base *pbfont1;
1420
2.75M
    gs_fapi_server *I;
1421
1422
    /* gs_fapi_do_char() expects the "natural" glyph, not the offset value */
1423
2.75M
    if (glyph >= GS_MIN_CID_GLYPH)
1424
304k
        glyph -= GS_MIN_CID_GLYPH;
1425
1426
2.75M
    pbfont1 = (gs_font_base *)pfont;
1427
1428
2.75M
    if (penum->fstack.depth >= 0) {
1429
304k
        gs_font_cid0 *cidpfont = (gs_font_cid0 *)penum->fstack.items[penum->fstack.depth].font;
1430
304k
        if (cidpfont->FontType == ft_CID_encrypted) {
1431
8.09k
            pbfont1 = (gs_font_base *)cidpfont->cidata.FDArray[penum->fstack.items[penum->fstack.depth].index];
1432
8.09k
            I = (gs_fapi_server *)pbfont1->FAPI;
1433
8.09k
            I->ff.client_font_data2 = cidpfont;
1434
8.09k
        }
1435
304k
    }
1436
    /* If between the font's creation and now another interpreter has driven FAPI (i.e. in a Postscript Begin/EndPage
1437
       context, the FAPI server data may end up set appropriately for the other interpreter, if that's happened, put
1438
       ours back before trying to interpret the glyph.
1439
    */
1440
2.75M
    if (((gs_fapi_server *)pbfont1->FAPI)->ff.get_glyphname_or_cid != pdfi_fapi_get_glyphname_or_cid) {
1441
0
        code = pdfi_fapi_passfont((pdf_font *)pbfont1->client_data, 0, NULL, NULL, NULL, 0);
1442
0
    }
1443
1444
2.75M
    if (code >= 0)
1445
2.75M
        code = gs_fapi_do_char((gs_font *)pbfont1, pgs, (gs_text_enum_t *) penum, NULL, false, NULL, NULL, chr, glyph, 0);
1446
1447
2.75M
    return (code);
1448
2.75M
}
1449
1450
static void
1451
pdfi_get_server_param(gs_fapi_server * I, const char *subtype,
1452
                    char **server_param, int *server_param_size)
1453
214k
{
1454
214k
    return;
1455
214k
}
1456
1457
#if 0
1458
static int
1459
pdfi_fapi_set_cache_metrics(gs_text_enum_t * penum, const gs_font_base * pbfont,
1460
                         const gs_string * char_name, int cid,
1461
                         const double pwidth[2], const gs_rect * pbbox,
1462
                         const double Metrics2_sbw_default[4],
1463
                         bool * imagenow)
1464
{
1465
    return (gs_error_unknownerror);
1466
}
1467
1468
static gs_glyph
1469
pdfi_fapi_encode_char(gs_font * pfont, gs_char pchr, gs_glyph_space_t not_used)
1470
{
1471
    return (gs_glyph) pchr;
1472
}
1473
#endif
1474
1475
int
1476
pdfi_fapi_passfont(pdf_font *font, int subfont, char *fapi_request,
1477
                 char *file_name, byte * font_data, int font_data_len)
1478
213k
{
1479
213k
    char *fapi_id = NULL;
1480
213k
    int code = 0;
1481
213k
    gs_string fdata;
1482
213k
    gs_string *fdatap = &fdata;
1483
213k
    gs_font_base *pbfont = (gs_font_base *)font->pfont;
1484
213k
    gs_fapi_font local_pdf_ff_stub = pdfi_ff_stub;
1485
213k
    gs_fapi_ttf_cmap_request symbolic_req[GS_FAPI_NUM_TTF_CMAP_REQ] = {{3, 0}, {1, 0}, {3, 1}, {3, 10}, {-1, -1}};
1486
213k
    gs_fapi_ttf_cmap_request nonsymbolic_req[GS_FAPI_NUM_TTF_CMAP_REQ] = {{3, 1}, {1, 0}, {3, 0}, {-1, -1}, {-1, -1}};
1487
213k
    int plat, enc;
1488
1489
213k
    if (!gs_fapi_available(pbfont->memory, NULL)) {
1490
0
        return (code);
1491
0
    }
1492
1493
213k
    if (font->pdfi_font_type == e_pdf_font_truetype) {
1494
13.5k
        fdatap = NULL;
1495
13.5k
    }
1496
199k
    else if (font->pdfi_font_type == e_pdf_cidfont_type2) {
1497
3.02k
        fdatap->data = ((pdf_cidfont_type2 *)font)->sfnt->data;
1498
3.02k
        fdatap->size = ((pdf_cidfont_type2 *)font)->sfnt->length;
1499
3.02k
    }
1500
196k
    else {
1501
196k
        fdatap->data = font_data;
1502
196k
        fdatap->size = font_data_len;
1503
196k
    }
1504
1505
213k
    if (font->pdfi_font_type == e_pdf_font_truetype) {
1506
13.5k
        pdf_font_truetype *ttfont = (pdf_font_truetype *)font;
1507
13.5k
        *local_pdf_ff_stub.ttf_cmap_req = (ttfont->descflags & 4) ? *symbolic_req : *nonsymbolic_req;
1508
13.5k
    }
1509
199k
    else {
1510
        /* doesn't really matter for non-ttf */
1511
199k
        *local_pdf_ff_stub.ttf_cmap_req = *nonsymbolic_req;
1512
199k
    }
1513
1514
213k
    gs_fapi_set_servers_client_data(pbfont->memory,
1515
213k
                                    (const gs_fapi_font *)&local_pdf_ff_stub,
1516
213k
                                    (gs_font *)pbfont);
1517
1518
213k
    code =
1519
213k
        gs_fapi_passfont((gs_font *)pbfont, subfont, (char *)file_name, fdatap,
1520
213k
                         (char *)fapi_request, NULL, (char **)&fapi_id,
1521
213k
                         (gs_fapi_get_server_param_callback)
1522
213k
                         pdfi_get_server_param);
1523
1524
213k
    if (code < 0 || fapi_id == NULL) {
1525
1.65k
        return code;
1526
1.65k
    }
1527
1528
211k
    if (font->pdfi_font_type == e_pdf_font_truetype) {
1529
12.3k
        pdf_font_truetype *ttfont = (pdf_font_truetype *)font;
1530
12.3k
        plat = pbfont->FAPI->ff.ttf_cmap_selected.platform_id;
1531
12.3k
        enc = pbfont->FAPI->ff.ttf_cmap_selected.encoding_id;
1532
12.3k
        ttfont->cmap = pdfi_truetype_cmap_none;
1533
1534
12.3k
        if (plat == 1 && enc == 0) {
1535
2.40k
            ttfont->cmap = pdfi_truetype_cmap_10;
1536
2.40k
        }
1537
9.94k
        else if (plat == 3 && enc == 0) {
1538
254
            ttfont->cmap = pdfi_truetype_cmap_30;
1539
254
        }
1540
9.68k
        else if (plat == 3 && enc == 1) {
1541
8.21k
            ttfont->cmap = pdfi_truetype_cmap_31;
1542
8.21k
        }
1543
1.46k
        else if (plat == 3 && enc == 10) { /* Currently shouldn't arise */
1544
0
            ttfont->cmap = pdfi_truetype_cmap_310;
1545
0
        }
1546
12.3k
    }
1547
1548
211k
    pbfont->procs.build_char = pdfi_fapi_build_char;
1549
1550
211k
    return (code);
1551
213k
}
1552
1553
int
1554
pdfi_fapi_check_cmap_for_GID(gs_font *pfont, uint cid, uint *gid)
1555
5.00M
{
1556
5.00M
    if (pfont->FontType == ft_TrueType
1557
5.00M
     || pfont->FontType == ft_CID_TrueType) {
1558
5.00M
        gs_font_base *pbfont = (gs_font_base *)pfont;
1559
5.00M
        gs_fapi_server *I = pbfont->FAPI;
1560
1561
5.00M
        if (I) {
1562
5.00M
            uint c = cid;
1563
5.00M
            I->ff.server_font_data = pbfont->FAPI_font_data;
1564
5.00M
            I->check_cmap_for_GID(I, &c);
1565
5.00M
            *gid = c;
1566
5.00M
            return 0;
1567
5.00M
        }
1568
5.00M
    }
1569
0
    return_error(gs_error_invalidfont);
1570
5.00M
}