Coverage Report

Created: 2025-08-28 07:06

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