unsigned FTRemap(FT_Face face, FTMappingPtr tm, unsigned code) { unsigned index; char *name; unsigned glyph_index; if(tm->mapping) { if(tm->named) { name = FontEncName(code, tm->mapping); if(!name) return 0; glyph_index = FT_Get_Name_Index(face, name); return glyph_index; } else { index = FontEncRecode(code, tm->mapping) + tm->base; FT_Set_Charmap(face, tm->cmap); glyph_index = FT_Get_Char_Index(face, index); return glyph_index; } } else { if(code < 0x100) { index = code; FT_Set_Charmap(face, tm->cmap); glyph_index = FT_Get_Char_Index(face, index); return glyph_index; } else return 0; } }
/* SumatraPDF: provide a bullet fallback font */ static pdf_font_desc * pdf_load_bullet_font(fz_context *ctx) { pdf_font_desc *fontdesc = pdf_new_font_desc(ctx); int gid, i; fz_try(ctx) { pdf_load_builtin_font(ctx, fontdesc, "Symbol"); fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1); fontdesc->cid_to_gid_len = 256; fontdesc->cid_to_gid = fz_malloc_array(ctx, 256, sizeof(unsigned short)); gid = FT_Get_Name_Index(fontdesc->font->ft_face, "bullet"); for (i = 0; i < 256; i++) fontdesc->cid_to_gid[i] = gid; pdf_set_default_hmtx(ctx, fontdesc, ft_width(ctx, fontdesc, 0)); } fz_catch(ctx) { pdf_drop_font(ctx, fontdesc); fz_rethrow(ctx); } return fontdesc; }
LEGlyphID XeTeXFontInst_FT2::mapGlyphToIndex(const char* glyphName) const { LEGlyphID rval = FT_Get_Name_Index(face, const_cast<char*>(glyphName)); if (rval == 0) rval = XeTeXFontInst::mapGlyphToIndex(glyphName); return rval; }
Py::Object FT2Font::get_name_index(const Py::Tuple & args) { _VERBOSE("FT2Font::get_name_index"); args.verify_length(1); std::string glyphname = Py::String(args[0]); return Py::Long((long) FT_Get_Name_Index(face, (FT_String *) glyphname.c_str())); }
static pdf_font_desc * pdf_load_simple_font(pdf_document *xref, pdf_obj *dict) { pdf_obj *descriptor; pdf_obj *encoding; pdf_obj *widths; unsigned short *etable = NULL; pdf_font_desc *fontdesc = NULL; char *subtype; FT_Face face; FT_CharMap cmap; int symbolic; int kind; char *basefont; char *estrings[256]; char ebuffer[256][32]; int i, k, n; int fterr; fz_context *ctx = xref->ctx; fz_var(fontdesc); fz_var(etable); basefont = pdf_to_name(pdf_dict_gets(dict, "BaseFont")); /* Load font file */ fz_try(ctx) { fontdesc = pdf_new_font_desc(ctx); descriptor = pdf_dict_gets(dict, "FontDescriptor"); if (descriptor) pdf_load_font_descriptor(fontdesc, xref, descriptor, NULL, basefont); else pdf_load_builtin_font(ctx, fontdesc, basefont); /* Some chinese documents mistakenly consider WinAnsiEncoding to be codepage 936 */ if (descriptor && pdf_is_string(pdf_dict_gets(descriptor, "FontName")) && !pdf_dict_gets(dict, "ToUnicode") && !strcmp(pdf_to_name(pdf_dict_gets(dict, "Encoding")), "WinAnsiEncoding") && pdf_to_int(pdf_dict_gets(descriptor, "Flags")) == 4) { char *cp936fonts[] = { "\xCB\xCE\xCC\xE5", "SimSun,Regular", "\xBA\xDA\xCC\xE5", "SimHei,Regular", "\xBF\xAC\xCC\xE5_GB2312", "SimKai,Regular", "\xB7\xC2\xCB\xCE_GB2312", "SimFang,Regular", "\xC1\xA5\xCA\xE9", "SimLi,Regular", NULL }; for (i = 0; cp936fonts[i]; i += 2) if (!strcmp(basefont, cp936fonts[i])) break; if (cp936fonts[i]) { fz_warn(ctx, "workaround for S22PDF lying about chinese font encodings"); pdf_drop_font(ctx, fontdesc); fontdesc = pdf_new_font_desc(ctx); pdf_load_font_descriptor(fontdesc, xref, descriptor, "Adobe-GB1", cp936fonts[i+1]); fontdesc->encoding = pdf_load_system_cmap(ctx, "GBK-EUC-H"); fontdesc->to_unicode = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2"); fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2"); face = fontdesc->font->ft_face; kind = ft_kind(face); goto skip_encoding; } } face = fontdesc->font->ft_face; kind = ft_kind(face); /* Encoding */ symbolic = fontdesc->flags & 4; if (face->num_charmaps > 0) cmap = face->charmaps[0]; else cmap = NULL; for (i = 0; i < face->num_charmaps; i++) { FT_CharMap test = face->charmaps[i]; if (kind == TYPE1) { if (test->platform_id == 7) cmap = test; } if (kind == TRUETYPE) { if (test->platform_id == 1 && test->encoding_id == 0) cmap = test; if (test->platform_id == 3 && test->encoding_id == 1) cmap = test; if (symbolic && test->platform_id == 3 && test->encoding_id == 0) cmap = test; } } if (cmap) { fterr = FT_Set_Charmap(face, cmap); if (fterr) fz_warn(ctx, "freetype could not set cmap: %s", ft_error_string(fterr)); } else fz_warn(ctx, "freetype could not find any cmaps"); etable = fz_malloc_array(ctx, 256, sizeof(unsigned short)); fontdesc->size += 256 * sizeof(unsigned short); for (i = 0; i < 256; i++) { estrings[i] = NULL; etable[i] = 0; } encoding = pdf_dict_gets(dict, "Encoding"); if (encoding) { if (pdf_is_name(encoding)) pdf_load_encoding(estrings, pdf_to_name(encoding)); if (pdf_is_dict(encoding)) { pdf_obj *base, *diff, *item; base = pdf_dict_gets(encoding, "BaseEncoding"); if (pdf_is_name(base)) pdf_load_encoding(estrings, pdf_to_name(base)); else if (!fontdesc->is_embedded && !symbolic) pdf_load_encoding(estrings, "StandardEncoding"); diff = pdf_dict_gets(encoding, "Differences"); if (pdf_is_array(diff)) { n = pdf_array_len(diff); k = 0; for (i = 0; i < n; i++) { item = pdf_array_get(diff, i); if (pdf_is_int(item)) k = pdf_to_int(item); if (pdf_is_name(item) && k >= 0 && k < nelem(estrings)) estrings[k++] = pdf_to_name(item); } } } } /* start with the builtin encoding */ for (i = 0; i < 256; i++) etable[i] = ft_char_index(face, i); fz_lock(ctx, FZ_LOCK_FREETYPE); /* built-in and substitute fonts may be a different type than what the document expects */ subtype = pdf_to_name(pdf_dict_gets(dict, "Subtype")); if (!strcmp(subtype, "Type1")) kind = TYPE1; else if (!strcmp(subtype, "MMType1")) kind = TYPE1; else if (!strcmp(subtype, "TrueType")) kind = TRUETYPE; else if (!strcmp(subtype, "CIDFontType0")) kind = TYPE1; else if (!strcmp(subtype, "CIDFontType2")) kind = TRUETYPE; /* encode by glyph name where we can */ if (kind == TYPE1) { for (i = 0; i < 256; i++) { if (estrings[i]) { etable[i] = FT_Get_Name_Index(face, estrings[i]); if (etable[i] == 0) { int aglcode = pdf_lookup_agl(estrings[i]); const char **dupnames = pdf_lookup_agl_duplicates(aglcode); while (*dupnames) { etable[i] = FT_Get_Name_Index(face, (char*)*dupnames); if (etable[i]) break; dupnames++; } } } } } /* encode by glyph name where we can */ if (kind == TRUETYPE) { /* Unicode cmap */ if (!symbolic && face->charmap && face->charmap->platform_id == 3) { for (i = 0; i < 256; i++) { if (estrings[i]) { int aglcode = pdf_lookup_agl(estrings[i]); if (!aglcode) etable[i] = FT_Get_Name_Index(face, estrings[i]); else etable[i] = ft_char_index(face, aglcode); } } } /* MacRoman cmap */ else if (!symbolic && face->charmap && face->charmap->platform_id == 1) { for (i = 0; i < 256; i++) { if (estrings[i]) { k = lookup_mre_code(estrings[i]); if (k <= 0) etable[i] = FT_Get_Name_Index(face, estrings[i]); else etable[i] = ft_char_index(face, k); } } } /* Symbolic cmap */ else if (!face->charmap || face->charmap->encoding != FT_ENCODING_MS_SYMBOL) { for (i = 0; i < 256; i++) { if (estrings[i]) { etable[i] = FT_Get_Name_Index(face, estrings[i]); if (etable[i] == 0) etable[i] = ft_char_index(face, i); } } } } /* try to reverse the glyph names from the builtin encoding */ for (i = 0; i < 256; i++) { if (etable[i] && !estrings[i]) { if (FT_HAS_GLYPH_NAMES(face)) { fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32); if (fterr) fz_warn(ctx, "freetype get glyph name (gid %d): %s", etable[i], ft_error_string(fterr)); if (ebuffer[i][0]) estrings[i] = ebuffer[i]; } else { estrings[i] = (char*) pdf_win_ansi[i]; /* discard const */ } } } /* symbolic Type 1 fonts with an implicit encoding and non-standard glyph names */ if (kind == TYPE1 && symbolic) { for (i = 0; i < 256; i++) if (etable[i] && estrings[i] && !pdf_lookup_agl(estrings[i])) estrings[i] = (char*) pdf_standard[i]; } fz_unlock(ctx, FZ_LOCK_FREETYPE); fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1); fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding); fontdesc->cid_to_gid_len = 256; fontdesc->cid_to_gid = etable; fz_try(ctx) { pdf_load_to_unicode(xref, fontdesc, estrings, NULL, pdf_dict_gets(dict, "ToUnicode")); } fz_catch(ctx) { fz_warn(ctx, "cannot load ToUnicode CMap"); } skip_encoding: /* Widths */ pdf_set_default_hmtx(ctx, fontdesc, fontdesc->missing_width); widths = pdf_dict_gets(dict, "Widths"); if (widths) { int first, last; first = pdf_to_int(pdf_dict_gets(dict, "FirstChar")); last = pdf_to_int(pdf_dict_gets(dict, "LastChar")); if (first < 0 || last > 255 || first > last) first = last = 0; for (i = 0; i < last - first + 1; i++) { int wid = pdf_to_int(pdf_array_get(widths, i)); pdf_add_hmtx(ctx, fontdesc, i + first, i + first, wid); } } else { fz_lock(ctx, FZ_LOCK_FREETYPE); fterr = FT_Set_Char_Size(face, 1000, 1000, 72, 72); if (fterr) fz_warn(ctx, "freetype set character size: %s", ft_error_string(fterr)); for (i = 0; i < 256; i++) { pdf_add_hmtx(ctx, fontdesc, i, i, ft_width(ctx, fontdesc, i)); } fz_unlock(ctx, FZ_LOCK_FREETYPE); } pdf_end_hmtx(ctx, fontdesc); } fz_catch(ctx) { if (fontdesc && etable != fontdesc->cid_to_gid) fz_free(ctx, etable); pdf_drop_font(ctx, fontdesc); fz_throw(ctx, "cannot load simple font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict)); } return fontdesc; }
static fz_error loadsimplefont(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict) { fz_error error; fz_obj *descriptor; fz_obj *encoding; fz_obj *widths; unsigned short *etable = nil; pdf_fontdesc *fontdesc; fz_bbox bbox; FT_Face face; FT_CharMap cmap; int kind; int symbolic; char *basefont; char *fontname; char *estrings[256]; char ebuffer[256][32]; int i, k, n; int fterr; basefont = fz_toname(fz_dictgets(dict, "BaseFont")); fontname = cleanfontname(basefont); /* Load font file */ fontdesc = pdf_newfontdesc(); pdf_logfont("load simple font (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), fontdesc); pdf_logfont("basefont %s -> %s\n", basefont, fontname); descriptor = fz_dictgets(dict, "FontDescriptor"); if (descriptor) error = pdf_loadfontdescriptor(fontdesc, xref, descriptor, nil, basefont); else error = pdf_loadbuiltinfont(fontdesc, fontname); if (error) goto cleanup; face = fontdesc->font->ftface; kind = ftkind(face); pdf_logfont("ft name '%s' '%s'\n", face->family_name, face->style_name); bbox.x0 = (face->bbox.xMin * 1000) / face->units_per_EM; bbox.y0 = (face->bbox.yMin * 1000) / face->units_per_EM; bbox.x1 = (face->bbox.xMax * 1000) / face->units_per_EM; bbox.y1 = (face->bbox.yMax * 1000) / face->units_per_EM; pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1); if (bbox.x0 == bbox.x1) fz_setfontbbox(fontdesc->font, -1000, -1000, 2000, 2000); else fz_setfontbbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1); /* Encoding */ symbolic = fontdesc->flags & 4; if (face->num_charmaps > 0) cmap = face->charmaps[0]; else cmap = nil; for (i = 0; i < face->num_charmaps; i++) { FT_CharMap test = face->charmaps[i]; if (kind == TYPE1) { if (test->platform_id == 7) cmap = test; } if (kind == TRUETYPE) { if (test->platform_id == 1 && test->encoding_id == 0) cmap = test; if (test->platform_id == 3 && test->encoding_id == 1) cmap = test; } } if (cmap) { fterr = FT_Set_Charmap(face, cmap); if (fterr) fz_warn("freetype could not set cmap: %s", ft_errorstring(fterr)); } else fz_warn("freetype could not find any cmaps"); etable = fz_malloc(sizeof(unsigned short) * 256); for (i = 0; i < 256; i++) { estrings[i] = nil; etable[i] = 0; } encoding = fz_dictgets(dict, "Encoding"); if (encoding) { if (fz_isname(encoding)) pdf_loadencoding(estrings, fz_toname(encoding)); if (fz_isdict(encoding)) { fz_obj *base, *diff, *item; base = fz_dictgets(encoding, "BaseEncoding"); if (fz_isname(base)) pdf_loadencoding(estrings, fz_toname(base)); else if (!fontdesc->isembedded && !symbolic) pdf_loadencoding(estrings, "StandardEncoding"); /* cf. http://bugs.ghostscript.com/show_bug.cgi?id=690615 and http://code.google.com/p/sumatrapdf/issues/detail?id=687 */ /* try to extract an encoding from the font or synthesize a likely one */ /* note: FT_Get_Name_Index fails for symbolic CFF fonts, so let them be encoded by index */ else if (!fontdesc->encoding && !ftloadt1encoding(face, estrings) && !(symbolic && !strcmp(FT_Get_X11_Font_Format(face), "CFF"))) pdf_loadencoding(estrings, "StandardEncoding"); diff = fz_dictgets(encoding, "Differences"); if (fz_isarray(diff)) { n = fz_arraylen(diff); k = 0; for (i = 0; i < n; i++) { item = fz_arrayget(diff, i); if (fz_isint(item)) k = fz_toint(item); if (fz_isname(item)) estrings[k++] = fz_toname(item); if (k < 0) k = 0; if (k > 255) k = 255; } } } } /* start with the builtin encoding */ for (i = 0; i < 256; i++) etable[i] = ftcharindex(face, i); /* encode by glyph name where we can */ if (kind == TYPE1) { pdf_logfont("encode type1/cff by strings\n"); for (i = 0; i < 256; i++) { if (estrings[i]) { etable[i] = FT_Get_Name_Index(face, estrings[i]); if (etable[i] == 0) { int aglcode = pdf_lookupagl(estrings[i]); char **aglnames = pdf_lookupaglnames(aglcode); while (*aglnames) { etable[i] = FT_Get_Name_Index(face, *aglnames); if (etable[i]) break; aglnames++; } } } } } /* encode by glyph name where we can */ if (kind == TRUETYPE) { /* Unicode cmap */ if (!symbolic && face->charmap && face->charmap->platform_id == 3) { pdf_logfont("encode truetype via unicode\n"); for (i = 0; i < 256; i++) { if (estrings[i]) { int aglcode = pdf_lookupagl(estrings[i]); if (!aglcode) etable[i] = FT_Get_Name_Index(face, estrings[i]); else etable[i] = ftcharindex(face, aglcode); } } } /* MacRoman cmap */ else if (!symbolic && face->charmap && face->charmap->platform_id == 1) { pdf_logfont("encode truetype via macroman\n"); for (i = 0; i < 256; i++) { if (estrings[i]) { k = mrecode(estrings[i]); if (k <= 0) etable[i] = FT_Get_Name_Index(face, estrings[i]); else etable[i] = ftcharindex(face, k); } } } /* Symbolic cmap */ else { pdf_logfont("encode truetype symbolic\n"); for (i = 0; i < 256; i++) { if (estrings[i]) { etable[i] = FT_Get_Name_Index(face, estrings[i]); if (etable[i] == 0) etable[i] = ftcharindex(face, i); } } } } /* try to reverse the glyph names from the builtin encoding */ for (i = 0; i < 256; i++) { if (etable[i] && !estrings[i]) { if (FT_HAS_GLYPH_NAMES(face)) { fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32); if (fterr) fz_warn("freetype get glyph name (gid %d): %s", etable[i], ft_errorstring(fterr)); if (ebuffer[i][0]) estrings[i] = ebuffer[i]; } else { estrings[i] = (char*) pdf_winansi[i]; /* discard const */ } } } /* Prevent encoding Differences from being overwritten by reloading them */ /* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=115 */ if (fz_isdict(encoding)) { fz_obj *diff, *item; diff = fz_dictgets(encoding, "Differences"); if (fz_isarray(diff)) { n = fz_arraylen(diff); k = 0; for (i = 0; i < n; i++) { item = fz_arrayget(diff, i); if (fz_isint(item)) k = fz_toint(item); if (fz_isname(item)) estrings[k++] = fz_toname(item); if (k < 0) k = 0; if (k > 255) k = 255; } } } fontdesc->encoding = pdf_newidentitycmap(0, 1); fontdesc->ncidtogid = 256; fontdesc->cidtogid = etable; error = pdf_loadtounicode(fontdesc, xref, estrings, nil, fz_dictgets(dict, "ToUnicode")); if (error) goto cleanup; /* Widths */ pdf_setdefaulthmtx(fontdesc, fontdesc->missingwidth); widths = fz_dictgets(dict, "Widths"); if (widths) { int first, last; first = fz_toint(fz_dictgets(dict, "FirstChar")); last = fz_toint(fz_dictgets(dict, "LastChar")); if (first < 0 || last > 255 || first > last) first = last = 0; for (i = 0; i < last - first + 1; i++) { int wid = fz_toint(fz_arrayget(widths, i)); pdf_addhmtx(fontdesc, i + first, i + first, wid); } } else { fterr = FT_Set_Char_Size(face, 1000, 1000, 72, 72); if (fterr) fz_warn("freetype set character size: %s", ft_errorstring(fterr)); for (i = 0; i < 256; i++) { pdf_addhmtx(fontdesc, i, i, ftwidth(fontdesc, i)); } } pdf_endhmtx(fontdesc); pdf_logfont("}\n"); *fontdescp = fontdesc; return fz_okay; cleanup: if (etable != fontdesc->cidtogid) fz_free(etable); pdf_dropfont(fontdesc); return fz_rethrow(error, "cannot load simple font (%d %d R)", fz_tonum(dict), fz_togen(dict)); }
unsigned int FreeTypeType1Wrapper::GetFreeTypeGlyphIndexFromEncodingGlyphIndex(unsigned int inGlyphIndex) { return FT_Get_Name_Index(mFace,(FT_String*)(GetPrivateGlyphName(inGlyphIndex).c_str())); }
GlyphID XeTeXFontInst::mapGlyphToIndex(const char* glyphName) const { return FT_Get_Name_Index(m_ftFace, const_cast<char*>(glyphName)); }
static fz_error loadsimplefont(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict) { fz_error error; fz_obj *descriptor = nil; fz_obj *encoding = nil; fz_obj *widths = nil; unsigned short *etable = nil; pdf_fontdesc *fontdesc; fz_irect bbox; FT_Face face; FT_CharMap cmap; int kind; int symbolic; char *basefont; char *fontname; char *estrings[256]; char ebuffer[256][32]; int i, k, n; int fterr; basefont = fz_toname(fz_dictgets(dict, "BaseFont")); fontname = cleanfontname(basefont); /* * Load font file */ fontdesc = pdf_newfontdesc(); if (!fontdesc) return fz_rethrow(-1, "out of memory"); pdf_logfont("load simple font (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), fontdesc); pdf_logfont("basefont0 %s\n", basefont); pdf_logfont("basefont1 %s\n", fontname); descriptor = fz_dictgets(dict, "FontDescriptor"); if (descriptor && basefont == fontname) error = pdf_loadfontdescriptor(fontdesc, xref, descriptor, nil); else error = pdf_loadbuiltinfont(fontdesc, fontname); if (error) goto cleanup; face = fontdesc->font->ftface; kind = ftkind(face); pdf_logfont("ft name '%s' '%s'\n", face->family_name, face->style_name); bbox.x0 = (face->bbox.xMin * 1000) / face->units_per_EM; bbox.y0 = (face->bbox.yMin * 1000) / face->units_per_EM; bbox.x1 = (face->bbox.xMax * 1000) / face->units_per_EM; bbox.y1 = (face->bbox.yMax * 1000) / face->units_per_EM; pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1); if (bbox.x0 == bbox.x1) fz_setfontbbox(fontdesc->font, -1000, -1000, 2000, 2000); else fz_setfontbbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1); /* * Encoding */ symbolic = fontdesc->flags & 4; if (face->num_charmaps > 0) cmap = face->charmaps[0]; else cmap = nil; for (i = 0; i < face->num_charmaps; i++) { FT_CharMap test = face->charmaps[i]; if (kind == TYPE1) { if (test->platform_id == 7) cmap = test; } if (kind == TRUETYPE) { if (test->platform_id == 1 && test->encoding_id == 0) cmap = test; if (test->platform_id == 3 && test->encoding_id == 1) cmap = test; } } if (cmap) { fterr = FT_Set_Charmap(face, cmap); if (fterr) fz_warn("freetype could not set cmap: %s", ft_errorstring(fterr)); } else fz_warn("freetype could not find any cmaps"); etable = fz_malloc(sizeof(unsigned short) * 256); if (!etable) goto cleanup; for (i = 0; i < 256; i++) { estrings[i] = nil; etable[i] = 0; } encoding = fz_dictgets(dict, "Encoding"); if (encoding && !(kind == TRUETYPE && symbolic)) { if (fz_isname(encoding)) pdf_loadencoding(estrings, fz_toname(encoding)); if (fz_isdict(encoding)) { fz_obj *base, *diff, *item; base = fz_dictgets(encoding, "BaseEncoding"); if (fz_isname(base)) pdf_loadencoding(estrings, fz_toname(base)); else if (!fontdesc->isembedded) pdf_loadencoding(estrings, "StandardEncoding"); diff = fz_dictgets(encoding, "Differences"); if (fz_isarray(diff)) { n = fz_arraylen(diff); k = 0; for (i = 0; i < n; i++) { item = fz_arrayget(diff, i); if (fz_isint(item)) k = fz_toint(item); if (fz_isname(item)) estrings[k++] = fz_toname(item); if (k < 0) k = 0; if (k > 255) k = 255; } } } if (kind == TYPE1) { pdf_logfont("encode type1/cff by strings\n"); for (i = 0; i < 256; i++) if (estrings[i]) etable[i] = FT_Get_Name_Index(face, estrings[i]); else etable[i] = ftcharindex(face, i); } if (kind == TRUETYPE) { /* Unicode cmap */ if (face->charmap && face->charmap->platform_id == 3) { pdf_logfont("encode truetype via unicode\n"); for (i = 0; i < 256; i++) if (estrings[i]) { int aglbuf[256]; int aglnum; aglnum = pdf_lookupagl(estrings[i], aglbuf, nelem(aglbuf)); if (aglnum != 1) etable[i] = FT_Get_Name_Index(face, estrings[i]); else etable[i] = ftcharindex(face, aglbuf[0]); } else etable[i] = ftcharindex(face, i); } /* MacRoman cmap */ else if (face->charmap && face->charmap->platform_id == 1) { pdf_logfont("encode truetype via macroman\n"); for (i = 0; i < 256; i++) if (estrings[i]) { k = mrecode(estrings[i]); if (k <= 0) etable[i] = FT_Get_Name_Index(face, estrings[i]); else etable[i] = ftcharindex(face, k); } else etable[i] = ftcharindex(face, i); } /* Symbolic cmap */ else { pdf_logfont("encode truetype symbolic\n"); for (i = 0; i < 256; i++) { etable[i] = ftcharindex(face, i); fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32); if (fterr) { error = fz_throw("freetype get glyph name (gid %d): %s", etable[i], ft_errorstring(fterr)); goto cleanup; } if (ebuffer[i][0]) estrings[i] = ebuffer[i]; } } } } else { pdf_logfont("encode builtin\n"); for (i = 0; i < 256; i++) { etable[i] = ftcharindex(face, i); if (etable[i] == 0) continue; if (FT_HAS_GLYPH_NAMES(face)) { fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32); if (fterr) { error = fz_throw("freetype get glyph name (gid %d): %s", etable[i], ft_errorstring(fterr)); goto cleanup; } if (ebuffer[i][0]) estrings[i] = ebuffer[i]; } } } error = pdf_newidentitycmap(&fontdesc->encoding, 0, 1); if (error) goto cleanup; fontdesc->ncidtogid = 256; fontdesc->cidtogid = etable; error = pdf_loadtounicode(fontdesc, xref, estrings, nil, fz_dictgets(dict, "ToUnicode")); if (error) goto cleanup; /* * Widths */ pdf_setdefaulthmtx(fontdesc, fontdesc->missingwidth); widths = fz_dictgets(dict, "Widths"); if (widths) { int first, last; first = fz_toint(fz_dictgets(dict, "FirstChar")); last = fz_toint(fz_dictgets(dict, "LastChar")); if (first < 0 || last > 255 || first > last) first = last = 0; for (i = 0; i < last - first + 1; i++) { int wid = fz_toint(fz_arrayget(widths, i)); error = pdf_addhmtx(fontdesc, i + first, i + first, wid); if (error) goto cleanup; } } else { fterr = FT_Set_Char_Size(face, 1000, 1000, 72, 72); if (fterr) fz_warn("freetype set character size: %s", ft_errorstring(fterr)); for (i = 0; i < 256; i++) { error = pdf_addhmtx(fontdesc, i, i, ftwidth(fontdesc, i)); if (error) goto cleanup; } } error = pdf_endhmtx(fontdesc); if (error) goto cleanup; pdf_logfont("}\n"); *fontdescp = fontdesc; return fz_okay; cleanup: fz_free(etable); fz_dropfont(fontdesc->font); fz_free(fontdesc); return fz_rethrow(error, "cannot load simple font"); }
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; }
double PdfFontMetricsFreetype::GetGlyphWidth( const char* pszGlyphname ) const { return GetGlyphWidth( FT_Get_Name_Index( m_pFace, const_cast<char *>(pszGlyphname) ) ); }
TeXFont_PFB::TeXFont_PFB(TeXFontDefinition *parent, fontEncoding *enc, double slant) : TeXFont(parent) { #ifdef DEBUG_PFB if (enc != 0) kdDebug(4300) << "TeXFont_PFB::TeXFont_PFB( parent=" << parent << ", encoding=" << enc->encodingFullName << " )" << endl; else kdDebug(4300) << "TeXFont_PFB::TeXFont_PFB( parent=" << parent << ", encoding=0 )" << endl; #endif fatalErrorInFontLoading = false; int error = FT_New_Face( parent->font_pool->FreeType_library, parent->filename.local8Bit(), 0, &face ); if ( error == FT_Err_Unknown_File_Format ) { errorMessage = i18n("The font file %1 could be opened and read, but its font format is unsupported.").arg(parent->filename); kdError(4300) << errorMessage << endl; fatalErrorInFontLoading = true; return; } else if ( error ) { errorMessage = i18n("The font file %1 is broken, or it could not be opened or read.").arg(parent->filename); kdError(4300) << errorMessage << endl; fatalErrorInFontLoading = true; return; } // Take care of slanting, and transform all characters in the font, if necessary. if (slant != 0.0) { // Construct a transformation matrix for vertical shear which will // be used to transform the characters. transformationMatrix.xx = 0x10000; transformationMatrix.xy = (FT_Fixed)(slant * 0x10000); transformationMatrix.yx = 0; transformationMatrix.yy = 0x10000; FT_Set_Transform( face, &transformationMatrix, 0); } if (face->family_name != 0) parent->fullFontName = face->family_name; // Finally, we need to set up the charMap array, which maps TeX // character codes to glyph indices in the font. (Remark: the // charMap, and the font encoding procedure is necessary, because // TeX is only able to address character codes 0-255 while // e.g. Type1 fonts may contain several thousands of characters) if (enc != 0) { parent->fullEncodingName = enc->encodingFullName.remove(QString::fromLatin1( "Encoding" )); parent->fullEncodingName = enc->encodingFullName.remove(QString::fromLatin1( "encoding" )); // An encoding vector is given for this font, i.e. an array of // character names (such as: 'parenleft' or 'dotlessj'). We use // the FreeType library function 'FT_Get_Name_Index()' to // associate glyph indices to those names. #ifdef DEBUG_PFB kdDebug(4300) << "Trying to associate glyph indices to names from the encoding vector." << endl; #endif for(int i=0; i<256; i++) { charMap[i] = FT_Get_Name_Index( face, (FT_String *)(enc->glyphNameVector[i].ascii()) ); #ifdef DEBUG_PFB kdDebug(4300) << i << ": " << enc->glyphNameVector[i] << ", GlyphIndex=" << charMap[i] << endl; #endif } } else { // If there is no encoding vector available, we check if the font // itself contains a charmap that could be used. An admissible // charMap will be stored under platform_id=7 and encoding_id=2. FT_CharMap found = 0; for (int n = 0; n<face->num_charmaps; n++ ) { FT_CharMap charmap = face->charmaps[n]; if ( charmap->platform_id == 7 && charmap->encoding_id == 2 ) { found = charmap; break; } } if ((found != 0) && (FT_Set_Charmap( face, found ) == 0)) { // Feed the charMap array with the charmap data found in the // previous step. #ifdef DEBUG_PFB kdDebug(4300) << "No encoding given: using charmap platform=7, encoding=2 that is contained in the font." << endl; #endif for(int i=0; i<256; i++) charMap[i] = FT_Get_Char_Index( face, i ); } else { if ((found == 0) && (face->charmap != 0)) { #ifdef DEBUG_PFB kdDebug(4300) << "No encoding given: using charmap platform=" << face->charmap->platform_id << ", encoding=" << face->charmap->encoding_id << " that is contained in the font." << endl; #endif for(int i=0; i<256; i++) charMap[i] = FT_Get_Char_Index( face, i ); } else { // As a last resort, we use the identity map. #ifdef DEBUG_PFB kdDebug(4300) << "No encoding given, no suitable charmaps found in the font: using identity charmap." << endl; #endif for(int i=0; i<256; i++) charMap[i] = i; } } } }