void* ScFace::ScFaceData::hbFont() { if (!m_hbFont) { if (!ftFace()) return NULL; if (formatCode == ScFace::SFNT || formatCode == ScFace::TTCF || formatCode == ScFace::TYPE42) { // use HarfBuzz internal font functions for formats it supports, // gives us more consistent glyph metrics. FT_Reference_Face(ftFace()); hb_face_t *hbFace = hb_face_create_for_tables(referenceTable, ftFace(), (hb_destroy_func_t) FT_Done_Face); hb_face_set_index(hbFace, ftFace()->face_index); hb_face_set_upem(hbFace, ftFace()->units_per_EM); m_hbFont = hb_font_create(hbFace); hb_ot_font_set_funcs(reinterpret_cast<hb_font_t*>(m_hbFont)); hb_face_destroy(hbFace); } else { m_hbFont = hb_ft_font_create_referenced(ftFace()); } } return m_hbFont; }
SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) { fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault(); int index; std::unique_ptr<SkStreamAsset> asset(fImpl->fTypeface->openStream(&index)); size_t size = asset->getLength(); SkAutoMalloc autoMalloc(size); // TODO(halcanary): Avoid this malloc+copy. asset->read(autoMalloc.get(), size); asset = nullptr; void* ptr = autoMalloc.get(); hb_blob_t* blob = hb_blob_create((char*)autoMalloc.release(), size, HB_MEMORY_MODE_READONLY, ptr, sk_free); SkASSERT(blob); hb_blob_make_immutable(blob); struct HBFaceDel { void operator()(hb_face_t* f) { hb_face_destroy(f); } }; std::unique_ptr<hb_face_t, HBFaceDel> face(hb_face_create(blob, (unsigned)index)); hb_blob_destroy(blob); SkASSERT(face); if (!face) { return; } hb_face_set_index(face.get(), (unsigned)index); hb_face_set_upem(face.get(), fImpl->fTypeface->getUnitsPerEm()); fImpl->fHarfBuzzFont.reset(hb_font_create(face.get())); SkASSERT(fImpl->fHarfBuzzFont); hb_font_set_scale(fImpl->fHarfBuzzFont.get(), FONT_SIZE_SCALE, FONT_SIZE_SCALE); hb_ot_font_set_funcs(fImpl->fHarfBuzzFont.get()); fImpl->fBuffer.reset(hb_buffer_create()); }
void XeTeXFontInst::initialize(const char* pathname, int index, int &status) { TT_Postscript *postTable; TT_OS2* os2Table; FT_Error error; hb_face_t *hbFace; if (!gFreeTypeLibrary) { error = FT_Init_FreeType(&gFreeTypeLibrary); if (error) { fprintf(stderr, "FreeType initialization failed! (%d)\n", error); exit(1); } } error = FT_New_Face(gFreeTypeLibrary, pathname, index, &m_ftFace); if (error) { status = 1; return; } if (!FT_IS_SCALABLE(m_ftFace)) { status = 1; return; } /* for non-sfnt-packaged fonts (presumably Type 1), see if there is an AFM file we can attach */ if (index == 0 && !FT_IS_SFNT(m_ftFace)) { char* afm = xstrdup (xbasename (pathname)); char* p = strrchr (afm, '.'); if (p != NULL && strlen(p) == 4 && tolower(*(p+1)) == 'p' && tolower(*(p+2)) == 'f') strcpy(p, ".afm"); char *fullafm = kpse_find_file (afm, kpse_afm_format, 0); free (afm); if (fullafm) { FT_Attach_File(m_ftFace, fullafm); free (fullafm); } } m_filename = xstrdup(pathname); m_index = index; m_unitsPerEM = m_ftFace->units_per_EM; m_ascent = unitsToPoints(m_ftFace->ascender); m_descent = unitsToPoints(m_ftFace->descender); postTable = (TT_Postscript *) getFontTable(ft_sfnt_post); if (postTable != NULL) { m_italicAngle = Fix2D(postTable->italicAngle); } os2Table = (TT_OS2*) getFontTable(ft_sfnt_os2); if (os2Table) { m_capHeight = unitsToPoints(os2Table->sCapHeight); m_xHeight = unitsToPoints(os2Table->sxHeight); } // Set up HarfBuzz font hbFace = hb_face_create_for_tables(_get_table, m_ftFace, NULL); hb_face_set_index(hbFace, index); hb_face_set_upem(hbFace, m_unitsPerEM); m_hbFont = hb_font_create(hbFace); hb_face_destroy(hbFace); if (hbFontFuncs == NULL) hbFontFuncs = _get_font_funcs(); hb_font_set_funcs(m_hbFont, hbFontFuncs, m_ftFace, NULL); hb_font_set_scale(m_hbFont, m_unitsPerEM, m_unitsPerEM); // We don’t want device tables adjustments hb_font_set_ppem(m_hbFont, 0, 0); return; }