/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 | } |