1 /* Copyright (C) 2000, 2001 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: zfcid1.c,v 1.23 2004/11/19 04:39:11 ray Exp $ */ 18 /* CIDFontType 1 and 2 operators */ 19 #include "memory_.h" 20 #include "ghost.h" 21 #include "oper.h" 22 #include "gsmatrix.h" 23 #include "gsccode.h" 24 #include "gsstruct.h" 25 #include "gsgcache.h" 26 #include "gxfcid.h" 27 #include "bfont.h" 28 #include "icid.h" 29 #include "idict.h" 30 #include "idparam.h" 31 #include "ifcid.h" 32 #include "ichar1.h" 33 #include "ifont42.h" 34 #include "store.h" 35 #include "stream.h" 36 #include "files.h" 37 38 /* ---------------- CIDFontType 1 (FontType 10) ---------------- */ 39 40 /* <string|name> <font_dict> .buildfont10 <string|name> <font> */ 41 private int 42 zbuildfont10(i_ctx_t *i_ctx_p) 43 { 44 os_ptr op = osp; 45 build_proc_refs build; 46 int code = build_gs_font_procs(op, &build); 47 gs_cid_system_info_t cidsi; 48 gs_font_base *pfont; 49 50 if (code < 0) 51 return code; 52 code = cid_font_system_info_param(&cidsi, op); 53 if (code < 0) 54 return code; 55 make_null(&build.BuildChar); /* only BuildGlyph */ 56 code = build_gs_simple_font(i_ctx_p, op, &pfont, ft_CID_user_defined, 57 &st_gs_font_cid1, &build, 58 bf_Encoding_optional | 59 bf_UniqueID_ignored); 60 if (code < 0) 61 return code; 62 ((gs_font_cid1 *)pfont)->cidata.CIDSystemInfo = cidsi; 63 return define_gs_font((gs_font *)pfont); 64 } 65 66 /* ---------------- CIDFontType 2 (FontType 11) ---------------- */ 67 68 /* ------ Accessing ------ */ 69 70 /* Map a glyph CID to a TrueType glyph number using the CIDMap. */ 71 private int 72 z11_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph) 73 { 74 const ref *pcidmap = &pfont_data(pfont)->u.type42.CIDMap; 75 ulong cid = glyph - gs_min_cid_glyph; 76 int gdbytes = pfont->cidata.common.GDBytes; 77 int gnum = 0; 78 const byte *data; 79 int i, code; 80 ref rcid; 81 ref *prgnum; 82 83 switch (r_type(pcidmap)) { 84 case t_string: 85 if (cid >= r_size(pcidmap) / gdbytes) 86 return_error(e_rangecheck); 87 data = pcidmap->value.const_bytes + cid * gdbytes; 88 break; 89 case t_integer: 90 return cid + pcidmap->value.intval; 91 case t_dictionary: 92 make_int(&rcid, cid); 93 code = dict_find(pcidmap, &rcid, &prgnum); 94 if (code <= 0) 95 return (code < 0 ? code : gs_note_error(e_undefined)); 96 if (!r_has_type(prgnum, t_integer)) 97 return_error(e_typecheck); 98 return prgnum->value.intval; 99 default: /* array type */ 100 code = string_array_access_proc(pfont->memory, pcidmap, 1, cid * gdbytes, 101 gdbytes, &data); 102 103 if (code < 0) 104 return code; 105 if ( code > 0 ) 106 return_error(e_invalidfont); 107 } 108 for (i = 0; i < gdbytes; ++i) 109 gnum = (gnum << 8) + data[i]; 110 return gnum; 111 } 112 113 /* Handle MetricsCount when accessing outline or metrics information. */ 114 private int 115 z11_get_outline(gs_font_type42 * pfont, uint glyph_index, 116 gs_glyph_data_t *pgd) 117 { 118 gs_font_cid2 *const pfcid = (gs_font_cid2 *)pfont; 119 int skip = pfcid->cidata.MetricsCount << 1; 120 int code = pfcid->cidata.orig_procs.get_outline(pfont, glyph_index, pgd); 121 122 if (code >= 0) { 123 uint size = pgd->bits.size; 124 125 if (size <= skip) { 126 gs_glyph_data_free(pgd, "z11_get_outline"); 127 gs_glyph_data_from_null(pgd); 128 } else { 129 gs_glyph_data_substring(pgd, skip, size - skip); 130 } 131 } 132 return code; 133 } 134 135 #define GET_U16_MSB(p) (((uint)((p)[0]) << 8) + (p)[1]) 136 #define GET_S16_MSB(p) (int)((GET_U16_MSB(p) ^ 0x8000) - 0x8000) 137 138 double recipunitsperem(gs_font_type42 *pfont); 139 140 private int 141 z11_get_metrics(gs_font_type42 * pfont, uint glyph_index, int wmode, 142 float sbw[4]) 143 { 144 gs_font_cid2 *const pfcid = (gs_font_cid2 *)pfont; 145 int skip = pfcid->cidata.MetricsCount << 1; 146 gs_glyph_data_t gdata; 147 const byte *pmetrics; 148 int lsb, width; 149 int code = 0; 150 151 gdata.memory = pfont->memory; 152 if (wmode >= skip >> 2 || 153 (code = pfcid->cidata.orig_procs.get_outline(pfont, glyph_index, &gdata)) < 0 || 154 gdata.bits.size < skip 155 ) 156 return pfcid->cidata.orig_procs.get_metrics(pfont, glyph_index, wmode, 157 sbw); 158 pmetrics = gdata.bits.data + skip - 4 - (wmode << 2); 159 lsb = GET_S16_MSB(pmetrics + 2); 160 width = GET_U16_MSB(pmetrics + 0); 161 { 162 double factor = recipunitsperem(pfont); 163 164 if (wmode) { 165 sbw[0] = 0, sbw[1] = -lsb * factor; 166 sbw[2] = 0, sbw[3] = -width * factor; 167 } else { 168 sbw[0] = lsb * factor, sbw[1] = 0; 169 sbw[2] = width * factor, sbw[3] = 0; 170 } 171 } 172 gs_glyph_data_free(&gdata, "z11_get_metrics"); 173 return 0; 174 } 175 176 private int 177 z11_glyph_info_aux(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, 178 int members, gs_glyph_info_t *info) 179 { 180 gs_font_cid2 *fontCID2 = (gs_font_cid2 *)font; 181 uint glyph_index; 182 int code = (glyph > GS_MIN_GLYPH_INDEX 183 ? glyph - GS_MIN_GLYPH_INDEX 184 : fontCID2->cidata.CIDMap_proc(fontCID2, glyph)); 185 186 if(code < 0) 187 return code; 188 glyph_index = (uint)code; 189 return gs_type42_glyph_info_by_gid(font, glyph, pmat, members, info, glyph_index); 190 } 191 192 private int 193 z11_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, 194 int members, gs_glyph_info_t *info) 195 { 196 int wmode = (members & GLYPH_INFO_WIDTH0 ? 0 : 1); 197 198 return z1_glyph_info_generic(font, glyph, pmat, members, info, 199 &z11_glyph_info_aux, wmode); 200 } 201 202 203 /* Enumerate glyphs (keys) from GlyphDirectory instead of loca / glyf. */ 204 private int 205 z11_enumerate_glyph(gs_font *font, int *pindex, 206 gs_glyph_space_t glyph_space, gs_glyph *pglyph) 207 { 208 gs_font_cid2 *pfont = (gs_font_cid2 *)font; 209 int code0 = z11_CIDMap_proc(pfont, GS_MIN_CID_GLYPH); 210 int code; 211 212 for (;;) { 213 code = z11_CIDMap_proc(pfont, GS_MIN_CID_GLYPH + *pindex); 214 215 if (code < 0) { 216 *pindex = 0; 217 return 0; 218 } 219 (*pindex)++; 220 if (*pindex == 1 || code != code0) 221 break; 222 /* else skip an underfined glyph */ 223 } 224 if (glyph_space == GLYPH_SPACE_INDEX) 225 *pglyph = GS_MIN_GLYPH_INDEX + (uint)code; 226 else 227 *pglyph = GS_MIN_CID_GLYPH + (uint)(*pindex - 1); 228 return 0; 229 } 230 231 private uint 232 z11_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph) 233 { 234 int code = z11_CIDMap_proc((gs_font_cid2 *)pfont, glyph); 235 236 return (code < 0 ? 0 /* notdef */: (uint)code); 237 } 238 239 240 private int 241 z11_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat, 242 gx_path *ppath, double sbw[4]) 243 { 244 return gs_type42_glyph_outline(font, WMode, 245 z11_get_glyph_index((gs_font_type42 *)font, glyph) + GS_MIN_GLYPH_INDEX, 246 pmat, ppath, sbw); 247 } 248 249 /* ------ Defining ------ */ 250 251 /* <string|name> <font_dict> .buildfont11 <string|name> <font> */ 252 private int 253 zbuildfont11(i_ctx_t *i_ctx_p) 254 { 255 os_ptr op = osp; 256 gs_font_cid_data common; 257 gs_font_type42 *pfont; 258 gs_font_cid2 *pfcid; 259 int MetricsCount; 260 ref rcidmap, ignore_gdir, file, *pfile, cfnstr, *pCIDFontName, CIDFontName; 261 ulong loca_glyph_pos[2][2]; 262 int code = cid_font_data_param(op, &common, &ignore_gdir); 263 264 if (code < 0 || 265 (code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 || 266 (code = dict_int_param(op, "MetricsCount", 0, 4, 0, &MetricsCount)) < 0 267 ) 268 return code; 269 /* 270 * Since build_gs_simple_font may resize the dictionary and cause 271 * pointers to become invalid, save CIDFontName 272 */ 273 CIDFontName = *pCIDFontName; 274 if (MetricsCount & 1) /* only allowable values are 0, 2, 4 */ 275 return_error(e_rangecheck); 276 code = dict_find_string(op, "File", &pfile); 277 if (code < 0 && code != e_dictfull) 278 return code; 279 if (code > 0) { 280 ref *file_table_pos, *a, v; 281 const char *name[2] = {"loca", "glyf"}; 282 int i, j; 283 284 /* 285 * Since build_gs_simple_font may resize the dictionary and cause 286 * pointers to become invalid, save File and CIDFontName 287 */ 288 file = *pfile; 289 check_read_type(file, t_file); 290 code = dict_find_string(op, "file_table_pos", &file_table_pos); 291 if (code <= 0 || r_type(file_table_pos) != t_dictionary) 292 return_error(e_invalidfont); 293 for (i = 0; i < 2; i++) { 294 code = dict_find_string(file_table_pos, name[i], &a); 295 if (code <= 0 || r_type(a) != t_array) 296 return_error(e_invalidfont); 297 for (j = 0; j < 2; j++) { 298 code = array_get(imemory, a, j, &v); 299 if (code < 0 || r_type(&v) != t_integer) 300 return_error(e_invalidfont); 301 loca_glyph_pos[i][j] = v.value.intval; 302 } 303 } 304 } else 305 pfile = NULL; 306 code = font_string_array_param(imemory, op, "CIDMap", &rcidmap); 307 switch (code) { 308 case 0: /* in PLRM3 */ 309 gdb: 310 /* GDBytes is required for indexing a string or string array. */ 311 if (common.GDBytes == 0) 312 return_error(e_rangecheck); 313 break; 314 default: 315 return code; 316 case e_typecheck: 317 switch (r_type(&rcidmap)) { 318 case t_string: /* in PLRM3 */ 319 goto gdb; 320 case t_dictionary: /* added in 3011 */ 321 case t_integer: /* added in 3011 */ 322 break; 323 default: 324 return code; 325 } 326 break; 327 } 328 code = build_gs_TrueType_font(i_ctx_p, op, &pfont, ft_CID_TrueType, 329 &st_gs_font_cid2, 330 (const char *)0, "%Type11BuildGlyph", 331 bf_Encoding_optional | 332 bf_UniqueID_ignored | 333 bf_CharStrings_optional); 334 if (code < 0) 335 return code; 336 pfcid = (gs_font_cid2 *)pfont; 337 pfcid->cidata.common = common; 338 pfcid->cidata.MetricsCount = MetricsCount; 339 ref_assign(&pfont_data(pfont)->u.type42.CIDMap, &rcidmap); 340 pfcid->cidata.CIDMap_proc = z11_CIDMap_proc; 341 pfont->procs.enumerate_glyph = z11_enumerate_glyph; 342 pfont->procs.glyph_info = z11_glyph_info; 343 pfont->procs.glyph_outline = z11_glyph_outline; 344 pfont->data.get_glyph_index = z11_get_glyph_index; 345 get_font_name(imemory, &cfnstr, &CIDFontName); 346 copy_font_name(&pfcid->font_name, &cfnstr); 347 if (MetricsCount) { 348 /* "Wrap" the glyph accessor procedures. */ 349 pfcid->cidata.orig_procs.get_outline = pfont->data.get_outline; 350 pfont->data.get_outline = z11_get_outline; 351 pfcid->cidata.orig_procs.get_metrics = pfont->data.get_metrics; 352 pfont->data.get_metrics = z11_get_metrics; 353 } else if(pfile != NULL) { 354 /* 355 * We assume that disk fonts has no MetricsCount. 356 * We could do not, but the number of virtual function wariants increases. 357 */ 358 stream *s; 359 360 check_read_file(s, &file); 361 pfont->data.loca = loca_glyph_pos[0][0]; 362 pfont->data.glyf = loca_glyph_pos[1][0]; 363 pfont->data.get_outline = gs_get_glyph_data_cached; 364 pfont->data.gdcache = gs_glyph_cache__alloc(pfont, s, gs_type42_get_outline_from_TT_file); 365 } 366 return define_gs_font((gs_font *)pfont); 367 } 368 369 /* <cid11font> <cid> .type11mapcid <glyph_index> */ 370 private int 371 ztype11mapcid(i_ctx_t *i_ctx_p) 372 { 373 os_ptr op = osp; 374 gs_font *pfont; 375 int code = font_param(op - 1, &pfont); 376 377 if (code < 0) 378 return code; 379 check_type(*op, t_integer); 380 #if defined(TEST) 381 /* Allow a Type 42 font here, for testing .wrapfont. */ 382 if (pfont->FontType == ft_TrueType) { 383 /* Use the CID as the glyph index. */ 384 if (op->value.intval < 0 || 385 op->value.intval >= ((gs_font_type42 *)pfont)->data.numGlyphs 386 ) 387 return_error(e_rangecheck); 388 code = (int)op->value.intval; 389 } else 390 #endif 391 { 392 if (pfont->FontType != ft_CID_TrueType) 393 return_error(e_invalidfont); 394 code = z11_CIDMap_proc((gs_font_cid2 *)pfont, 395 (gs_glyph)(gs_min_cid_glyph + op->value.intval)); 396 } 397 if (code < 0) 398 return code; 399 make_int(op - 1, code); 400 pop(1); 401 return 0; 402 } 403 404 /* <Decoding> <TT_cmap> <SubstNWP> <GDBytes> <CIDMap> .fillCIDMap - */ 405 private int 406 zfillCIDMap(i_ctx_t *i_ctx_p) 407 { 408 os_ptr op = osp; 409 ref *Decoding = op - 4, *TT_cmap = op - 3, *SubstNWP = op - 2, 410 *GDBytes = op - 1, *CIDMap = op; 411 int code; 412 413 check_type(*Decoding, t_dictionary); 414 check_type(*TT_cmap, t_array); 415 check_type(*SubstNWP, t_array); 416 check_type(*GDBytes, t_integer); 417 check_type(*CIDMap, t_array); 418 code = cid_fill_CIDMap(imemory, Decoding, TT_cmap, SubstNWP, GDBytes->value.intval, CIDMap); 419 pop(5); 420 return code; 421 } 422 423 /* ------ Initialization procedure ------ */ 424 425 const op_def zfcid1_op_defs[] = 426 { 427 {"2.buildfont10", zbuildfont10}, 428 {"2.buildfont11", zbuildfont11}, 429 {"2.type11mapcid", ztype11mapcid}, 430 {"2.fillCIDMap", zfillCIDMap}, 431 op_def_end(0) 432 }; 433