Coverage Report

Created: 2025-06-10 07:06

/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
0
ENUM_PTRS_WITH(font_cid0_enum_ptrs, gs_font_cid0 *pfcid0)
34
0
{
35
0
    index -= 2;
36
0
    if (index < st_gs_font_cid_data_num_ptrs)
37
0
        return ENUM_USING(st_gs_font_cid_data, &pfcid0->cidata.common,
38
0
                          sizeof(gs_font_cid_data), index);
39
0
    ENUM_PREFIX(st_gs_font_base, st_gs_font_cid_data_num_ptrs);
40
0
}
41
0
ENUM_PTR(0, gs_font_cid0, cidata.FDArray);
42
0
ENUM_PTR(1, gs_font_cid0, cidata.proc_data);
43
0
ENUM_PTRS_END
44
static
45
0
RELOC_PTRS_WITH(font_cid0_reloc_ptrs, gs_font_cid0 *pfcid0);
46
0
    RELOC_PREFIX(st_gs_font_base);
47
0
    RELOC_USING(st_gs_font_cid_data, &pfcid0->cidata.common,
48
0
                sizeof(st_gs_font_cid_data));
49
0
    RELOC_VAR(pfcid0->cidata.FDArray);
50
0
    RELOC_VAR(pfcid0->cidata.proc_data);
51
0
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
0
ENUM_PTRS_WITH(font_cid2_enum_ptrs, gs_font_cid2 *pfcid2)
71
0
{
72
0
    if (index < st_gs_font_cid2_own_ptrs)
73
0
        ENUM_PTR(0, gs_font_cid2, subst_CID_on_WMode);
74
0
    if (index < st_gs_font_cid_data_num_ptrs + st_gs_font_cid2_own_ptrs)
75
0
        return ENUM_USING(st_gs_font_cid_data, &pfcid2->cidata.common,
76
0
                          sizeof(gs_font_cid_data), index - st_gs_font_cid2_own_ptrs);
77
0
    ENUM_PREFIX(st_gs_font_type42, st_gs_font_cid_data_num_ptrs + st_gs_font_cid2_own_ptrs);
78
0
}
79
0
ENUM_PTRS_END
80
static
81
0
RELOC_PTRS_WITH(font_cid2_reloc_ptrs, gs_font_cid2 *pfcid2);
82
0
    RELOC_PREFIX(st_gs_font_type42);
83
0
    RELOC_USING(st_gs_font_cid_data, &pfcid2->cidata.common,
84
0
                sizeof(st_gs_font_cid_data));
85
0
    RELOC_VAR(pfcid2->subst_CID_on_WMode);
86
0
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
611
{
130
611
    memset(pcidsi, 0, sizeof(*pcidsi));
131
611
}
132
bool
133
cid_system_info_is_null(const gs_cid_system_info_t *pcidsi)
134
0
{
135
0
    return (pcidsi->Registry.size == 0 && pcidsi->Ordering.size == 0 &&
136
0
            pcidsi->Supplement == 0);
137
0
}
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
0
{
146
0
    switch (pfont->FontType) {
147
0
    case ft_CID_encrypted:
148
0
        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
0
    case ft_CID_TrueType:
152
0
        return &((const gs_font_cid2 *)pfont)->cidata.common.CIDSystemInfo;
153
0
    default:
154
0
        return 0;
155
0
    }
156
0
}
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
0
{
165
0
    if (info0 == NULL || info1 == NULL)
166
0
        return false;
167
0
    if (info0->Registry.size != info1->Registry.size)
168
0
        return false;
169
0
    if (info0->Ordering.size != info1->Ordering.size)
170
0
        return false;
171
0
    if (memcmp(info0->Registry.data, info1->Registry.data,
172
0
               info0->Registry.size))
173
0
        return false;
174
0
    if (memcmp(info0->Ordering.data, info1->Ordering.data,
175
0
               info0->Ordering.size))
176
0
        return false;
177
0
    return true;
178
0
}
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
1.56k
{
215
1.56k
    gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
216
217
1.56k
    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
1.56k
    return (const gs_font*) (pfont->cidata.FDArray[fidx]);
224
1.56k
}
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
}