xref: /plan9/sys/src/cmd/gs/src/gsfcid.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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