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 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 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 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 98 cid_system_info_set_null(gs_cid_system_info_t *pcidsi) 99 { 100 memset(pcidsi, 0, sizeof(*pcidsi)); 101 } 102 bool 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 * 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 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 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 * 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 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