LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) : fHbFont(NULL), fHbBuffer(NULL), fTypoFlags(typoFlags) { if (LE_FAILURE(success)) { return; } fHbBuffer = hb_buffer_create (); if (fHbBuffer == hb_buffer_get_empty ()) { success = LE_MEMORY_ALLOCATION_ERROR; return; } hb_buffer_set_unicode_funcs (fHbBuffer, hb_icu_get_unicode_funcs ()); hb_buffer_set_script (fHbBuffer, hb_icu_script_to_script ((UScriptCode) scriptCode)); /* TODO set language */ hb_face_t *face = hb_face_create_for_tables (icu_le_hb_reference_table, (void *) fontInstance, NULL); fHbFont = hb_font_create (face); hb_face_destroy (face); if (fHbFont == hb_font_get_empty ()) { success = LE_MEMORY_ALLOCATION_ERROR; return; } hb_font_set_funcs (fHbFont, icu_le_hb_get_font_funcs (), (void *) fontInstance, NULL); hb_font_set_scale (fHbFont, +from_float (fontInstance->getXPixelsPerEm () * fontInstance->getScaleFactorX ()), -from_float (fontInstance->getYPixelsPerEm () * fontInstance->getScaleFactorY ())); hb_font_set_ppem (fHbFont, fontInstance->getXPixelsPerEm (), fontInstance->getYPixelsPerEm ()); }
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; }
static void * create_font (void) { hb_face_t *face = (hb_face_t *) create_face (); hb_font_t *font = hb_font_create (face); hb_face_destroy (face); return font; }
static void test_subset_cff1_seac (void) { hb_face_t *face = hb_test_open_font_file ("fonts/cff1_seac.otf"); hb_face_t *face_subset = hb_test_open_font_file ("fonts/cff1_seac.C0.otf"); hb_face_t *face_test; hb_set_t *codepoints = hb_set_create (); hb_set_add (codepoints, 0xC0); /* Agrave */ face_test = hb_subset_test_create_subset (face, hb_subset_test_create_input (codepoints)); hb_set_destroy (codepoints); hb_subset_test_check (face_subset, face_test, HB_TAG ('C','F','F',' ')); hb_face_destroy (face_test); hb_face_destroy (face_subset); hb_face_destroy (face); }
static void test_subset_cff1_noop (void) { hb_face_t *face_abc = hb_test_open_font_file("fonts/SourceSansPro-Regular.abc.otf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; hb_set_add (codepoints, 'a'); hb_set_add (codepoints, 'b'); hb_set_add (codepoints, 'c'); face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints)); hb_set_destroy (codepoints); hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('C','F','F',' ')); hb_face_destroy (face_abc_subset); hb_face_destroy (face_abc); }
static void test_subset_hdmx_multiple_device_records (void) { hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.multihdmx.abc.ttf"); hb_face_t *face_a = hb_test_open_font_file ("fonts/Roboto-Regular.multihdmx.a.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; hb_set_add (codepoints, 'a'); face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints)); hb_set_destroy (codepoints); hb_subset_test_check (face_a, face_abc_subset, HB_TAG ('h','d','m','x')); hb_face_destroy (face_abc_subset); hb_face_destroy (face_abc); hb_face_destroy (face_a); }
static void pango_ot_info_finalize (GObject *object) { PangoOTInfo *info = PANGO_OT_INFO (object); if (info->hb_face) hb_face_destroy (info->hb_face); G_OBJECT_CLASS (pango_ot_info_parent_class)->finalize (object); }
static void test_subset_hdmx_simple_subset (void) { hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); hb_face_t *face_ac = hb_test_open_font_file ("fonts/Roboto-Regular.ac.ttf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_abc_subset; hb_set_add (codepoints, 'a'); hb_set_add (codepoints, 'c'); face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints)); hb_set_destroy (codepoints); hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('h','d','m','x')); hb_face_destroy (face_abc_subset); hb_face_destroy (face_abc); hb_face_destroy (face_ac); }
static void test_post_drops_glyph_names (void) { hb_face_t *face_full = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E,6975,73E0,5EA6,8F38,6E05.ttf"); hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Mplus1p-Regular.660E.ttf"); hb_face_t *face_full_subset; hb_set_t *codepoints = hb_set_create (); hb_set_add (codepoints, 0x660E); face_full_subset = hb_subset_test_create_subset (face_full, hb_subset_test_create_input (codepoints)); hb_set_destroy (codepoints); hb_subset_test_check (face_subset, face_full_subset, HB_TAG ('p','o','s','t')); hb_face_destroy (face_full_subset); hb_face_destroy (face_full); hb_face_destroy (face_subset); }
static void test_subset_cff1_j (void) { hb_face_t *face_41_3041_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,3041,4C2E.otf"); hb_face_t *face_41_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,4C2E.otf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_41_3041_4c2e_subset; hb_set_add (codepoints, 0x41); hb_set_add (codepoints, 0x4C2E); face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, hb_subset_test_create_input (codepoints)); hb_set_destroy (codepoints); hb_subset_test_check (face_41_4c2e, face_41_3041_4c2e_subset, HB_TAG ('C','F','F',' ')); hb_face_destroy (face_41_3041_4c2e_subset); hb_face_destroy (face_41_3041_4c2e); hb_face_destroy (face_41_4c2e); }
static void test_subset_cff1_expert (void) { hb_face_t *face = hb_test_open_font_file ("fonts/cff1_expert.otf"); hb_face_t *face_subset = hb_test_open_font_file ("fonts/cff1_expert.2D,F6E9,FB00.otf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_test; hb_set_add (codepoints, 0x2D); hb_set_add (codepoints, 0xF6E9); hb_set_add (codepoints, 0xFB00); face_test = hb_subset_test_create_subset (face, hb_subset_test_create_input (codepoints)); hb_set_destroy (codepoints); hb_subset_test_check (face_subset, face_test, HB_TAG ('C','F','F',' ')); hb_face_destroy (face_test); hb_face_destroy (face_subset); hb_face_destroy (face); }
static void test_subset_hdmx_invalid (void) { hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a"); hb_subset_input_t *input = hb_subset_input_create_or_fail (); hb_set_t *codepoints = hb_subset_input_unicode_set (input); hb_face_t *subset; hb_set_add (codepoints, 'a'); hb_set_add (codepoints, 'b'); hb_set_add (codepoints, 'c'); subset = hb_subset (face, input); g_assert (subset); g_assert (subset == hb_face_get_empty ()); hb_subset_input_destroy (input); hb_face_destroy (subset); hb_face_destroy (face); }
static void test_subset_cff1_dotsection (void) { hb_face_t *face = hb_test_open_font_file ("fonts/cff1_dotsect.otf"); hb_face_t *face_subset = hb_test_open_font_file ("fonts/cff1_dotsect.nohints.otf"); hb_set_t *codepoints = hb_set_create (); hb_subset_input_t *input; hb_face_t *face_test; hb_set_add (codepoints, 0x69); /* i */ input = hb_subset_test_create_input (codepoints); hb_subset_input_set_drop_hints (input, true); face_test = hb_subset_test_create_subset (face, input); hb_set_destroy (codepoints); hb_subset_test_check (face_subset, face_test, HB_TAG ('C','F','F',' ')); hb_face_destroy (face_test); hb_face_destroy (face_subset); hb_face_destroy (face); }
static void test_subset_hdmx_fails_sanitize (void) { hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016"); hb_subset_input_t *input = hb_subset_input_create_or_fail (); hb_set_t *codepoints = hb_subset_input_unicode_set (input); hb_face_t *subset; hb_set_add (codepoints, 'a'); hb_set_add (codepoints, 'b'); hb_set_add (codepoints, 'c'); subset = hb_subset (face, input); g_assert (subset); g_assert (subset == hb_face_get_empty ()); hb_subset_input_destroy (input); hb_face_destroy (subset); hb_face_destroy (face); }
static void test_subset_cff1_desubr (void) { hb_face_t *face_abc = hb_test_open_font_file ("fonts/SourceSansPro-Regular.abc.otf"); hb_face_t *face_ac = hb_test_open_font_file ("fonts/SourceSansPro-Regular.ac.nosubrs.otf"); hb_set_t *codepoints = hb_set_create (); hb_subset_input_t *input; hb_face_t *face_abc_subset; hb_set_add (codepoints, 'a'); hb_set_add (codepoints, 'c'); input = hb_subset_test_create_input (codepoints); hb_subset_input_set_desubroutinize (input, true); face_abc_subset = hb_subset_test_create_subset (face_abc, input); hb_set_destroy (codepoints); hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('C','F','F',' ')); hb_face_destroy (face_abc_subset); hb_face_destroy (face_abc); hb_face_destroy (face_ac); }
static void test_subset_cff1_j_desubr_strip_hints (void) { hb_face_t *face_41_3041_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,3041,4C2E.otf"); hb_face_t *face_41_4c2e = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,4C2E.nosubrs.nohints.otf"); hb_set_t *codepoints = hb_set_create (); hb_face_t *face_41_3041_4c2e_subset; hb_subset_input_t *input; hb_set_add (codepoints, 0x41); hb_set_add (codepoints, 0x4C2E); input = hb_subset_test_create_input (codepoints); hb_subset_input_set_drop_hints (input, true); hb_subset_input_set_desubroutinize (input, true); face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, input); hb_set_destroy (codepoints); hb_subset_test_check (face_41_4c2e, face_41_3041_4c2e_subset, HB_TAG ('C','F','F',' ')); hb_face_destroy (face_41_3041_4c2e_subset); hb_face_destroy (face_41_3041_4c2e); hb_face_destroy (face_41_4c2e); }
static void text_des(void *obj) { ilG_gui_textlayout *self = obj; il_unref(self->font); free(self->lang); free(self->script); il_string_unref(self->source); hb_buffer_destroy(self->buf); hb_face_destroy(self->hb_ft_face); hb_font_destroy(self->hb_ft_font); cairo_destroy(self->cr); cairo_surface_destroy(self->surface); cairo_font_face_destroy(self->cairo_ft_face); FT_Done_Face(self->ft_face); }
void hb_font_destroy(hb_font_t *font) { if (!font) return; if (hb_atomic_int32_get(&font->ref_cnt) == REF_CNT_INVALID_VAL) return; hb_atomic_int32_add(&font->ref_cnt, -1); if (hb_atomic_int32_get(&font->ref_cnt) > 0) return; hb_atomic_int32_set(&font->ref_cnt, REF_CNT_INVALID_VAL); #ifdef HAVE_GRAPHITE2 if (font->shaper_data.graphite2 && font->shaper_data.graphite2 != HB_SHAPER_DATA_INVALID && font->shaper_data.graphite2 != HB_SHAPER_DATA_SUCCEEDED) hb_graphite2_shaper_font_data_destroy(font->shaper_data.graphite2); #endif #ifdef HAVE_OT if (font->shaper_data.ot && font->shaper_data.ot != HB_SHAPER_DATA_INVALID && font->shaper_data.ot != HB_SHAPER_DATA_SUCCEEDED) hb_ot_shaper_font_data_destroy(font->shaper_data.ot); #endif if (font->shaper_data.fallback && font->shaper_data.fallback != HB_SHAPER_DATA_INVALID && font->shaper_data.fallback != HB_SHAPER_DATA_SUCCEEDED) hb_fallback_shaper_font_data_destroy(font->shaper_data.fallback); if (font->destroy) font->destroy(font->user_data); hb_font_destroy(font->parent); hb_face_destroy(font->face); hb_font_funcs_destroy(font->klass); free(font); }
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; }
void sui_font_free(sui_font *font) { hb_font_destroy(font->hb_font); hb_face_destroy(font->hb_face); FT_Done_Face(font->face); }
void operator()(hb_face_t* f) { hb_face_destroy(f); }