Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: third_party/harfbuzz-ng/src/hb-ot-layout.cc

Issue 10915172: harfbuzz-ng roll (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/harfbuzz-ng/src/hb-ot-layout.cc
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout.cc b/third_party/harfbuzz-ng/src/hb-ot-layout.cc
index 0621f86d3b0c5029e3418acb2698dcc30ab78252..e241e332697895aa2358ef12a292276f830b1395 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout.cc
@@ -2,6 +2,7 @@
* Copyright © 1998-2004 David Turner and Werner Lemberg
* Copyright © 2006 Behdad Esfahbod
* Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -24,6 +25,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
*/
#include "hb-ot-layout-private.hh"
@@ -33,26 +35,45 @@
#include "hb-ot-layout-gpos-table.hh"
#include "hb-ot-maxp-table.hh"
-
#include <stdlib.h>
#include <string.h>
+HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
hb_ot_layout_t *
_hb_ot_layout_create (hb_face_t *face)
{
- /* TODO Remove this object altogether */
hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
+ if (unlikely (!layout))
+ return NULL;
+
+ layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF));
+ layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob);
+
+ layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB));
+ layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob);
+
+ layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS));
+ layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
- layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GDEF));
- layout->gdef = Sanitizer<GDEF>::lock_instance (layout->gdef_blob);
+ layout->gsub_lookup_count = layout->gsub->get_lookup_count ();
+ layout->gpos_lookup_count = layout->gpos->get_lookup_count ();
- layout->gsub_blob = Sanitizer<GSUB>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GSUB));
- layout->gsub = Sanitizer<GSUB>::lock_instance (layout->gsub_blob);
+ layout->gsub_digests = (hb_set_digest_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_set_digest_t));
+ layout->gpos_digests = (hb_set_digest_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_set_digest_t));
- layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GPOS));
- layout->gpos = Sanitizer<GPOS>::lock_instance (layout->gpos_blob);
+ if (unlikely ((layout->gsub_lookup_count && !layout->gsub_digests) ||
+ (layout->gpos_lookup_count && !layout->gpos_digests)))
+ {
+ _hb_ot_layout_destroy (layout);
+ return NULL;
+ }
+
+ for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
+ layout->gsub->add_coverage (&layout->gsub_digests[i], i);
+ for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
+ layout->gpos->add_coverage (&layout->gpos_digests[i], i);
return layout;
}
@@ -64,23 +85,29 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
hb_blob_destroy (layout->gsub_blob);
hb_blob_destroy (layout->gpos_blob);
+ free (layout->gsub_digests);
+ free (layout->gpos_digests);
+
free (layout);
}
-static inline const GDEF&
+static inline const OT::GDEF&
_get_gdef (hb_face_t *face)
{
- return likely (face->ot_layout && face->ot_layout->gdef) ? *face->ot_layout->gdef : Null(GDEF);
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF);
+ return *hb_ot_layout_from_face (face)->gdef;
}
-static inline const GSUB&
+static inline const OT::GSUB&
_get_gsub (hb_face_t *face)
{
- return likely (face->ot_layout && face->ot_layout->gsub) ? *face->ot_layout->gsub : Null(GSUB);
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB);
+ return *hb_ot_layout_from_face (face)->gsub;
}
-static inline const GPOS&
+static inline const OT::GPOS&
_get_gpos (hb_face_t *face)
{
- return likely (face->ot_layout && face->ot_layout->gpos) ? *face->ot_layout->gpos : Null(GPOS);
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS);
+ return *hb_ot_layout_from_face (face)->gpos;
}
@@ -94,84 +121,6 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
return _get_gdef (face).has_glyph_classes ();
}
-unsigned int
-_hb_ot_layout_get_glyph_property (hb_face_t *face,
- hb_glyph_info_t *info)
-{
- if (!info->props_cache())
- {
- const GDEF &gdef = _get_gdef (face);
- info->props_cache() = gdef.get_glyph_props (info->codepoint);
- }
-
- return info->props_cache();
-}
-
-static hb_bool_t
-_hb_ot_layout_match_properties (hb_face_t *face,
- hb_codepoint_t codepoint,
- unsigned int glyph_props,
- unsigned int lookup_props)
-{
- /* Not covered, if, for example, glyph class is ligature and
- * lookup_props includes LookupFlags::IgnoreLigatures
- */
- if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
- return false;
-
- if (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
- {
- /* If using mark filtering sets, the high short of
- * lookup_props has the set index.
- */
- if (lookup_props & LookupFlag::UseMarkFilteringSet)
- return _get_gdef (face).mark_set_covers (lookup_props >> 16, codepoint);
-
- /* The second byte of lookup_props has the meaning
- * "ignore marks of attachment type different than
- * the attachment type specified."
- */
- if (lookup_props & LookupFlag::MarkAttachmentType && glyph_props & LookupFlag::MarkAttachmentType)
- return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
- }
-
- return true;
-}
-
-hb_bool_t
-_hb_ot_layout_check_glyph_property (hb_face_t *face,
- hb_glyph_info_t *ginfo,
- unsigned int lookup_props,
- unsigned int *property_out)
-{
- unsigned int property;
-
- property = _hb_ot_layout_get_glyph_property (face, ginfo);
- (void) (property_out && (*property_out = property));
-
- return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
-}
-
-hb_bool_t
-_hb_ot_layout_skip_mark (hb_face_t *face,
- hb_glyph_info_t *ginfo,
- unsigned int lookup_props,
- unsigned int *property_out)
-{
- unsigned int property;
-
- property = _hb_ot_layout_get_glyph_property (face, ginfo);
- (void) (property_out && (*property_out = property));
-
- /* If it's a mark, skip it we don't accept it. */
- if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
- return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
-
- /* If not a mark, don't skip. */
- return false;
-}
-
-
unsigned int
hb_ot_layout_get_attach_points (hb_face_t *face,
@@ -194,18 +143,19 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
}
+
/*
* GSUB/GPOS
*/
-static const GSUBGPOS&
+static const OT::GSUBGPOS&
get_gsubgpos_table (hb_face_t *face,
hb_tag_t table_tag)
{
switch (table_tag) {
case HB_OT_TAG_GSUB: return _get_gsub (face);
case HB_OT_TAG_GPOS: return _get_gpos (face);
- default: return Null(GSUBGPOS);
+ default: return OT::Null(OT::GSUBGPOS);
}
}
@@ -217,7 +167,7 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face,
unsigned int *script_count /* IN/OUT */,
hb_tag_t *script_tags /* OUT */)
{
- const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
return g.get_script_tags (start_offset, script_count, script_tags);
}
@@ -228,8 +178,8 @@ hb_ot_layout_table_find_script (hb_face_t *face,
hb_tag_t script_tag,
unsigned int *script_index)
{
- ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
- const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
if (g.find_script_index (script_tag, script_index))
return true;
@@ -254,8 +204,8 @@ hb_ot_layout_table_choose_script (hb_face_t *face,
unsigned int *script_index,
hb_tag_t *chosen_script)
{
- ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
- const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
while (*script_tags)
{
@@ -303,7 +253,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face,
unsigned int *feature_count /* IN/OUT */,
hb_tag_t *feature_tags /* OUT */)
{
- const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
return g.get_feature_tags (start_offset, feature_count, feature_tags);
}
@@ -317,7 +267,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
unsigned int *language_count /* IN/OUT */,
hb_tag_t *language_tags /* OUT */)
{
- const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
+ const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
return s.get_lang_sys_tags (start_offset, language_count, language_tags);
}
@@ -329,8 +279,8 @@ hb_ot_layout_script_find_language (hb_face_t *face,
hb_tag_t language_tag,
unsigned int *language_index)
{
- ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
- const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
+ const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
if (s.find_lang_sys_index (language_tag, language_index))
return true;
@@ -350,7 +300,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
unsigned int language_index,
unsigned int *feature_index)
{
- const LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
+ const OT::LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
if (feature_index) *feature_index = l.get_required_feature_index ();
@@ -366,8 +316,8 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
unsigned int *feature_count /* IN/OUT */,
unsigned int *feature_indexes /* OUT */)
{
- const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
- const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
}
@@ -381,8 +331,8 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
unsigned int *feature_count /* IN/OUT */,
hb_tag_t *feature_tags /* OUT */)
{
- const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
- const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);
@@ -405,9 +355,9 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
hb_tag_t feature_tag,
unsigned int *feature_index)
{
- ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
- const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
- const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
unsigned int num_features = l.get_feature_count ();
for (unsigned int i = 0; i < num_features; i++) {
@@ -431,84 +381,118 @@ hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face,
unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_indexes /* OUT */)
{
- const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
- const Feature &f = g.get_feature (feature_index);
+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+ const OT::Feature &f = g.get_feature (feature_index);
return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
}
/*
- * GSUB
+ * OT::GSUB
*/
hb_bool_t
hb_ot_layout_has_substitution (hb_face_t *face)
{
- return &_get_gsub (face) != &Null(GSUB);
+ return &_get_gsub (face) != &OT::Null(OT::GSUB);
+}
+
+hb_bool_t
+hb_ot_layout_would_substitute_lookup (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
+ return hb_ot_layout_would_substitute_lookup_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
+}
+
+hb_bool_t
+hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context)
+{
+ if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false;
+ OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context);
+
+ const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
+
+ return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_digests[lookup_index]);
}
void
-hb_ot_layout_substitute_start (hb_buffer_t *buffer)
+hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer)
{
- GSUB::substitute_start (buffer);
+ OT::GSUB::substitute_start (font, buffer);
}
hb_bool_t
-hb_ot_layout_substitute_lookup (hb_face_t *face,
+hb_ot_layout_substitute_lookup (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int lookup_index,
hb_mask_t mask)
{
- hb_apply_context_t c (NULL, face, buffer, mask);
- return _get_gsub (face).substitute_lookup (&c, lookup_index);
+ if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gsub_lookup_count)) return false;
+
+ OT::hb_apply_context_t c (font, buffer, mask);
+
+ const OT::SubstLookup& l = hb_ot_layout_from_face (font->face)->gsub->get_lookup (lookup_index);
+
+ return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gsub_digests[lookup_index]);
}
void
-hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED)
+hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer)
{
- GSUB::substitute_finish (buffer);
+ OT::GSUB::substitute_finish (font, buffer);
}
void
hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
- hb_set_t *glyphs,
- unsigned int lookup_index)
+ unsigned int lookup_index,
+ hb_set_t *glyphs)
{
- hb_closure_context_t c (face, glyphs);
+ OT::hb_closure_context_t c (face, glyphs);
_get_gsub (face).closure_lookup (&c, lookup_index);
}
/*
- * GPOS
+ * OT::GPOS
*/
hb_bool_t
hb_ot_layout_has_positioning (hb_face_t *face)
{
- return &_get_gpos (face) != &Null(GPOS);
+ return &_get_gpos (face) != &OT::Null(OT::GPOS);
}
void
-hb_ot_layout_position_start (hb_buffer_t *buffer)
+hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
{
- GPOS::position_start (buffer);
+ OT::GPOS::position_start (font, buffer);
}
hb_bool_t
-hb_ot_layout_position_lookup (hb_font_t *font,
- hb_buffer_t *buffer,
- unsigned int lookup_index,
- hb_mask_t mask)
+hb_ot_layout_position_lookup (hb_font_t *font,
+ hb_buffer_t *buffer,
+ unsigned int lookup_index,
+ hb_mask_t mask)
{
- hb_apply_context_t c (font, font->face, buffer, mask);
- return _get_gpos (font->face).position_lookup (&c, lookup_index);
+ if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gpos_lookup_count)) return false;
+
+ OT::hb_apply_context_t c (font, buffer, mask);
+
+ const OT::PosLookup& l = hb_ot_layout_from_face (font->face)->gpos->get_lookup (lookup_index);
+
+ return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gpos_digests[lookup_index]);
}
void
-hb_ot_layout_position_finish (hb_buffer_t *buffer)
+hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks)
{
- GPOS::position_finish (buffer);
+ OT::GPOS::position_finish (font, buffer, zero_width_attached_marks);
}
-
-
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-layout.h ('k') | third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698