Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gsfcid.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Support for CID-keyed fonts */
18
#include "memory_.h"
19
#include "gx.h"
20
#include "gsmatrix.h"   /* for gsfont.h */
21
#include "gsstruct.h"
22
#include "gxfcid.h"
23
#include "gserrors.h"
24
25
/* CIDSystemInfo structure descriptors */
26
public_st_cid_system_info();
27
public_st_cid_system_info_element();
28
29
/* CID-keyed font structure descriptors */
30
public_st_gs_font_cid_data();
31
public_st_gs_font_cid0();
32
static
33
324
ENUM_PTRS_WITH(font_cid0_enum_ptrs, gs_font_cid0 *pfcid0)
34
270
{
35
270
    index -= 2;
36
270
    if (index < st_gs_font_cid_data_num_ptrs)
37
54
        return ENUM_USING(st_gs_font_cid_data, &pfcid0->cidata.common,
38
270
                          sizeof(gs_font_cid_data), index);
39
270
    ENUM_PREFIX(st_gs_font_base, st_gs_font_cid_data_num_ptrs);
40
270
}
41
270
ENUM_PTR(0, gs_font_cid0, cidata.FDArray);
42
324
ENUM_PTR(1, gs_font_cid0, cidata.proc_data);
43
324
ENUM_PTRS_END
44
static
45
27
RELOC_PTRS_WITH(font_cid0_reloc_ptrs, gs_font_cid0 *pfcid0);
46
27
    RELOC_PREFIX(st_gs_font_base);
47
27
    RELOC_USING(st_gs_font_cid_data, &pfcid0->cidata.common,
48
27
                sizeof(st_gs_font_cid_data));
49
27
    RELOC_VAR(pfcid0->cidata.FDArray);
50
27
    RELOC_VAR(pfcid0->cidata.proc_data);
51
27
RELOC_PTRS_END
52
public_st_gs_font_cid1();
53
static
54
0
ENUM_PTRS_WITH(font_cid1_enum_ptrs, gs_font_cid1 *pfcid1)
55
0
{
56
0
    if (index < st_cid_system_info_num_ptrs)
57
0
        return ENUM_USING(st_cid_system_info, &pfcid1->cidata.CIDSystemInfo,
58
0
                          sizeof(st_cid_system_info), index);
59
0
    ENUM_PREFIX(st_gs_font_base, st_cid_system_info_num_ptrs);
60
0
}
61
0
ENUM_PTRS_END
62
static
63
0
RELOC_PTRS_WITH(font_cid1_reloc_ptrs, gs_font_cid1 *pfcid1);
64
0
    RELOC_PREFIX(st_gs_font_base);
65
0
    RELOC_USING(st_cid_system_info, &pfcid1->cidata.CIDSystemInfo,
66
0
                sizeof(st_cid_system_info));
67
0
RELOC_PTRS_END
68
public_st_gs_font_cid2();
69
static
70
5.58k
ENUM_PTRS_WITH(font_cid2_enum_ptrs, gs_font_cid2 *pfcid2)
71
5.20k
{
72
5.20k
    if (index < st_gs_font_cid2_own_ptrs)
73
372
        ENUM_PTR(0, gs_font_cid2, subst_CID_on_WMode);
74
5.20k
    if (index < st_gs_font_cid_data_num_ptrs + st_gs_font_cid2_own_ptrs)
75
744
        return ENUM_USING(st_gs_font_cid_data, &pfcid2->cidata.common,
76
5.20k
                          sizeof(gs_font_cid_data), index - st_gs_font_cid2_own_ptrs);
77
5.20k
    ENUM_PREFIX(st_gs_font_type42, st_gs_font_cid_data_num_ptrs + st_gs_font_cid2_own_ptrs);
78
5.20k
}
79
5.58k
ENUM_PTRS_END
80
static
81
372
RELOC_PTRS_WITH(font_cid2_reloc_ptrs, gs_font_cid2 *pfcid2);
82
372
    RELOC_PREFIX(st_gs_font_type42);
83
372
    RELOC_USING(st_gs_font_cid_data, &pfcid2->cidata.common,
84
372
                sizeof(st_gs_font_cid_data));
85
372
    RELOC_VAR(pfcid2->subst_CID_on_WMode);
86
372
RELOC_PTRS_END
87
88
/* GC descriptor for allocating FDArray for CIDFontType 0 fonts. */
89
gs_private_st_ptr(st_gs_font_type1_ptr, gs_font_type1 *, "gs_font_type1 *",
90
  font1_ptr_enum_ptrs, font1_ptr_reloc_ptrs);
91
gs_public_st_element(st_gs_font_type1_ptr_element, gs_font_type1 *,
92
  "gs_font_type1 *[]", font1_ptr_element_enum_ptrs,
93
  font1_ptr_element_reloc_ptrs, st_gs_font_type1_ptr);
94
95
/* GC descriptor for allocating FDArray for subst_CID_on_WMode. */
96
static
97
0
ENUM_PTRS_WITH(subst_CID_on_WMode_enum_ptrs, gs_subst_CID_on_WMode_t *subst) return 0;
98
0
    case 0: return ENUM_OBJ(subst->rc.memory);
99
0
    case 1: return ENUM_OBJ(subst->data[0]);
100
0
    case 2: return ENUM_OBJ(subst->data[1]);
101
0
ENUM_PTRS_END
102
0
static RELOC_PTRS_WITH(subst_CID_on_WMode_reloc_ptrs, gs_subst_CID_on_WMode_t *subst)
103
0
{
104
0
    RELOC_VAR(subst->data[0]);
105
0
    RELOC_VAR(subst->data[1]);
106
0
    RELOC_VAR(subst->rc.memory);
107
0
} RELOC_PTRS_END
108
109
static void
110
subst_CID_on_WMode_finalize(const gs_memory_t *cmem, void *data)
111
0
{
112
0
    gs_subst_CID_on_WMode_t *subst = (gs_subst_CID_on_WMode_t *)data;
113
0
    (void)cmem; /* unused */
114
115
0
    gs_free_object(subst->rc.memory, subst->data[0], "subst_CID_on_WMode_finalize");
116
0
    subst->data[0] = NULL;
117
0
    gs_free_object(subst->rc.memory, subst->data[1], "subst_CID_on_WMode_finalize");
118
0
    subst->data[1] = NULL;
119
0
}
120
121
public_st_subst_CID_on_WMode();
122
123
/*
124
 * The CIDSystemInfo of a CMap may be null.  We represent this by setting
125
 * Registry and Ordering to empty strings, and Supplement to 0.
126
 */
127
void
128
cid_system_info_set_null(gs_cid_system_info_t *pcidsi)
129
16.1k
{
130
16.1k
    memset(pcidsi, 0, sizeof(*pcidsi));
131
16.1k
}
132
bool
133
cid_system_info_is_null(const gs_cid_system_info_t *pcidsi)
134
27
{
135
27
    return (pcidsi->Registry.size == 0 && pcidsi->Ordering.size == 0 &&
136
27
            pcidsi->Supplement == 0);
137
27
}
138
139
/*
140
 * Get the CIDSystemInfo of a font.  If the font is not a CIDFont,
141
 * return NULL.
142
 */
143
const gs_cid_system_info_t *
144
gs_font_cid_system_info(const gs_font *pfont)
145
173k
{
146
173k
    switch (pfont->FontType) {
147
900
    case ft_CID_encrypted:
148
900
        return &((const gs_font_cid0 *)pfont)->cidata.common.CIDSystemInfo;
149
0
    case ft_CID_user_defined:
150
0
        return &((const gs_font_cid1 *)pfont)->cidata.CIDSystemInfo;
151
172k
    case ft_CID_TrueType:
152
172k
        return &((const gs_font_cid2 *)pfont)->cidata.common.CIDSystemInfo;
153
0
    default:
154
0
        return 0;
155
173k
    }
156
173k
}
157
158
/*
159
 * Check CIDSystemInfo compatibility.
160
 */
161
bool
162
gs_is_CIDSystemInfo_compatible(const gs_cid_system_info_t *info0,
163
                               const gs_cid_system_info_t *info1)
164
86.8k
{
165
86.8k
    if (info0 == NULL || info1 == NULL)
166
0
        return false;
167
86.8k
    if (info0->Registry.size != info1->Registry.size)
168
0
        return false;
169
86.8k
    if (info0->Ordering.size != info1->Ordering.size)
170
0
        return false;
171
86.8k
    if (memcmp(info0->Registry.data, info1->Registry.data,
172
86.8k
               info0->Registry.size))
173
0
        return false;
174
86.8k
    if (memcmp(info0->Ordering.data, info1->Ordering.data,
175
86.8k
               info0->Ordering.size))
176
0
        return false;
177
86.8k
    return true;
178
86.8k
}
179
180
/*
181
 * Provide a default enumerate_glyph procedure for CIDFontType 0 fonts.
182
 * Built for simplicity, not for speed.
183
 */
184
font_proc_enumerate_glyph(gs_font_cid0_enumerate_glyph); /* check prototype */
185
int
186
gs_font_cid0_enumerate_glyph(gs_font *font, int *pindex,
187
                             gs_glyph_space_t ignore_glyph_space,
188
                             gs_glyph *pglyph)
189
0
{
190
0
    gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
191
192
0
    while (*pindex < pfont->cidata.common.CIDCount) {
193
0
        gs_glyph_data_t gdata;
194
0
        int fidx;
195
0
        gs_glyph glyph = (gs_glyph)(GS_MIN_CID_GLYPH + (*pindex)++);
196
0
        int code;
197
198
0
        gdata.memory = pfont->memory;
199
0
        code = pfont->cidata.glyph_data((gs_font_base *)pfont, glyph,
200
0
                                            &gdata, &fidx);
201
0
        if (code < 0 || gdata.bits.size == 0)
202
0
            continue;
203
0
        *pglyph = glyph;
204
0
        gs_glyph_data_free(&gdata, "gs_font_cid0_enumerate_glyphs");
205
0
        return 0;
206
0
    }
207
0
    *pindex = 0;
208
0
    return 0;
209
0
}
210
211
/* Return the font from the FDArray at the given index */
212
const gs_font *
213
gs_cid0_indexed_font(const gs_font *font, int fidx)
214
28.9k
{
215
28.9k
    gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
216
217
28.9k
    if (font->FontType != ft_CID_encrypted) {
218
0
        emprintf1(font->memory,
219
0
                  "Unexpected font type: %d\n",
220
0
                  font->FontType);
221
0
        return 0;
222
0
    }
223
28.9k
    return (const gs_font*) (pfont->cidata.FDArray[fidx]);
224
28.9k
}
225
226
/* Check whether a CID font has a Type 2 subfont. */
227
bool
228
gs_cid0_has_type2(const gs_font *font)
229
0
{
230
0
    gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
231
0
    int i;
232
233
0
    if (font->FontType != ft_CID_encrypted) {
234
0
        emprintf1(font->memory,
235
0
                  "Unexpected font type: %d\n",
236
0
                  font->FontType);
237
0
        return false;
238
0
    }
239
0
    for (i = 0; i < pfont->cidata.FDArray_size; i++)
240
0
        if (((const gs_font *)pfont->cidata.FDArray[i])->FontType == ft_encrypted2)
241
0
            return true;
242
0
    return false;
243
0
}