< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.cc

Print this page

        

*** 34,45 **** #include "hb-ot-cbdt-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-os2-table.hh" ! //#include "hb-ot-post-table.hh" struct hb_ot_face_metrics_accelerator_t { unsigned int num_metrics; --- 34,47 ---- #include "hb-ot-cbdt-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" + #include "hb-ot-kern-table.hh" #include "hb-ot-os2-table.hh" ! #include "hb-ot-post-table.hh" ! #include "hb-ot-var-hvar-table.hh" struct hb_ot_face_metrics_accelerator_t { unsigned int num_metrics;
*** 48,63 **** unsigned short ascender; unsigned short descender; unsigned short line_gap; bool has_font_extents; ! const OT::_mtx *table; hb_blob_t *blob; inline void init (hb_face_t *face, hb_tag_t _hea_tag, hb_tag_t _mtx_tag, hb_tag_t os2_tag, unsigned int default_advance = 0) { this->default_advance = default_advance ? default_advance : face->get_upem (); --- 50,69 ---- unsigned short ascender; unsigned short descender; unsigned short line_gap; bool has_font_extents; ! const OT::hmtxvmtx *table; hb_blob_t *blob; + const OT::HVARVVAR *var; + hb_blob_t *var_blob; + inline void init (hb_face_t *face, hb_tag_t _hea_tag, hb_tag_t _mtx_tag, + hb_tag_t _var_tag, hb_tag_t os2_tag, unsigned int default_advance = 0) { this->default_advance = default_advance ? default_advance : face->get_upem ();
*** 89,99 **** } hb_blob_destroy (_hea_blob); this->has_font_extents = got_font_extents; ! this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag)); /* Cap num_metrics() and num_advances() based on table length. */ unsigned int len = hb_blob_get_length (this->blob); if (unlikely (this->num_advances * 4 > len)) this->num_advances = len / 4; --- 95,105 ---- } hb_blob_destroy (_hea_blob); this->has_font_extents = got_font_extents; ! this->blob = OT::Sanitizer<OT::hmtxvmtx>::sanitize (face->reference_table (_mtx_tag)); /* Cap num_metrics() and num_advances() based on table length. */ unsigned int len = hb_blob_get_length (this->blob); if (unlikely (this->num_advances * 4 > len)) this->num_advances = len / 4;
*** 105,123 **** { this->num_metrics = this->num_advances = 0; hb_blob_destroy (this->blob); this->blob = hb_blob_get_empty (); } ! this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob); } inline void fini (void) { hb_blob_destroy (this->blob); } ! inline unsigned int get_advance (hb_codepoint_t glyph) const { if (unlikely (glyph >= this->num_metrics)) { /* If this->num_metrics is zero, it means we don't have the metrics table * for this direction: return default advance. Otherwise, it means that the --- 111,134 ---- { this->num_metrics = this->num_advances = 0; hb_blob_destroy (this->blob); this->blob = hb_blob_get_empty (); } ! this->table = OT::Sanitizer<OT::hmtxvmtx>::lock_instance (this->blob); ! ! this->var_blob = OT::Sanitizer<OT::HVARVVAR>::sanitize (face->reference_table (_var_tag)); ! this->var = OT::Sanitizer<OT::HVARVVAR>::lock_instance (this->var_blob); } inline void fini (void) { hb_blob_destroy (this->blob); + hb_blob_destroy (this->var_blob); } ! inline unsigned int get_advance (hb_codepoint_t glyph, ! hb_font_t *font) const { if (unlikely (glyph >= this->num_metrics)) { /* If this->num_metrics is zero, it means we don't have the metrics table * for this direction: return default advance. Otherwise, it means that the
*** 126,139 **** return 0; else return this->default_advance; } ! if (glyph >= this->num_advances) ! glyph = this->num_advances - 1; ! ! return this->table->longMetric[glyph].advance; } }; struct hb_ot_face_glyf_accelerator_t { --- 137,148 ---- return 0; else return this->default_advance; } ! return this->table->longMetric[MIN (glyph, (uint32_t) this->num_advances - 1)].advance ! + this->var->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?! } }; struct hb_ot_face_glyf_accelerator_t {
*** 214,236 **** hb_blob_t *cbdt_blob; const OT::CBLC *cblc; const OT::CBDT *cbdt; unsigned int cbdt_len; ! float upem; inline void init (hb_face_t *face) { upem = face->get_upem(); cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); cbdt_len = hb_blob_get_length (cbdt_blob); if (hb_blob_get_length (cblc_blob) == 0) { ! cblc = NULL; ! cbdt = NULL; return; /* Not a bitmap font. */ } cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob); cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob); --- 223,245 ---- hb_blob_t *cbdt_blob; const OT::CBLC *cblc; const OT::CBDT *cbdt; unsigned int cbdt_len; ! unsigned int upem; inline void init (hb_face_t *face) { upem = face->get_upem(); cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); cbdt_len = hb_blob_get_length (cbdt_blob); if (hb_blob_get_length (cblc_blob) == 0) { ! cblc = nullptr; ! cbdt = nullptr; return; /* Not a bitmap font. */ } cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob); cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob);
*** 244,258 **** inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */ ! if (cblc == NULL) return false; // Not a color bitmap font. const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); ! if (subtable_record == NULL) return false; if (subtable_record->get_extents (extents)) return true; --- 253,267 ---- inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */ ! if (!cblc) return false; // Not a color bitmap font. const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); ! if (!subtable_record || !x_ppem || !y_ppem) return false; if (subtable_record->get_extents (extents)) return true;
*** 291,300 **** --- 300,363 ---- return true; } }; + struct hb_ot_face_post_accelerator_t + { + hb_blob_t *post_blob; + OT::post::accelerator_t accel; + + inline void init (hb_face_t *face) + { + hb_blob_t *blob = this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post)); + accel.init (OT::Sanitizer<OT::post>::lock_instance (blob), hb_blob_get_length (blob)); + } + + inline void fini (void) + { + accel.fini (); + hb_blob_destroy (this->post_blob); + } + + inline bool get_glyph_name (hb_codepoint_t glyph, + char *name, unsigned int size) const + { + return this->accel.get_glyph_name (glyph, name, size); + } + + inline bool get_glyph_from_name (const char *name, int len, + hb_codepoint_t *glyph) const + { + if (unlikely (!len)) + return false; + + return this->accel.get_glyph_from_name (name, len, glyph); + } + }; + + struct hb_ot_face_kern_accelerator_t + { + hb_blob_t *kern_blob; + OT::kern::accelerator_t accel; + + inline void init (hb_face_t *face) + { + hb_blob_t *blob = this->kern_blob = OT::Sanitizer<OT::kern>::sanitize (face->reference_table (HB_OT_TAG_kern)); + accel.init (OT::Sanitizer<OT::kern>::lock_instance (blob), hb_blob_get_length (blob)); + } + + inline void fini (void) + { + accel.fini (); + hb_blob_destroy (this->kern_blob); + } + + inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { return accel.get_h_kerning (left, right); } + }; + typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); template <typename Type>
*** 339,350 **** inline void init (hb_face_t *face) { this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap)); const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); ! const OT::CmapSubtable *subtable = NULL; ! const OT::CmapSubtableFormat14 *subtable_uvs = NULL; bool symbol = false; /* 32-bit subtables. */ if (!subtable) subtable = cmap->find_subtable (3, 10); if (!subtable) subtable = cmap->find_subtable (0, 6); --- 402,413 ---- inline void init (hb_face_t *face) { this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap)); const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); ! const OT::CmapSubtable *subtable = nullptr; ! const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; bool symbol = false; /* 32-bit subtables. */ if (!subtable) subtable = cmap->find_subtable (3, 10); if (!subtable) subtable = cmap->find_subtable (0, 6);
*** 419,506 **** return get_nominal_glyph (unicode, glyph); } }; - template <typename T> - struct hb_lazy_loader_t - { - inline void init (hb_face_t *face_) - { - face = face_; - instance = NULL; - } - - inline void fini (void) - { - if (instance && instance != &OT::Null(T)) - { - instance->fini(); - free (instance); - } - } - - inline const T* operator-> (void) const - { - retry: - T *p = (T *) hb_atomic_ptr_get (&instance); - if (unlikely (!p)) - { - p = (T *) calloc (1, sizeof (T)); - if (unlikely (!p)) - return &OT::Null(T); - p->init (face); - if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p))) - { - p->fini (); - goto retry; - } - } - return p; - } - - private: - hb_face_t *face; - T *instance; - }; - struct hb_ot_font_t { hb_ot_face_cmap_accelerator_t cmap; hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; ! hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; ! hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; }; static hb_ot_font_t * _hb_ot_font_create (hb_face_t *face) { hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); if (unlikely (!ot_font)) ! return NULL; ot_font->cmap.init (face); ! ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2); ! ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ ot_font->glyf.init (face); ot_font->cbdt.init (face); return ot_font; } static void ! _hb_ot_font_destroy (hb_ot_font_t *ot_font) { ot_font->cmap.fini (); ot_font->h_metrics.fini (); ot_font->v_metrics.fini (); ot_font->glyf.fini (); ot_font->cbdt.fini (); free (ot_font); } --- 482,535 ---- return get_nominal_glyph (unicode, glyph); } }; struct hb_ot_font_t { hb_ot_face_cmap_accelerator_t cmap; hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; ! OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; ! OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; ! OT::hb_lazy_loader_t<hb_ot_face_post_accelerator_t> post; ! OT::hb_lazy_loader_t<hb_ot_face_kern_accelerator_t> kern; }; static hb_ot_font_t * _hb_ot_font_create (hb_face_t *face) { hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); if (unlikely (!ot_font)) ! return nullptr; ot_font->cmap.init (face); ! ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_HVAR, HB_OT_TAG_os2); ! ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_OT_TAG_VVAR, HB_TAG_NONE, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ ot_font->glyf.init (face); ot_font->cbdt.init (face); + ot_font->post.init (face); + ot_font->kern.init (face); return ot_font; } static void ! _hb_ot_font_destroy (void *data) { + hb_ot_font_t *ot_font = (hb_ot_font_t *) data; + ot_font->cmap.fini (); ot_font->h_metrics.fini (); ot_font->v_metrics.fini (); ot_font->glyf.fini (); ot_font->cbdt.fini (); + ot_font->post.fini (); + ot_font->kern.fini (); free (ot_font); }
*** 527,553 **** const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; return ot_font->cmap.get_variation_glyph (unicode, variation_selector, glyph); } static hb_position_t ! hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED, void *font_data, hb_codepoint_t glyph, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; ! return font->em_scale_x (ot_font->h_metrics.get_advance (glyph)); } static hb_position_t ! hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, void *font_data, hb_codepoint_t glyph, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; ! return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); } static hb_bool_t hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, void *font_data, --- 556,593 ---- const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; return ot_font->cmap.get_variation_glyph (unicode, variation_selector, glyph); } static hb_position_t ! hb_ot_get_glyph_h_advance (hb_font_t *font, void *font_data, hb_codepoint_t glyph, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; ! return font->em_scale_x (ot_font->h_metrics.get_advance (glyph, font)); } static hb_position_t ! hb_ot_get_glyph_v_advance (hb_font_t *font, void *font_data, hb_codepoint_t glyph, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; ! return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph, font)); ! } ! ! static hb_position_t ! hb_ot_get_glyph_h_kerning (hb_font_t *font, ! void *font_data, ! hb_codepoint_t left_glyph, ! hb_codepoint_t right_glyph, ! void *user_data HB_UNUSED) ! { ! const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; ! return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph)); } static hb_bool_t hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, void *font_data,
*** 557,583 **** --- 597,647 ---- { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; bool ret = ot_font->glyf->get_extents (glyph, extents); if (!ret) ret = ot_font->cbdt->get_extents (glyph, extents); + // TODO Hook up side-bearings variations. extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); extents->width = font->em_scale_x (extents->width); extents->height = font->em_scale_y (extents->height); return ret; } static hb_bool_t + hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, + void *font_data, + hb_codepoint_t glyph, + char *name, unsigned int size, + void *user_data HB_UNUSED) + { + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + return ot_font->post->get_glyph_name (glyph, name, size); + } + + static hb_bool_t + hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, + void *font_data, + const char *name, int len, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) + { + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + return ot_font->post->get_glyph_from_name (name, len, glyph); + } + + static hb_bool_t hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, void *font_data, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender); metrics->descender = font->em_scale_y (ot_font->h_metrics.descender); metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap); + // TODO Hook up variations. return ot_font->h_metrics.has_font_extents; } static hb_bool_t hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED,
*** 587,600 **** { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender); metrics->descender = font->em_scale_x (ot_font->v_metrics.descender); metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap); return ot_font->v_metrics.has_font_extents; } ! static hb_font_funcs_t *static_ot_funcs = NULL; #ifdef HB_USE_ATEXIT static void free_static_ot_funcs (void) { --- 651,665 ---- { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender); metrics->descender = font->em_scale_x (ot_font->v_metrics.descender); metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap); + // TODO Hook up variations. return ot_font->v_metrics.has_font_extents; } ! static hb_font_funcs_t *static_ot_funcs = nullptr; #ifdef HB_USE_ATEXIT static void free_static_ot_funcs (void) {
*** 610,637 **** if (unlikely (!funcs)) { funcs = hb_font_funcs_create (); ! hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, NULL, NULL); ! hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, NULL, NULL); ! hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, NULL, NULL); ! hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, NULL, NULL); ! hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NULL, NULL); ! hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NULL, NULL); ! //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, NULL, NULL); ! //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, NULL, NULL); ! //hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, NULL, NULL); TODO ! //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, NULL, NULL); ! hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, NULL, NULL); ! //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, NULL, NULL); TODO ! //hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, NULL, NULL); TODO ! //hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, NULL, NULL); TODO hb_font_funcs_make_immutable (funcs); ! if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) { hb_font_funcs_destroy (funcs); goto retry; } #ifdef HB_USE_ATEXIT --- 675,702 ---- if (unlikely (!funcs)) { funcs = hb_font_funcs_create (); ! hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); ! hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); ! hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr); ! hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr); ! hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, nullptr, nullptr); ! hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr); ! //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); ! //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); ! hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr); ! //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr); ! hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); ! //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); TODO ! hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); ! hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr); hb_font_funcs_make_immutable (funcs); ! if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, nullptr, funcs)) { hb_font_funcs_destroy (funcs); goto retry; } #ifdef HB_USE_ATEXIT
*** 656,662 **** return; hb_font_set_funcs (font, _hb_ot_get_font_funcs (), ot_font, ! (hb_destroy_func_t) _hb_ot_font_destroy); } --- 721,727 ---- return; hb_font_set_funcs (font, _hb_ot_get_font_funcs (), ot_font, ! _hb_ot_font_destroy); }
< prev index next >