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 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; }