Coverage Report

Created: 2025-06-24 07:01

/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
65.1M
{
170
65.1M
    return ((ushort) (v * 16)); /* fixme : the scale may depend on renderer */
171
65.1M
}
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
91.9M
{
176
91.9M
    int code = 0;
177
91.9M
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
178
179
91.9M
    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
922k
        case gs_fapi_font_feature_FontType:
196
922k
            *ret = (pfont->FontType == 2 ? 2 : 1);
197
922k
            break;
198
7.38M
        case gs_fapi_font_feature_FontBBox:
199
7.38M
            switch (index) {
200
1.84M
                case 0:
201
1.84M
                    *ret = ((ushort) pfont->FontBBox.p.x);
202
1.84M
                    break;
203
1.84M
                case 1:
204
1.84M
                    *ret = ((ushort) pfont->FontBBox.p.y);
205
1.84M
                    break;
206
1.84M
                case 2:
207
1.84M
                    *ret = ((ushort) pfont->FontBBox.q.x);
208
1.84M
                    break;
209
1.84M
                case 3:
210
1.84M
                    *ret = ((ushort) pfont->FontBBox.q.y);
211
1.84M
                    break;
212
0
                default:
213
0
                    code = gs_note_error(gs_error_rangecheck);
214
7.38M
            }
215
7.38M
            break;
216
7.38M
        case gs_fapi_font_feature_BlueValues_count:
217
1.84M
            *ret = pfont->data.BlueValues.count;
218
1.84M
            break;
219
14.5M
        case gs_fapi_font_feature_BlueValues:
220
14.5M
            *ret =  (float_to_ushort(pfont->data.BlueValues.values[index]));
221
14.5M
            break;
222
1.84M
        case gs_fapi_font_feature_OtherBlues_count:
223
1.84M
            *ret = pfont->data.OtherBlues.count;
224
1.84M
            break;
225
52.5k
        case gs_fapi_font_feature_OtherBlues:
226
52.5k
            *ret = (float_to_ushort(pfont->data.OtherBlues.values[index]));
227
52.5k
            break;
228
1.84M
        case gs_fapi_font_feature_FamilyBlues_count:
229
1.84M
            *ret = pfont->data.FamilyBlues.count;
230
1.84M
            break;
231
28.6k
        case gs_fapi_font_feature_FamilyBlues:
232
28.6k
            *ret = (float_to_ushort(pfont->data.FamilyBlues.values[index]));
233
28.6k
            break;
234
1.84M
        case gs_fapi_font_feature_FamilyOtherBlues_count:
235
1.84M
            *ret = pfont->data.FamilyOtherBlues.count;
236
1.84M
            break;
237
21.7k
        case gs_fapi_font_feature_FamilyOtherBlues:
238
21.7k
            *ret = (float_to_ushort(pfont->data.FamilyOtherBlues.values[index]));
239
21.7k
            break;
240
1.84M
        case gs_fapi_font_feature_BlueShift:
241
1.84M
            *ret = float_to_ushort(pfont->data.BlueShift);
242
1.84M
            break;
243
1.84M
        case gs_fapi_font_feature_BlueFuzz:
244
1.84M
            *ret = float_to_ushort(pfont->data.BlueShift);
245
1.84M
            break;
246
1.84M
        case gs_fapi_font_feature_StdHW:
247
1.84M
            *ret = (pfont->data.StdHW.count == 0 ? 0 : float_to_ushort(pfont->data.StdHW.values[0]));   /* UFST bug ? */
248
1.84M
            break;
249
1.84M
        case gs_fapi_font_feature_StdVW:
250
1.84M
            *ret = (pfont->data.StdVW.count == 0 ? 0 : float_to_ushort(pfont->data.StdVW.values[0]));   /* UFST bug ? */
251
1.84M
            break;
252
1.84M
        case gs_fapi_font_feature_StemSnapH_count:
253
1.84M
            *ret = pfont->data.StemSnapH.count;
254
1.84M
            break;
255
21.6M
        case gs_fapi_font_feature_StemSnapH:
256
21.6M
            *ret = float_to_ushort(pfont->data.StemSnapH.values[index]);
257
21.6M
            break;
258
1.84M
        case gs_fapi_font_feature_StemSnapV_count:
259
1.84M
            *ret = pfont->data.StemSnapV.count;
260
1.84M
            break;
261
21.4M
        case gs_fapi_font_feature_StemSnapV:
262
21.4M
            *ret = float_to_ushort(pfont->data.StemSnapV.values[index]);
263
21.4M
            break;
264
1.84M
        case gs_fapi_font_feature_ForceBold:
265
1.84M
            *ret = pfont->data.ForceBold;
266
1.84M
            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
24.1k
        case gs_fapi_font_feature_GlobalSubrs_count:
274
24.1k
            {
275
24.1k
                if (pfont->FontType == ft_encrypted2) {
276
24.1k
                    pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
277
24.1k
                    *ret = pdffont2->GlobalSubrs == NULL ? 0 : pdfi_array_size(pdffont2->GlobalSubrs);
278
24.1k
                }
279
0
                else {
280
0
                    *ret = 0;
281
0
                    code = gs_note_error(gs_error_invalidaccess);
282
0
                }
283
24.1k
                break;
284
7.38M
            }
285
1.86M
        case gs_fapi_font_feature_Subrs_count:
286
1.86M
            {
287
1.86M
                if (pfont->FontType == ft_encrypted) {
288
1.82M
                    pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
289
1.82M
                    *ret = pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs);
290
1.82M
                }
291
48.2k
                else if (pfont->FontType == ft_encrypted2) {
292
48.2k
                    pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
293
48.2k
                    *ret = pdffont2->Subrs == NULL ? 0 : pdfi_array_size(pdffont2->Subrs);
294
48.2k
                }
295
0
                else {
296
0
                    *ret = 0;
297
0
                    code = gs_note_error(gs_error_invalidaccess);
298
0
                }
299
1.86M
                break;
300
7.38M
            }
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
7.38M
            }
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
3.64M
        case gs_fapi_font_feature_DollarBlend:
337
3.64M
            {
338
3.64M
                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
3.64M
                else {
342
3.64M
                    *ret = 0;
343
3.64M
                }
344
3.64M
            }
345
3.64M
            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
91.9M
    }
450
91.9M
    return code;
451
91.9M
}
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
1.84M
{
456
1.84M
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
457
1.84M
    int code = 0;
458
459
1.84M
    switch ((int)var_id) {
460
0
        case gs_fapi_font_feature_UniqueID:
461
0
            *ret = pfont->UID.id;
462
0
            break;
463
1.84M
        case gs_fapi_font_feature_BlueScale:
464
1.84M
            *ret = (ulong) (pfont->data.BlueScale * 65536);
465
1.84M
            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
1.84M
    }
487
1.84M
    return code;
488
1.84M
}
489
490
static int
491
pdfi_fapi_get_float(gs_fapi_font *ff, gs_fapi_font_feature var_id, int index, float *ret)
492
11.0M
{
493
11.0M
    gs_font_base *pbfont = (gs_font_base *) ff->client_font_data2;
494
11.0M
    int code = 0;
495
11.0M
    gs_fapi_server *I = pbfont->FAPI;
496
497
11.0M
    switch ((int)var_id) {
498
11.0M
        case gs_fapi_font_feature_FontMatrix:
499
11.0M
            {
500
11.0M
                double FontMatrix_div;
501
11.0M
                gs_matrix m, *mptr;
502
503
11.0M
                if (I && I->get_fontmatrix) {
504
11.0M
                    FontMatrix_div = 1;
505
11.0M
                    mptr = &m;
506
11.0M
                    I->get_fontmatrix(I, mptr);
507
11.0M
                }
508
0
                else {
509
0
                    FontMatrix_div = ((ff->is_cid && (!FAPI_ISCIDFONT(pbfont))) ? 1000 : 1);
510
0
                    mptr = &(pbfont->base->FontMatrix);
511
0
                }
512
11.0M
                switch (index) {
513
1.84M
                    case 0:
514
1.84M
                    default:
515
1.84M
                        *ret = (mptr->xx / FontMatrix_div);
516
1.84M
                        break;
517
1.84M
                    case 1:
518
1.84M
                        *ret = (mptr->xy / FontMatrix_div);
519
1.84M
                        break;
520
1.84M
                    case 2:
521
1.84M
                        *ret = (mptr->yx / FontMatrix_div);
522
1.84M
                        break;
523
1.84M
                    case 3:
524
1.84M
                        *ret = (mptr->yy / FontMatrix_div);
525
1.84M
                        break;
526
1.84M
                    case 4:
527
1.84M
                        *ret = (mptr->tx / FontMatrix_div);
528
1.84M
                        break;
529
1.84M
                    case 5:
530
1.84M
                        *ret = (mptr->ty / FontMatrix_div);
531
1.84M
                        break;
532
11.0M
                }
533
11.0M
                break;
534
11.0M
            }
535
11.0M
        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
11.0M
    }
626
627
11.0M
    return code;
628
11.0M
}
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
20.0M
{
681
20.0M
    ushort state = 4330;
682
683
1.24G
    for (; l; s++, l--) {
684
1.22G
        uchar c = (*s ^ (state >> 8));
685
686
1.22G
        state = (*s + state) * crypt_c1 + crypt_c2;
687
1.22G
        if (lenIV > 0)
688
80.0M
            lenIV--;
689
1.14G
        else {
690
1.14G
            *p = c;
691
1.14G
            p++;
692
1.14G
        }
693
1.22G
    }
694
20.0M
}
695
696
static int
697
pdfi_fapi_get_gsubr(gs_fapi_font *ff, int index, byte *buf, int buf_length)
698
7.98M
{
699
7.98M
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
700
7.98M
    int code = 0;
701
7.98M
    if (pfont->FontType == ft_encrypted2) {
702
7.98M
        pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
703
7.98M
        if (index > (pdffont2->GlobalSubrs == NULL ? 0 : pdfi_array_size(pdffont2->GlobalSubrs))) {
704
0
            code = gs_error_rangecheck;
705
0
        }
706
7.98M
        else {
707
7.98M
            int leniv = (pfont->data.lenIV > 0 ? pfont->data.lenIV : 0);
708
7.98M
            pdf_string *subrstring = NULL;
709
710
7.98M
            code = pdfi_array_get(pdffont2->ctx, pdffont2->GlobalSubrs, index, (pdf_obj **)&subrstring);
711
7.98M
            if (code >= 0) {
712
7.98M
                if (pdfi_type_of(subrstring) == PDF_STRING) {
713
7.98M
                    code = subrstring->length - leniv;
714
7.98M
                    if (buf && buf_length >= code) {
715
3.98M
                        if (ff->need_decrypt && pfont->data.lenIV >= 0) {
716
0
                            decode_bytes(buf, subrstring->data, code + leniv, pfont->data.lenIV);
717
0
                        }
718
3.98M
                        else {
719
3.98M
                            memcpy(buf, subrstring->data, code);
720
3.98M
                        }
721
3.98M
                    }
722
7.98M
                }
723
92
                else {
724
92
                    code = gs_note_error(gs_error_invalidfont);
725
92
                }
726
7.98M
                pdfi_countdown(subrstring);
727
7.98M
            }
728
7.98M
        }
729
7.98M
    }
730
0
    else {
731
0
        code = gs_note_error(gs_error_invalidfont);
732
0
    }
733
7.98M
    return code;
734
7.98M
}
735
736
static int
737
pdfi_fapi_get_subr(gs_fapi_font *ff, int index, byte *buf, int buf_length)
738
15.8M
{
739
15.8M
    gs_font_type1 *pfont = (gs_font_type1 *) ff->client_font_data;
740
15.8M
    int code = 0;
741
742
15.8M
    if (pfont->FontType == ft_encrypted) {
743
15.7M
        pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pfont->client_data;
744
15.7M
        if (index > (pdffont1->Subrs == NULL ? 0 : pdfi_array_size(pdffont1->Subrs))) {
745
0
            code = gs_note_error(gs_error_rangecheck);
746
0
        }
747
15.7M
        else {
748
15.7M
            int leniv = (pfont->data.lenIV > 0 ? pfont->data.lenIV : 0);
749
15.7M
            pdf_string *subr_str = NULL;
750
751
15.7M
            code = pdfi_array_get_type(pdffont1->ctx, pdffont1->Subrs, index, PDF_STRING, (pdf_obj **)&subr_str);
752
15.7M
            if (code >= 0) {
753
15.7M
                 code = subr_str->length - leniv;
754
15.7M
                 if (buf && buf_length >= code) {
755
5.24M
                     if (ff->need_decrypt && pfont->data.lenIV >= 0) {
756
5.24M
                         decode_bytes(buf, subr_str->data, code + leniv, pfont->data.lenIV);
757
5.24M
                     }
758
0
                     else {
759
0
                         memcpy(buf, subr_str->data, code);
760
0
                     }
761
5.24M
                 }
762
15.7M
            }
763
0
            else {
764
                /* Ignore invalid or missing subrs */
765
0
                code = 0;
766
0
            }
767
15.7M
            pdfi_countdown(subr_str);
768
15.7M
        }
769
15.7M
    }
770
158k
    else if (pfont->FontType == ft_encrypted2) {
771
158k
        pdf_font_cff *pdffont2 = (pdf_font_cff *)pfont->client_data;
772
158k
        if (index > (pdffont2->Subrs == NULL ? 0 : pdfi_array_size(pdffont2->Subrs))) {
773
0
            code = gs_error_rangecheck;
774
0
        }
775
158k
        else {
776
158k
            int leniv = (pfont->data.lenIV > 0 ? pfont->data.lenIV : 0);
777
158k
            pdf_string *subrstring;
778
779
158k
            if (pdffont2->Subrs == NULL)
780
0
                code = gs_note_error(gs_error_invalidfont);
781
158k
            else
782
158k
                code = pdfi_array_get(pdffont2->ctx, pdffont2->Subrs, index, (pdf_obj **)&subrstring);
783
158k
            if (code >= 0) {
784
158k
                if (pdfi_type_of(subrstring) == PDF_STRING) {
785
158k
                    if (subrstring->length > 0) {
786
112k
                        code = subrstring->length - leniv;
787
112k
                        if (buf && buf_length >= code) {
788
54.7k
                            if (ff->need_decrypt && pfont->data.lenIV >= 0) {
789
0
                                decode_bytes(buf, subrstring->data, code + leniv, pfont->data.lenIV);
790
0
                            }
791
54.7k
                            else {
792
54.7k
                                memcpy(buf, subrstring->data, code);
793
54.7k
                            }
794
54.7k
                        }
795
112k
                    }
796
158k
                }
797
52
                else {
798
52
                    code = gs_note_error(gs_error_invalidfont);
799
52
                }
800
158k
                pdfi_countdown(subrstring);
801
158k
            }
802
158k
        }
803
158k
    }
804
0
    else {
805
0
        code = gs_note_error(gs_error_invalidfont);
806
0
    }
807
15.8M
    return code;
808
15.8M
}
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
18.7M
{
857
18.7M
    gs_fapi_server *I = pbfont->FAPI;
858
18.7M
    int code = 0;
859
18.7M
    pdf_context *ctx = (pdf_context *) ((pdf_font *)pbfont->client_data)->ctx;
860
861
18.7M
    if (pbfont->FontType == ft_CID_TrueType) {
862
1.73M
        pdf_cidfont_type2 *pttfont = (pdf_cidfont_type2 *)pbfont->client_data;
863
1.73M
        gs_glyph gid;
864
865
1.73M
        if (ccode >= GS_MIN_CID_GLYPH)
866
0
            ccode = ccode - GS_MIN_CID_GLYPH;
867
868
1.73M
        if (pttfont->substitute == false) {
869
1.13M
            gid = ccode;
870
1.13M
            if (pttfont->cidtogidmap != NULL && pttfont->cidtogidmap->length > (ccode << 1) + 1) {
871
457k
                gid = pttfont->cidtogidmap->data[ccode << 1] << 8 | pttfont->cidtogidmap->data[(ccode << 1) + 1];
872
457k
            }
873
1.13M
            cr->client_char_code = ccode;
874
1.13M
            cr->char_codes[0] = gid;
875
1.13M
            cr->is_glyph_index = true;
876
1.13M
        }
877
602k
        else { /* If the composite font has a decoding, then this is a subsituted CIDFont with a "known" ordering */
878
602k
            unsigned int gc = 0, cc = (unsigned int)ccode;
879
602k
            byte uc[4];
880
602k
            int l, i;
881
882
602k
            if (penum->text.operation & TEXT_FROM_SINGLE_CHAR) {
883
0
                cc = penum->text.data.d_char;
884
602k
            } else if (penum->text.operation & TEXT_FROM_SINGLE_GLYPH) {
885
0
                cc = penum->text.data.d_glyph - GS_MIN_CID_GLYPH;
886
0
            }
887
602k
            else {
888
602k
                byte *c = (byte *)&penum->text.data.bytes[penum->index - penum->bytes_decoded];
889
602k
                cc = 0;
890
1.78M
                for (i = 0; i < penum->bytes_decoded ; i++) {
891
1.18M
                    cc |= c[i] << ((penum->bytes_decoded - 1) - i) * 8;
892
1.18M
                }
893
602k
            }
894
895
602k
            l = penum->orig_font->procs.decode_glyph((gs_font *)penum->orig_font, ccode, (gs_char)cc, (ushort *)uc, 4);
896
602k
            if (l > 0 && l <= sizeof(uc)) {
897
282k
                cc = 0;
898
850k
                for (i = 0; i < l; i++) {
899
568k
                    cc |= uc[l - 1 - i] << (i * 8);
900
568k
                }
901
282k
            }
902
319k
            else
903
319k
                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
602k
            if (l != 0) {
908
282k
                code = pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, cc, &gc);
909
282k
                if (code < 0 || gc == 0)
910
27.8k
                    (void)pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, 32, &gc);
911
282k
            }
912
319k
            else {
913
319k
                if (ccode == 0) {
914
3.50k
                    (void)pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, 32, &gc);
915
3.50k
                }
916
316k
                else {
917
316k
                    gc = ccode;
918
316k
                }
919
319k
            }
920
921
602k
            cr->client_char_code = ccode;
922
602k
            cr->char_codes[0] = gc;
923
602k
            cr->is_glyph_index = true;
924
602k
        }
925
1.73M
        return 0;
926
1.73M
    }
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.0M
    else if (penum->current_font->FontType == ft_CID_encrypted) {
937
155k
        gs_font_cid0 *pfont9 = (gs_font_cid0 *)penum->current_font;
938
155k
        gs_glyph_data_t gd;
939
155k
        int f_ind;
940
941
155k
        code = (*pfont9->cidata.glyph_data)((gs_font_base *)pfont9, ccode, &gd, &f_ind);
942
155k
        if (code < 0) {
943
124k
            code = (*pfont9->cidata.glyph_data)((gs_font_base *)pfont9, 0, &gd, &f_ind);
944
124k
        }
945
155k
        if (code < 0)
946
0
            return_error(gs_error_invalidfont);
947
948
155k
        I->ff.char_data = (void *)gd.bits.data;
949
155k
        I->ff.char_data_len = gd.bits.size;
950
951
155k
        cr->client_char_code = 0;
952
155k
        cr->char_codes[0] = 0;
953
155k
        cr->is_glyph_index = true;
954
155k
        I->ff.client_font_data2 = penum->fstack.items[penum->fstack.depth].font;
955
956
155k
        return 0;
957
155k
    }
958
16.8M
    else if (pbfont->FontType == ft_encrypted2) {
959
1.09M
        pdf_font_cff *cfffont = (pdf_font_cff *)pbfont->client_data;
960
1.09M
        pdf_name *glyphname = NULL;
961
1.09M
        pdf_string *charstr = NULL;
962
1.09M
        gs_const_string gname;
963
964
1.09M
        code = (*ctx->get_glyph_name)((gs_font *)pbfont, ccode, &gname);
965
1.09M
        if (code >= 0) {
966
1.09M
            code = pdfi_name_alloc(ctx, (byte *) gname.data, gname.size, (pdf_obj **) &glyphname);
967
1.09M
            if (code < 0)
968
0
                return code;
969
1.09M
            pdfi_countup(glyphname);
970
1.09M
        }
971
972
1.09M
        if (code < 0) {
973
0
            pdfi_countdown(glyphname);
974
0
            return code;
975
0
        }
976
1.09M
        code = pdfi_dict_get_by_key(cfffont->ctx, cfffont->CharStrings, glyphname, (pdf_obj **)&charstr);
977
1.09M
        if (code < 0) {
978
1.58k
            code = pdfi_map_glyph_name_via_agl(cfffont->CharStrings, glyphname, &charstr);
979
1.58k
            if (code < 0)
980
1.50k
                code = pdfi_dict_get(cfffont->ctx, cfffont->CharStrings, ".notdef", (pdf_obj **)&charstr);
981
1.58k
        }
982
1.09M
        pdfi_countdown(glyphname);
983
1.09M
        if (code < 0)
984
0
            return code;
985
986
1.09M
        I->ff.char_data = charstr->data;
987
1.09M
        I->ff.char_data_len = charstr->length;
988
989
1.09M
        cr->client_char_code = 0;
990
1.09M
        cr->char_codes[0] = 0;
991
1.09M
        cr->is_glyph_index = true;
992
993
1.09M
        pdfi_countdown(charstr);
994
1.09M
        return code;
995
1.09M
    }
996
15.7M
    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
973k
        pdf_font_truetype *ttfont = (pdf_font_truetype *)pbfont->client_data;
999
973k
        pdf_name *GlyphName = NULL;
1000
973k
        gs_const_string gname;
1001
973k
        int i;
1002
973k
        uint cc = 0;
1003
973k
        if ((ttfont->descflags & 4) != 0) {
1004
286k
            if (ttfont->cmap == pdfi_truetype_cmap_30) {
1005
1006
57.3k
                ccode = cr->client_char_code;
1007
57.3k
                code = pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, (uint)ccode, &cc);
1008
57.3k
                if (code < 0 || cc == 0)
1009
57.1k
                    cr->char_codes[0] = ccode | 0xf0 << 8;
1010
216
                else
1011
216
                    cr->char_codes[0] = ccode;
1012
57.3k
                cr->is_glyph_index = false;
1013
57.3k
            }
1014
228k
            else {
1015
228k
                cr->char_codes[0] = cr->client_char_code;
1016
228k
                cr->is_glyph_index = false;
1017
228k
            }
1018
286k
        }
1019
687k
        else {
1020
1021
687k
            code = (*ctx->get_glyph_name)((gs_font *)pbfont, ccode, &gname);
1022
687k
            if (code >= 0) {
1023
687k
                code = pdfi_name_alloc(ctx, (byte *) gname.data, gname.size, (pdf_obj **) &GlyphName);
1024
687k
                if (code >= 0)
1025
687k
                    pdfi_countup(GlyphName);
1026
0
                else
1027
0
                    return_error(gs_error_VMerror);
1028
687k
            }
1029
1030
687k
            cr->char_codes[0] = cr->client_char_code;
1031
687k
            cr->is_glyph_index = false;
1032
687k
            if (code < 0)
1033
0
                return 0;
1034
1035
687k
            if (ttfont->cmap == pdfi_truetype_cmap_10) {
1036
182k
                gs_glyph g;
1037
1038
182k
                g = gs_c_name_glyph((const byte *)GlyphName->data, GlyphName->length);
1039
182k
                if (g != GS_NO_GLYPH) {
1040
182k
                    g = (gs_glyph)gs_c_decode(g, ENCODING_INDEX_MACROMAN);
1041
182k
                }
1042
0
                else {
1043
0
                    g = GS_NO_CHAR;
1044
0
                }
1045
1046
182k
                if (g != GS_NO_CHAR) {
1047
182k
                    code = pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, (uint)g, &cc);
1048
182k
                }
1049
1050
182k
                if (code < 0 || cc == 0) {
1051
9.23k
                    gs_font_type42 *pfonttt = (gs_font_type42 *)pbfont;
1052
9.23k
                    gs_string gname;
1053
9.23k
                    gname.data = GlyphName->data;
1054
9.23k
                    gname.size = GlyphName->length;
1055
1056
9.23k
                    code = pdfi_find_post_entry(pfonttt, (gs_const_string *)&gname, &cc);
1057
9.23k
                    if (code >= 0) {
1058
238
                        cr->char_codes[0] = cc;
1059
238
                        cr->is_glyph_index = true;
1060
238
                    }
1061
9.23k
                }
1062
173k
                else {
1063
173k
                    cr->char_codes[0] = g;
1064
173k
                    cr->is_glyph_index = false;
1065
173k
                }
1066
182k
            }
1067
504k
            else if (ttfont->cmap == pdfi_truetype_cmap_31) {
1068
438k
                    unsigned int cc;
1069
438k
                    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
438k
                    if (GlyphName->length == 7 && !strncmp((char *)GlyphName->data, "uni", 3)) {
1074
1.28k
                        char gnbuf[64];
1075
1.28k
                        int l = (GlyphName->length - 3) > 63 ? 63 : GlyphName->length - 3;
1076
1077
1.28k
                        memcpy(gnbuf, GlyphName->data + 3, l);
1078
1.28k
                        gnbuf[l] = '\0';
1079
1.28k
                        l = sscanf(gnbuf, "%x", &cc);
1080
1.28k
                        if (l > 0)
1081
1.28k
                            cr->char_codes[0] = cc;
1082
0
                        else
1083
0
                            cr->char_codes[0] = 0;
1084
1.28k
                    }
1085
436k
                    else {
1086
                        /* Slow linear search, we could binary chop it */
1087
945M
                        for (i = 0; sgl[i].Glyph != 0x00; i++) {
1088
945M
                            if (sgl[i].Glyph[0] == GlyphName->data[0]
1089
945M
                                && strlen(sgl[i].Glyph) == GlyphName->length
1090
945M
                                && !strncmp((char *)sgl[i].Glyph, (char *)GlyphName->data, GlyphName->length))
1091
436k
                                break;
1092
945M
                        }
1093
436k
                        if (sgl[i].Glyph != NULL) {
1094
436k
                            code = pdfi_fapi_check_cmap_for_GID((gs_font *)pbfont, (uint)sgl[i].Unicode, &cc);
1095
436k
                            if (code < 0 || cc == 0)
1096
17.5k
                                cc = 0;
1097
418k
                            else
1098
418k
                                cc = sgl[i].Unicode;
1099
436k
                        }
1100
490
                        else
1101
490
                            cc = 0;
1102
1103
436k
                        if (cc == 0) {
1104
18.0k
                            gs_font_type42 *pfonttt = (gs_font_type42 *)pbfont;
1105
18.0k
                            gs_string gname;
1106
18.0k
                            gname.data = GlyphName->data;
1107
18.0k
                            gname.size = GlyphName->length;
1108
1109
18.0k
                            code = pdfi_find_post_entry(pfonttt, (gs_const_string *)&gname, &cc);
1110
18.0k
                            if (code >= 0) {
1111
235
                                cr->char_codes[0] = cc;
1112
235
                                cr->is_glyph_index = true;
1113
235
                            }
1114
18.0k
                        }
1115
418k
                        else {
1116
418k
                            cr->char_codes[0] = cc;
1117
418k
                            cr->is_glyph_index = false;
1118
418k
                        }
1119
436k
                    }
1120
438k
            }
1121
687k
            pdfi_countdown(GlyphName);
1122
687k
            return 0;
1123
687k
        }
1124
973k
    }
1125
14.8M
    else if (pbfont->FontType == ft_encrypted || pbfont->FontType == ft_MicroType) {
1126
14.8M
        gs_const_string gname;
1127
14.8M
        code = (*ctx->get_glyph_name)((gs_font *)pbfont, ccode, &gname);
1128
14.8M
        I->ff.char_data = cr->char_name = enc_char_name->data = (byte *)gname.data;
1129
14.8M
        I->ff.char_data_len = cr->char_name_length = enc_char_name->size = gname.size;
1130
14.8M
        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
14.8M
    }
1150
15.0M
    return code;
1151
18.7M
}
1152
1153
static int
1154
pdfi_fapi_get_glyph(gs_fapi_font * ff, gs_glyph char_code, byte * buf, int buf_length)
1155
18.7M
{
1156
18.7M
    gs_font_base *pbfont = (gs_font_base *) ff->client_font_data2;
1157
18.7M
    gs_fapi_server *I = pbfont->FAPI;
1158
18.7M
    int code = 0;
1159
18.7M
    pdf_name *encn;
1160
18.7M
    int cstrlen = 0;
1161
1162
18.7M
    if (ff->is_type1) {
1163
1164
17.6M
        if (pbfont->FontType == ft_encrypted) {
1165
16.2M
            gs_font_type1 *pfont1 = (gs_font_type1 *) pbfont;
1166
16.2M
            pdf_name *glyphname = NULL;
1167
16.2M
            pdf_string *charstring = NULL;
1168
16.2M
            pdf_font_type1 *pdffont1 = (pdf_font_type1 *)pbfont->client_data;
1169
16.2M
            int leniv = pfont1->data.lenIV > 0 ? pfont1->data.lenIV : 0;
1170
1171
16.2M
            if (I->ff.char_data != NULL) {
1172
16.2M
                code = pdfi_name_alloc(pdffont1->ctx, (byte *)I->ff.char_data, I->ff.char_data_len, (pdf_obj **)&glyphname);
1173
16.2M
                if (code < 0)
1174
0
                    return code;
1175
16.2M
                pdfi_countup(glyphname);
1176
16.2M
                code = pdfi_dict_get_by_key(pdffont1->ctx, pdffont1->CharStrings, glyphname, (pdf_obj **)&charstring);
1177
16.2M
                if (code < 0) {
1178
557k
                    code = pdfi_map_glyph_name_via_agl(pdffont1->CharStrings, glyphname, &charstring);
1179
557k
                    if (code < 0) {
1180
556k
                        code = pdfi_dict_get(pdffont1->ctx, pdffont1->CharStrings, ".notdef", (pdf_obj **)&charstring);
1181
556k
                        if (code < 0) {
1182
0
                            pdfi_countdown(glyphname);
1183
0
                            code = gs_note_error(gs_error_invalidfont);
1184
0
                            goto done;
1185
0
                        }
1186
556k
                    }
1187
557k
                }
1188
16.2M
                pdfi_countdown(glyphname);
1189
16.2M
                cstrlen = charstring->length - leniv;
1190
16.2M
                if (buf != NULL && cstrlen <= buf_length) {
1191
14.8M
                    if (ff->need_decrypt && pfont1->data.lenIV >= 0)
1192
14.8M
                        decode_bytes(buf, charstring->data, cstrlen + leniv, leniv);
1193
789
                    else
1194
789
                        memcpy(buf, charstring->data, charstring->length);
1195
14.8M
                }
1196
16.2M
                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.2M
                if (buf != NULL)
1202
15.5M
                    I->ff.char_data = NULL;
1203
16.2M
            }
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.2M
        }
1233
1.36M
        else if (pbfont->FontType == ft_CID_encrypted || pbfont->FontType == ft_encrypted2) {
1234
1.36M
            gs_font_type1 *pfont = (gs_font_type1 *) (gs_font_base *) ff->client_font_data;
1235
1.36M
            int leniv = pfont->data.lenIV > 0 ? pfont->data.lenIV : 0;
1236
1237
1.36M
            if (I->ff.char_data_len > 0 && I->ff.char_data != NULL) {
1238
1.28M
                cstrlen = I->ff.char_data_len - leniv;
1239
1240
1.28M
                if (buf && buf_length >= cstrlen) {
1241
1.25M
                    if (ff->need_decrypt && pfont->data.lenIV >= 0)
1242
0
                        decode_bytes(buf, I->ff.char_data, cstrlen + leniv, leniv);
1243
1.25M
                    else
1244
1.25M
                        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.25M
                    I->ff.char_data = NULL;
1251
1.25M
                }
1252
1.28M
            }
1253
84.1k
            else {
1254
84.1k
                pdf_font_cff *pdffont = (pdf_font_cff *)pfont->client_data;
1255
84.1k
                pdf_name *encn;
1256
84.1k
                pdf_string *charstring;
1257
1258
84.1k
                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
1.79k
                     char indstring[33];
1263
1.79k
                     int l;
1264
1.79k
                     l = gs_snprintf(indstring, 32, "%u", (unsigned int)char_code);
1265
1.79k
                     code = pdfi_name_alloc(pdffont->ctx, (byte *)indstring, l, (pdf_obj **)&encn);
1266
1.79k
                }
1267
82.3k
                else {
1268
82.3k
                    gs_const_string encstr;
1269
82.3k
                    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
82.3k
                    if (enc_ind == GS_NO_GLYPH)
1275
27.4k
                        enc_ind = gs_c_known_encode(0, ENCODING_INDEX_STANDARD);
1276
1277
82.3k
                    code = gs_c_glyph_name(enc_ind, &encstr);
1278
1279
82.3k
                    if (code < 0)
1280
0
                        code = pdfi_name_alloc(pdffont->ctx, (byte *)".notdef", 7, (pdf_obj **)&encn);
1281
82.3k
                    else
1282
82.3k
                        code = pdfi_name_alloc(pdffont->ctx, (byte *)encstr.data, encstr.size, (pdf_obj **)&encn);
1283
82.3k
                }
1284
84.1k
                if (code < 0)
1285
0
                    goto done;
1286
1287
84.1k
                pdfi_countup(encn);
1288
84.1k
                code = pdfi_dict_get_by_key(pdffont->ctx, pdffont->CharStrings, encn, (pdf_obj **)&charstring);
1289
84.1k
                pdfi_countdown(encn);
1290
84.1k
                if (code < 0)
1291
2.22k
                    goto done;
1292
81.8k
                cstrlen = charstring->length - leniv;
1293
81.8k
                if (buf != NULL && cstrlen <= buf_length) {
1294
57.4k
                    if (ff->need_decrypt && pfont->data.lenIV >= 0)
1295
0
                        decode_bytes(buf, charstring->data, cstrlen + leniv, leniv);
1296
57.4k
                    else
1297
57.4k
                        memcpy(buf, charstring->data, charstring->length);
1298
57.4k
                }
1299
81.8k
                pdfi_countdown(charstring);
1300
81.8k
            }
1301
1302
1.36M
        }
1303
17.6M
    }
1304
1.16M
    else {
1305
1.16M
        gs_font_type42 *pfont42 = (gs_font_type42 *)pbfont;
1306
1.16M
        gs_glyph_data_t pgd;
1307
1308
1.16M
        code = pfont42->data.get_outline(pfont42, char_code, &pgd);
1309
1.16M
        cstrlen = pgd.bits.size;
1310
1.16M
        if (code >= 0) {
1311
1.16M
            if (buf && buf_length >= cstrlen) {
1312
1.00M
                memcpy(buf, pgd.bits.data, cstrlen);
1313
1.00M
            }
1314
1.16M
        }
1315
1.16M
    }
1316
18.7M
done:
1317
18.7M
    if (code < 0)
1318
3.72k
        return code;
1319
1320
18.7M
    return cstrlen;
1321
18.7M
}
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
20.9k
{
1332
20.9k
    gs_font_type42 *pfonttt = (gs_font_type42 *) ff->client_font_data;
1333
20.9k
    pdf_font_truetype *pdfttf = (pdf_font_truetype *)pfonttt->client_data;
1334
1335
20.9k
    *buf = pdfttf->sfnt->data;
1336
20.9k
    *buf_size = pdfttf->sfnt->length;
1337
1338
20.9k
    return 0;
1339
20.9k
}
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
18.3M
{
1352
18.3M
    return 0;
1353
18.3M
}
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
13.8M
{
1361
13.8M
    int code = 0;
1362
13.8M
    int code2;
1363
13.8M
    gs_gstate *pgs = penum->pgs;
1364
13.8M
    float w2[10];
1365
13.8M
    double widths[6] = {0};
1366
13.8M
    gs_point pt;
1367
13.8M
    gs_font_base *pbfont1 = (gs_font_base *)pbfont;
1368
13.8M
    gs_matrix imat;
1369
13.8M
    gs_matrix mat1;
1370
1371
13.8M
    mat1 = pbfont1->FontMatrix;
1372
1373
13.8M
    if (penum->orig_font->FontType == ft_composite) {
1374
1375
1.44M
        if (cid >= GS_MIN_CID_GLYPH) {
1376
1.33M
            cid = cid - GS_MIN_CID_GLYPH;
1377
1.33M
        }
1378
1379
1.44M
        if (pbfont->FontType == ft_encrypted || pbfont->FontType == ft_encrypted2) {
1380
111k
            gs_fapi_server *I = (gs_fapi_server *)pbfont1->FAPI;
1381
111k
            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
111k
            (void)gs_matrix_multiply(&pbfont->FontMatrix, &pbfont1->FontMatrix, &mat1);
1386
111k
        }
1387
1388
1.44M
        code = pdfi_get_cidfont_glyph_metrics((gs_font *)pbfont1, cid, widths, true);
1389
1.44M
        if (code < 0) {
1390
            /* Insert warning here! */
1391
3.59k
            code = 0; /* Using the defaults */
1392
3.59k
        }
1393
1.44M
    }
1394
12.4M
    else {
1395
12.4M
        code = -1;
1396
12.4M
    }
1397
1398
    /* Since we have to tranverse a few things by the inverse font matrix,
1399
       invert the matrix once upfront.
1400
     */
1401
13.8M
    code2 = gs_matrix_invert(&mat1, &imat);
1402
13.8M
    if (code2 < 0)
1403
0
        return code2; /* By this stage, this is basically impossible */
1404
1405
13.8M
    if (code < 0) {
1406
12.4M
        w2[0] = (float)pwidth[0];
1407
12.4M
        w2[1] = (float)pwidth[1];
1408
12.4M
    }
1409
1.44M
    else {
1410
        /* gs_distance_transform() cannot return an error */
1411
1.44M
        (void)gs_distance_transform(widths[GLYPH_W0_WIDTH_INDEX], widths[GLYPH_W0_HEIGHT_INDEX], &imat, &pt);
1412
1413
1.44M
        w2[0] = pt.x / 1000.0;
1414
1.44M
        w2[1] = pt.y / 1000.0;
1415
1.44M
    }
1416
13.8M
    w2[2] = pbbox->p.x;
1417
13.8M
    w2[3] = pbbox->p.y;
1418
13.8M
    w2[4] = pbbox->q.x;
1419
13.8M
    w2[5] = pbbox->q.y;
1420
1421
13.8M
    (void)gs_distance_transform(widths[GLYPH_W1_WIDTH_INDEX], widths[GLYPH_W1_HEIGHT_INDEX], &imat, &pt);
1422
13.8M
    w2[6] =  pt.x / 1000.0;
1423
13.8M
    w2[7] =  pt.y / 1000.0;
1424
13.8M
    (void)gs_distance_transform(widths[GLYPH_W1_V_X_INDEX], widths[GLYPH_W1_V_Y_INDEX], &imat, &pt);
1425
13.8M
    w2[8] =  pt.x / 1000.0;
1426
13.8M
    w2[9] =  pt.y / 1000.0;
1427
1428
13.8M
    if ((code = gs_setcachedevice2((gs_show_enum *) penum, pgs, w2)) < 0) {
1429
52
        return (code);
1430
52
    }
1431
1432
13.8M
    *imagenow = true;
1433
13.8M
    return (code);
1434
13.8M
}
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
13.9M
{
1441
13.9M
    int code = 0;
1442
13.9M
    gs_font_base *pbfont1;
1443
13.9M
    gs_fapi_server *I;
1444
1445
    /* gs_fapi_do_char() expects the "natural" glyph, not the offset value */
1446
13.9M
    if (glyph >= GS_MIN_CID_GLYPH)
1447
1.45M
        glyph -= GS_MIN_CID_GLYPH;
1448
1449
13.9M
    pbfont1 = (gs_font_base *)pfont;
1450
1451
13.9M
    if (penum->fstack.depth >= 0) {
1452
1.45M
        gs_font_cid0 *cidpfont = (gs_font_cid0 *)penum->fstack.items[penum->fstack.depth].font;
1453
1.45M
        if (cidpfont->FontType == ft_CID_encrypted) {
1454
111k
            pbfont1 = (gs_font_base *)cidpfont->cidata.FDArray[penum->fstack.items[penum->fstack.depth].index];
1455
111k
            I = (gs_fapi_server *)pbfont1->FAPI;
1456
111k
            I->ff.client_font_data2 = cidpfont;
1457
111k
        }
1458
1.45M
    }
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
13.9M
    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
13.9M
    if (code >= 0)
1478
13.9M
        code = gs_fapi_do_char((gs_font *)pbfont1, pgs, (gs_text_enum_t *) penum, NULL, false, NULL, NULL, chr, glyph, 0);
1479
1480
13.9M
    return (code);
1481
13.9M
}
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
962k
{
1505
962k
    char *fapi_id = NULL;
1506
962k
    int code = 0;
1507
962k
    gs_string fdata;
1508
962k
    gs_string *fdatap = &fdata;
1509
962k
    gs_font_base *pbfont = (gs_font_base *)font->pfont;
1510
962k
    gs_fapi_font local_pdf_ff_stub = pdfi_ff_stub;
1511
962k
    gs_fapi_ttf_cmap_request symbolic_req[GS_FAPI_NUM_TTF_CMAP_REQ] = {{3, 0}, {1, 0}, {3, 1}, {3, 10}, {-1, -1}};
1512
962k
    gs_fapi_ttf_cmap_request nonsymbolic_req[GS_FAPI_NUM_TTF_CMAP_REQ] = {{3, 1}, {1, 0}, {3, 0}, {-1, -1}, {-1, -1}};
1513
962k
    int plat, enc;
1514
962k
    const char *xlatmapu = (char *)"Microtype\000\000*\000FCO_Unicode";
1515
962k
    const char *xlatmaps = (char *)"Microtype\000\000*\000FCO_Symbol";
1516
962k
    const char *xlatmapd = (char *)"Microtype\000\000*\000FCO_Dingbats";
1517
962k
    char *xlatmap = NULL;
1518
962k
    char *decodingID = NULL;
1519
1520
962k
    if (!gs_fapi_available(pbfont->memory, NULL)) {
1521
0
        return (code);
1522
0
    }
1523
1524
962k
    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
962k
    if (font->pdfi_font_type == e_pdf_font_truetype) {
1539
20.0k
        fdatap = NULL;
1540
20.0k
    }
1541
942k
    else if (font->pdfi_font_type == e_pdf_cidfont_type2) {
1542
14.0k
        fdatap->data = ((pdf_cidfont_type2 *)font)->sfnt->data;
1543
14.0k
        fdatap->size = ((pdf_cidfont_type2 *)font)->sfnt->length;
1544
14.0k
    }
1545
928k
    else {
1546
928k
        fdatap->data = font_data;
1547
928k
        fdatap->size = font_data_len;
1548
928k
    }
1549
1550
962k
    if (font->pdfi_font_type == e_pdf_font_truetype) {
1551
20.0k
        pdf_font_truetype *ttfont = (pdf_font_truetype *)font;
1552
20.0k
        *local_pdf_ff_stub.ttf_cmap_req = (ttfont->descflags & 4) ? *symbolic_req : *nonsymbolic_req;
1553
20.0k
    }
1554
942k
    else {
1555
        /* doesn't really matter for non-ttf */
1556
942k
        *local_pdf_ff_stub.ttf_cmap_req = *nonsymbolic_req;
1557
942k
    }
1558
1559
962k
    gs_fapi_set_servers_client_data(pbfont->memory,
1560
962k
                                    (const gs_fapi_font *)&local_pdf_ff_stub,
1561
962k
                                    (gs_font *)pbfont);
1562
1563
962k
    code =
1564
962k
        gs_fapi_passfont((gs_font *)pbfont, subfont, (char *)file_name, fdatap,
1565
962k
                         (char *)fapi_request, xlatmap, (char **)&fapi_id,
1566
962k
                         &decodingID, pdfi_get_server_param);
1567
1568
962k
    if (code < 0 || fapi_id == NULL) {
1569
1.48k
        return code;
1570
1.48k
    }
1571
1572
961k
    if (font->pdfi_font_type == e_pdf_font_truetype) {
1573
19.0k
        pdf_font_truetype *ttfont = (pdf_font_truetype *)font;
1574
19.0k
        plat = pbfont->FAPI->ff.ttf_cmap_selected.platform_id;
1575
19.0k
        enc = pbfont->FAPI->ff.ttf_cmap_selected.encoding_id;
1576
19.0k
        ttfont->cmap = pdfi_truetype_cmap_none;
1577
1578
19.0k
        if (plat == 1 && enc == 0) {
1579
6.26k
            ttfont->cmap = pdfi_truetype_cmap_10;
1580
6.26k
        }
1581
12.7k
        else if (plat == 3 && enc == 0) {
1582
1.26k
            ttfont->cmap = pdfi_truetype_cmap_30;
1583
1.26k
        }
1584
11.4k
        else if (plat == 3 && enc == 1) {
1585
9.48k
            ttfont->cmap = pdfi_truetype_cmap_31;
1586
9.48k
        }
1587
2.00k
        else if (plat == 3 && enc == 10) { /* Currently shouldn't arise */
1588
0
            ttfont->cmap = pdfi_truetype_cmap_310;
1589
0
        }
1590
        /* Officially only 3,1 in PDF, but 0,x is Unicode, too */
1591
2.00k
        else if (plat == 0) {
1592
125
            ttfont->cmap = pdfi_truetype_cmap_31;
1593
125
            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
125
        }
1595
1.87k
        else {
1596
1.87k
            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
1.87k
        }
1598
19.0k
    }
1599
961k
    if (font->pdfi_font_type == e_pdf_font_microtype) {
1600
0
        ((pdf_font_microtype *)font)->DecodingID = decodingID;
1601
0
    }
1602
961k
    pbfont->procs.build_char = pdfi_fapi_build_char;
1603
1604
961k
    return (code);
1605
962k
}
1606
1607
int
1608
pdfi_fapi_check_cmap_for_GID(gs_font *pfont, uint cid, uint *gid)
1609
7.61M
{
1610
7.61M
    if (pfont->FontType == ft_TrueType
1611
7.61M
     || pfont->FontType == ft_CID_TrueType) {
1612
7.61M
        gs_font_base *pbfont = (gs_font_base *)pfont;
1613
7.61M
        gs_fapi_server *I = pbfont->FAPI;
1614
1615
7.61M
        if (I) {
1616
7.61M
            uint c = cid;
1617
7.61M
            I->ff.server_font_data = pbfont->FAPI_font_data;
1618
7.61M
            I->check_cmap_for_GID(I, &c);
1619
7.61M
            *gid = c;
1620
7.61M
            return 0;
1621
7.61M
        }
1622
7.61M
    }
1623
7.61M
    return_error(gs_error_invalidfont);
1624
7.61M
}
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
964k
{
1729
964k
    *server_param = NULL;
1730
964k
    *server_param_size = 0;
1731
964k
    return 1;
1732
964k
}
1733
#endif /* UFST_BRIDGE */