CAMLprim value has_ps_glyph_names(value f) { CAMLparam1(f); FT_Face face; face = *(FT_Face *)Data_custom_val(f); CAMLreturn(Val_bool(FT_Has_PS_Glyph_Names(face) != 0)); };
static int checkExtraEncoding(FT_Face face, char *encoding_name, int found) { int c; if(strcasecmp(encoding_name, "iso10646-1") == 0) { if(doISO10646_1_encoding && find_cmap(FONT_ENCODING_UNICODE, -1, -1, face)) { int found = 0; /* Export as Unicode if there are at least 15 BMP characters that are not a space or ignored. */ for(c = 0x21; c < 0x10000; c++) { if(CODE_IGNORED(c)) continue; if(FT_Get_Char_Index(face, c) > 0) found++; if(found >= 15) return 1; } return 0; } else return 0; } else if(strcasecmp(encoding_name, "microsoft-symbol") == 0) { if(find_cmap(FONT_ENCODING_TRUETYPE, TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, face)) return 1; else return 0; } else if(strcasecmp(encoding_name, "adobe-fontspecific") == 0) { if(!found) { if(FT_Has_PS_Glyph_Names(face)) return 1; else return 0; } else return 0; } else { fprintf(stderr, "Unknown extra encoding %s\n", encoding_name); return 0; } }
int FTPickMapping(char *xlfd, int length, char *filename, FT_Face face, FTMappingPtr tm) { FontEncPtr encoding; FontMapPtr mapping; FT_CharMap cmap; int ftrc; int symbol = 0; const char *enc, *reg; char *encoding_name = 0; char buf[20]; if(xlfd) encoding_name = FontEncFromXLFD(xlfd, length); if(!encoding_name) encoding_name = "iso8859-1"; symbol = FTEncFontSpecific(encoding_name); #if XFONT_BDFFORMAT ftrc = FT_Get_BDF_Charset_ID(face, &enc, ®); #else ftrc = -1; #endif if(ftrc == 0) { /* Disable reencoding for non-Unicode fonts. This will currently only work for BDFs. */ if(strlen(enc) + strlen(reg) > 18) goto native; strcpy(buf, enc); strcat(buf, "-"); strcat(buf, reg); ErrorF("%s %s\n", buf, encoding_name); if(strcasecmp(buf, "iso10646-1") != 0) { if(strcasecmp(buf, encoding_name) == 0) goto native; return BadFontFormat; } } else if(symbol) { ftrc = FT_Select_Charmap(face, ft_encoding_adobe_custom); if(ftrc == 0) goto native; } encoding = FontEncFind(encoding_name, filename); if(symbol && encoding == NULL) encoding = FontEncFind("microsoft-symbol", filename); if(encoding == NULL) { ErrorF("FreeType: couldn't find encoding '%s' for '%s'\n", encoding_name, filename); return BadFontName; } if(FT_Has_PS_Glyph_Names(face)) { for(mapping = encoding->mappings; mapping; mapping = mapping->next) { if(mapping->type == FONT_ENCODING_POSTSCRIPT) { tm->named = 1; tm->base = 0; tm->mapping = mapping; return Successful; } } } for(mapping = encoding->mappings; mapping; mapping = mapping->next) { if(find_cmap(mapping->type, mapping->pid, mapping->eid, face, &cmap)) { tm->named = 0; tm->cmap = cmap; if(symbol) { /* deal with an undocumented ``feature'' of the Microsft-Symbol cmap */ TT_OS2 *os2; os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); if(os2) tm->base = os2->usFirstCharIndex - 0x20; else tm->base = 0; } else tm->base = 0; tm->mapping = mapping; return Successful; } } return BadFontFormat; native: tm->named = 0; tm->cmap = face->charmap; tm->base = 0; tm->mapping = NULL; return Successful; }
static int glnames( GLYPH *glyph_list ) { #define MAX_NAMELEN 1024 #ifdef XP_PSTEXT char buf[1024]; long i; FT_Error error; #ifdef XP_ONLY_BLOCKS extern unsigned long xp_font_block_offset; extern FTFontPtr xp_xtf; int bc; /* block counter */ /* FixMe: This code should use PsOut_Get_FreeType_Glyph_Name() instead of * duplicating the code */ for( bc = xp_font_block_offset ; bc < (xp_font_block_offset+256) ; bc++ ) { /* Remap X11 font index to FreeType font index */ i = FTRemap(face, &xp_xtf->mapping, bc); if( i >= face->num_glyphs ) continue; #else for(i=0; i < face->num_glyphs; i++) { #endif /* XP_ONLY_BLOCKS */ if( FT_Has_PS_Glyph_Names(face) ) { error = FT_Get_Glyph_Name(face, i, buf, MAX_NAMELEN); } else { error = -1; } if( error ) { /* Check for unicode mapping * See Adobe document "Unicode and Glyph Names" * (http://partners.adobe.com/asn/tech/type/unicodegn.jsp) */ if( (xp_xtf->mapping.mapping->type == FONT_ENCODING_UNICODE) && (i < 0xFFFE) ) { sprintf(buf, "uni%04lx", i); } else { sprintf(buf, "ch%02lx", i); } } glyph_list[i].name = strdup(buf); if(ISDBG(FT)) fprintf(stderr, "%d has name %s\n", i, buf); if (glyph_list[i].name == NULL) { fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__); exit(255); } } return 0; #else char bf[1024]; long i; if( ! FT_HAS_GLYPH_NAMES(face) ) { WARNING_1 fprintf(stderr, "Font has no glyph names\n"); return 1; } for(i=0; i < face->num_glyphs; i++) { if( FT_Get_Glyph_Name(face, i, bf, MAX_NAMELEN) || bf[0]==0 ) { sprintf(bf, "_g_%d", i); WARNING_2 fprintf(stderr, "Glyph No. %d has no postscript name, becomes %s\n", i, bf); } glyph_list[i].name = strdup(bf); if(ISDBG(FT)) fprintf(stderr, "%d has name %s\n", i, bf); if (glyph_list[i].name == NULL) { fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__); exit(255); } } return 0; #endif /* XP_PSTEXT */ } /* * Get the metrics of the glyphs. */ static void glmetrics( GLYPH *glyph_list ) { GLYPH *g; int i; FT_Glyph_Metrics *met; FT_BBox bbox; FT_Glyph gly; #ifdef XP_ONLY_BLOCKS extern unsigned long xp_font_block_offset; extern FTFontPtr xp_xtf; int bc; /* block counter */ for( bc = xp_font_block_offset ; bc < (xp_font_block_offset+256) ; bc++ ) { /* Remap X11 font index to FreeType font index */ i = FTRemap(face, &xp_xtf->mapping, bc); if( i >= face->num_glyphs ) continue; #else for(i=0; i < face->num_glyphs; i++) { #endif /* XP_ONLY_BLOCKS */ g = &(glyph_list[i]); if( FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE) ) { fprintf(stderr, "Can't load glyph %s, skipped\n", g->name); continue; } met = &face->glyph->metrics; if(FT_HAS_HORIZONTAL(face)) { g->width = met->horiAdvance; g->lsb = met->horiBearingX; } else { WARNING_2 fprintf(stderr, "Glyph %s has no horizontal metrics, guessed them\n", g->name); g->width = met->width; g->lsb = 0; } if( FT_Get_Glyph(face->glyph, &gly) ) { fprintf(stderr, "Can't access glyph %s bbox, skipped\n", g->name); continue; } FT_Glyph_Get_CBox(gly, ft_glyph_bbox_unscaled, &bbox); g->xMin = bbox.xMin; g->yMin = bbox.yMin; g->xMax = bbox.xMax; g->yMax = bbox.yMax; g->ttf_pathlen = face->glyph->outline.n_points; } } /* * Get the original encoding of the font. * Returns 1 for if the original encoding is Unicode, 2 if the * original encoding is other 16-bit, 0 if 8-bit. */ static int glenc( GLYPH *glyph_list, int *encoding, int *unimap ) { #ifdef XP_PSTEXT int i, e; unsigned code; extern FTFontPtr xp_xtf; extern unsigned long xp_font_block_offset; enc_found = 1; enc_type = 0; for(i=0; i<ENCTABSZ; i++) { if(encoding[i] != -1) continue; /* Remap X11 font index to FreeType font index */ code = FTRemap(face, &xp_xtf->mapping, xp_font_block_offset+i); if(code == 0) continue; /* .notdef */ encoding[i] = code; } return enc_type; #else int i, e; unsigned code; if(ISDBG(FT)) for(e=0; e < face->num_charmaps; e++) { fprintf(stderr, "found encoding pid=%d eid=%d\n", face->charmaps[e]->platform_id, face->charmaps[e]->encoding_id); } if(enc_found) goto populate_map; enc_type = 0; /* first check for an explicit PID/EID */ if(force_pid != -1) { for(e=0; e < face->num_charmaps; e++) { if(face->charmaps[e]->platform_id == force_pid && face->charmaps[e]->encoding_id == force_eid) { WARNING_1 fprintf(stderr, "Found Encoding PID=%d/EID=%d\n", force_pid, force_eid); if( FT_Set_Charmap(face, face->charmaps[e]) ) { fprintf(stderr, "**** Cannot set charmap in FreeType ****\n"); exit(1); } enc_type = 1; goto populate_map; } } fprintf(stderr, "*** TTF encoding table PID=%d/EID=%d not found\n", force_pid, force_eid); exit(1); } /* next check for a direct Adobe mapping */ if(!forcemap) { for(e=0; e < face->num_charmaps; e++) { if(face->charmaps[e]->encoding == ft_encoding_adobe_custom) { WARNING_1 fputs("Found Adobe Custom Encoding\n", stderr); if( FT_Set_Charmap(face, face->charmaps[e]) ) { fprintf(stderr, "**** Cannot set charmap in FreeType ****\n"); exit(1); } goto populate_map; } } } for(e=0; e < face->num_charmaps; e++) { if(face->charmaps[e]->platform_id == 3) { switch(face->charmaps[e]->encoding_id) { case 0: WARNING_1 fputs("Found Symbol Encoding\n", stderr); break; case 1: WARNING_1 fputs("Found Unicode Encoding\n", stderr); enc_type = 1; break; default: WARNING_1 { fprintf(stderr, "****MS Encoding ID %d not supported****\n", face->charmaps[e]->encoding_id); fputs("Treating it like Symbol encoding\n", stderr); } break; } break; } } if(e >= face->num_charmaps) { WARNING_1 fputs("No Microsoft encoding, using first encoding available\n", stderr); e = 0; } if( FT_Set_Charmap(face, face->charmaps[e]) ) { fprintf(stderr, "**** Cannot set charmap in FreeType ****\n"); exit(1); } populate_map: enc_found = 1; for(i=0; i<ENCTABSZ; i++) { if(encoding[i] != -1) continue; if(enc_type == 1 || forcemap) { code = unimap[i]; if(code == (unsigned) -1) continue; } else code = i; code = FT_Get_Char_Index(face, code); if(0 && ISDBG(FT)) fprintf(stderr, "code of %3d is %3d\n", i, code); if(code == 0) continue; /* .notdef */ encoding[i] = code; } return enc_type; #endif /* XP_PSTEXT */ }
static int checkEncoding(FT_Face face, char *encoding_name) { FontEncPtr encoding; FontMapPtr mapping; int i, j, c, koi8; char *n; encoding = FontEncFind(encoding_name, NULL); if(!encoding) return 0; /* An encoding is ``small'' if one of the following is true: - it is linear and has no more than 256 codepoints; or - it is a matrix encoding and has no more than one column. For small encodings using Unicode indices, we require perfect coverage except for CODE_IGNORED and KOI-8 IBM-PC compatibility. For large encodings, we require coverage up to bigEncodingFuzz. For encodings using PS names (currently Adobe Standard and Adobe Symbol only), we require perfect coverage. */ if(FT_Has_PS_Glyph_Names(face)) { for(mapping = encoding->mappings; mapping; mapping = mapping->next) { if(mapping->type == FONT_ENCODING_POSTSCRIPT) { if(encoding->row_size > 0) { for(i = encoding->first; i < encoding->size; i++) { for(j = encoding->first_col; j < encoding->row_size; j++) { n = FontEncName((i<<8) | j, mapping); if(n && FT_Get_Name_Index(face, n) == 0) { return 0; } } } return 1; } else { for(i = encoding->first; i < encoding->size; i++) { n = FontEncName(i, mapping); if(n && FT_Get_Name_Index(face, n) == 0) { return 0; } } return 1; } } } } for(mapping = encoding->mappings; mapping; mapping = mapping->next) { if(find_cmap(mapping->type, mapping->pid, mapping->eid, face)) { int total = 0, failed = 0; if(encoding->row_size > 0) { int estimate = (encoding->size - encoding->first) * (encoding->row_size - encoding->first_col); for(i = encoding->first; i < encoding->size; i++) { for(j = encoding->first_col; j < encoding->row_size; j++) { c = FontEncRecode((i<<8) | j, mapping); if(CODE_IGNORED(c)) { continue; } else { if(FT_Get_Char_Index(face, c) == 0) { failed++; } total++; if((encoding->size <= 1 && failed > 0) || ((float)failed >= bigEncodingFuzz * estimate)) { return 0; } } } } if((float)failed >= total * bigEncodingFuzz) return 0; else return 1; } else { int estimate = encoding->size - encoding->first; /* For the KOI8 encodings, we ignore the lack of linedrawing and pseudo-math characters */ if(strncmp(encoding->name, "koi8-", 5) == 0) koi8 = 1; else koi8 = 0; for(i = encoding->first; i < encoding->size; i++) { c = FontEncRecode(i, mapping); if(CODE_IGNORED(c) || (koi8 && ((c >= 0x2200 && c < 0x2600) || c == 0x00b2))) { continue; } else { if(FT_Get_Char_Index(face, c) == 0) { failed++; } total++; if((encoding->size <= 256 && failed > 0) || ((float)failed >= bigEncodingFuzz * estimate)) { return 0; } } } if((float)failed >= total * bigEncodingFuzz) return 0; else return 1; } } } return 0; }