1 /* Copyright (C) 2000 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gsfcid.c,v 1.14 2005/01/13 16:58:07 igor Exp $ */
18 /* Support for CID-keyed fonts */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gsmatrix.h" /* for gsfont.h */
22 #include "gsstruct.h"
23 #include "gxfcid.h"
24 #include "gserrors.h"
25
26 /* CIDSystemInfo structure descriptors */
27 public_st_cid_system_info();
28 public_st_cid_system_info_element();
29
30 /* CID-keyed font structure descriptors */
31 public_st_gs_font_cid_data();
32 public_st_gs_font_cid0();
33 private
ENUM_PTRS_WITH(font_cid0_enum_ptrs,gs_font_cid0 * pfcid0)34 ENUM_PTRS_WITH(font_cid0_enum_ptrs, gs_font_cid0 *pfcid0)
35 {
36 index -= 2;
37 if (index < st_gs_font_cid_data_num_ptrs)
38 return ENUM_USING(st_gs_font_cid_data, &pfcid0->cidata.common,
39 sizeof(gs_font_cid_data), index);
40 ENUM_PREFIX(st_gs_font_base, st_gs_font_cid_data_num_ptrs);
41 }
42 ENUM_PTR(0, gs_font_cid0, cidata.FDArray);
43 ENUM_PTR(1, gs_font_cid0, cidata.proc_data);
44 ENUM_PTRS_END
45 private
46 RELOC_PTRS_WITH(font_cid0_reloc_ptrs, gs_font_cid0 *pfcid0);
47 RELOC_PREFIX(st_gs_font_base);
48 RELOC_USING(st_gs_font_cid_data, &pfcid0->cidata.common,
49 sizeof(st_gs_font_cid_data));
50 RELOC_VAR(pfcid0->cidata.FDArray);
51 RELOC_VAR(pfcid0->cidata.proc_data);
52 RELOC_PTRS_END
53 public_st_gs_font_cid1();
54 private
ENUM_PTRS_WITH(font_cid1_enum_ptrs,gs_font_cid1 * pfcid1)55 ENUM_PTRS_WITH(font_cid1_enum_ptrs, gs_font_cid1 *pfcid1)
56 {
57 if (index < st_cid_system_info_num_ptrs)
58 return ENUM_USING(st_cid_system_info, &pfcid1->cidata.CIDSystemInfo,
59 sizeof(st_cid_system_info), index);
60 ENUM_PREFIX(st_gs_font_base, st_cid_system_info_num_ptrs);
61 }
62 ENUM_PTRS_END
63 private
64 RELOC_PTRS_WITH(font_cid1_reloc_ptrs, gs_font_cid1 *pfcid1);
65 RELOC_PREFIX(st_gs_font_base);
66 RELOC_USING(st_cid_system_info, &pfcid1->cidata.CIDSystemInfo,
67 sizeof(st_cid_system_info));
68 RELOC_PTRS_END
69 public_st_gs_font_cid2();
70 private
ENUM_PTRS_WITH(font_cid2_enum_ptrs,gs_font_cid2 * pfcid2)71 ENUM_PTRS_WITH(font_cid2_enum_ptrs, gs_font_cid2 *pfcid2)
72 {
73 if (index < st_gs_font_cid_data_num_ptrs)
74 return ENUM_USING(st_gs_font_cid_data, &pfcid2->cidata.common,
75 sizeof(gs_font_cid_data), index);
76 ENUM_PREFIX(st_gs_font_type42, st_gs_font_cid_data_num_ptrs);
77 }
78 ENUM_PTRS_END
79 private
80 RELOC_PTRS_WITH(font_cid2_reloc_ptrs, gs_font_cid2 *pfcid2);
81 RELOC_PREFIX(st_gs_font_type42);
82 RELOC_USING(st_gs_font_cid_data, &pfcid2->cidata.common,
83 sizeof(st_gs_font_cid_data));
84 RELOC_PTRS_END
85
86 /* GC descriptor for allocating FDArray for CIDFontType 0 fonts. */
87 gs_private_st_ptr(st_gs_font_type1_ptr, gs_font_type1 *, "gs_font_type1 *",
88 font1_ptr_enum_ptrs, font1_ptr_reloc_ptrs);
89 gs_public_st_element(st_gs_font_type1_ptr_element, gs_font_type1 *,
90 "gs_font_type1 *[]", font1_ptr_element_enum_ptrs,
91 font1_ptr_element_reloc_ptrs, st_gs_font_type1_ptr);
92
93 /*
94 * The CIDSystemInfo of a CMap may be null. We represent this by setting
95 * Registry and Ordering to empty strings, and Supplement to 0.
96 */
97 void
cid_system_info_set_null(gs_cid_system_info_t * pcidsi)98 cid_system_info_set_null(gs_cid_system_info_t *pcidsi)
99 {
100 memset(pcidsi, 0, sizeof(*pcidsi));
101 }
102 bool
cid_system_info_is_null(const gs_cid_system_info_t * pcidsi)103 cid_system_info_is_null(const gs_cid_system_info_t *pcidsi)
104 {
105 return (pcidsi->Registry.size == 0 && pcidsi->Ordering.size == 0 &&
106 pcidsi->Supplement == 0);
107 }
108
109 /*
110 * Get the CIDSystemInfo of a font. If the font is not a CIDFont,
111 * return NULL.
112 */
113 const gs_cid_system_info_t *
gs_font_cid_system_info(const gs_font * pfont)114 gs_font_cid_system_info(const gs_font *pfont)
115 {
116 switch (pfont->FontType) {
117 case ft_CID_encrypted:
118 return &((const gs_font_cid0 *)pfont)->cidata.common.CIDSystemInfo;
119 case ft_CID_user_defined:
120 return &((const gs_font_cid1 *)pfont)->cidata.CIDSystemInfo;
121 case ft_CID_TrueType:
122 return &((const gs_font_cid2 *)pfont)->cidata.common.CIDSystemInfo;
123 default:
124 return 0;
125 }
126 }
127
128 /*
129 * Check CIDSystemInfo compatibility.
130 */
131 bool
gs_is_CIDSystemInfo_compatible(const gs_cid_system_info_t * info0,const gs_cid_system_info_t * info1)132 gs_is_CIDSystemInfo_compatible(const gs_cid_system_info_t *info0,
133 const gs_cid_system_info_t *info1)
134 {
135 if (info0 == NULL || info1 == NULL)
136 return false;
137 if (info0->Registry.size != info1->Registry.size)
138 return false;
139 if (info0->Ordering.size != info1->Ordering.size)
140 return false;
141 if (memcmp(info0->Registry.data, info1->Registry.data,
142 info0->Registry.size))
143 return false;
144 if (memcmp(info0->Ordering.data, info1->Ordering.data,
145 info0->Ordering.size))
146 return false;
147 return true;
148 }
149
150 /*
151 * Provide a default enumerate_glyph procedure for CIDFontType 0 fonts.
152 * Built for simplicity, not for speed.
153 */
154 font_proc_enumerate_glyph(gs_font_cid0_enumerate_glyph); /* check prototype */
155 int
gs_font_cid0_enumerate_glyph(gs_font * font,int * pindex,gs_glyph_space_t ignore_glyph_space,gs_glyph * pglyph)156 gs_font_cid0_enumerate_glyph(gs_font *font, int *pindex,
157 gs_glyph_space_t ignore_glyph_space,
158 gs_glyph *pglyph)
159 {
160 gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
161
162 while (*pindex < pfont->cidata.common.CIDCount) {
163 gs_glyph_data_t gdata;
164 int fidx;
165 gs_glyph glyph = (gs_glyph)(gs_min_cid_glyph + (*pindex)++);
166 int code;
167
168 gdata.memory = pfont->memory;
169 code = pfont->cidata.glyph_data((gs_font_base *)pfont, glyph,
170 &gdata, &fidx);
171 if (code < 0 || gdata.bits.size == 0)
172 continue;
173 *pglyph = glyph;
174 gs_glyph_data_free(&gdata, "gs_font_cid0_enumerate_glyphs");
175 return 0;
176 }
177 *pindex = 0;
178 return 0;
179 }
180
181 /* Return the font from the FDArray at the given index */
182 const gs_font *
gs_cid0_indexed_font(const gs_font * font,int fidx)183 gs_cid0_indexed_font(const gs_font *font, int fidx)
184 {
185 gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
186
187 if (font->FontType != ft_CID_encrypted) {
188 eprintf1("Unexpected font type: %d\n", font->FontType);
189 return 0;
190 }
191 return (const gs_font*) (pfont->cidata.FDArray[fidx]);
192 }
193
194 /* Check whether a CID font has a Type 2 subfont. */
195 bool
gs_cid0_has_type2(const gs_font * font)196 gs_cid0_has_type2(const gs_font *font)
197 {
198 gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
199 int i;
200
201 if (font->FontType != ft_CID_encrypted) {
202 eprintf1("Unexpected font type: %d\n", font->FontType);
203 return false;
204 }
205 for (i = 0; i < pfont->cidata.FDArray_size; i++)
206 if (((const gs_font *)pfont->cidata.FDArray[i])->FontType == ft_encrypted2)
207 return true;
208 return false;
209 }
210