Index: third_party/harfbuzz-ng/src/hb-ot-layout-private.hh |
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh |
index 4866c41912530838e61bec0b056f45201679e708..139e33fe7a3e189548e262accd6ae3d2b0ba1483 100644 |
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh |
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh |
@@ -1,6 +1,6 @@ |
/* |
* Copyright © 2007,2008,2009 Red Hat, Inc. |
- * Copyright © 2012 Google, Inc. |
+ * Copyright © 2012,2013 Google, Inc. |
* |
* This is part of HarfBuzz, a text shaping library. |
* |
@@ -38,34 +38,179 @@ |
#include "hb-set-private.hh" |
-/* buffer var allocations, used during the GSUB/GPOS processing */ |
-#define glyph_props() var1.u16[0] /* GDEF glyph properties */ |
-#define syllable() var1.u8[2] /* GSUB/GPOS shaping boundaries */ |
-#define lig_props() var1.u8[3] /* GSUB/GPOS ligature tracking */ |
+/* |
+ * GDEF |
+ */ |
+ |
+typedef enum |
+{ |
+ /* The following three match LookupFlags::Ignore* numbers. */ |
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u, |
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x04u, |
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x08u, |
+ |
+ /* The following are used internally; not derived from GDEF. */ |
+ HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u, |
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u, |
+ |
+ HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | |
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
+} hb_ot_layout_glyph_class_mask_t; |
+ |
+ |
+/* |
+ * GSUB/GPOS |
+ */ |
+ |
+HB_INTERNAL hb_bool_t |
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, |
+ unsigned int lookup_index, |
+ const hb_codepoint_t *glyphs, |
+ unsigned int glyphs_length, |
+ hb_bool_t zero_context); |
+ |
+ |
+/* Should be called before all the substitute_lookup's are done. */ |
+HB_INTERNAL void |
+hb_ot_layout_substitute_start (hb_font_t *font, |
+ hb_buffer_t *buffer); |
+ |
+ |
+struct hb_ot_layout_lookup_accelerator_t; |
+ |
+namespace OT { |
+ struct hb_apply_context_t; |
+ struct SubstLookup; |
+} |
+ |
+HB_INTERNAL void |
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, |
+ const OT::SubstLookup &lookup, |
+ const hb_ot_layout_lookup_accelerator_t &accel); |
+ |
+ |
+/* Should be called after all the substitute_lookup's are done */ |
+HB_INTERNAL void |
+hb_ot_layout_substitute_finish (hb_font_t *font, |
+ hb_buffer_t *buffer); |
+ |
+ |
+/* Should be called before all the position_lookup's are done. Resets positions to zero. */ |
+HB_INTERNAL void |
+hb_ot_layout_position_start (hb_font_t *font, |
+ hb_buffer_t *buffer); |
+ |
+/* Should be called after all the position_lookup's are done */ |
+HB_INTERNAL void |
+hb_ot_layout_position_finish (hb_font_t *font, |
+ hb_buffer_t *buffer); |
+ |
+ |
+ |
+/* |
+ * hb_ot_layout_t |
+ */ |
+ |
+namespace OT { |
+ struct GDEF; |
+ struct GSUB; |
+ struct GPOS; |
+} |
+ |
+struct hb_ot_layout_lookup_accelerator_t |
+{ |
+ template <typename TLookup> |
+ inline void init (const TLookup &lookup) |
+ { |
+ digest.init (); |
+ lookup.add_coverage (&digest); |
+ } |
+ |
+ template <typename TLookup> |
+ inline void fini (const TLookup &lookup) |
+ { |
+ } |
+ |
+ hb_set_digest_t digest; |
+}; |
+ |
+struct hb_ot_layout_t |
+{ |
+ hb_blob_t *gdef_blob; |
+ hb_blob_t *gsub_blob; |
+ hb_blob_t *gpos_blob; |
+ |
+ const struct OT::GDEF *gdef; |
+ const struct OT::GSUB *gsub; |
+ const struct OT::GPOS *gpos; |
+ |
+ unsigned int gsub_lookup_count; |
+ unsigned int gpos_lookup_count; |
+ |
+ hb_ot_layout_lookup_accelerator_t *gsub_accels; |
+ hb_ot_layout_lookup_accelerator_t *gpos_accels; |
+}; |
+ |
+ |
+HB_INTERNAL hb_ot_layout_t * |
+_hb_ot_layout_create (hb_face_t *face); |
+ |
+HB_INTERNAL void |
+_hb_ot_layout_destroy (hb_ot_layout_t *layout); |
+ |
+ |
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot) |
+ |
+ |
+/* |
+ * Buffer var routines. |
+ */ |
/* buffer var allocations, used during the entire shaping process */ |
#define unicode_props0() var2.u8[0] |
#define unicode_props1() var2.u8[1] |
+/* buffer var allocations, used during the GSUB/GPOS processing */ |
+#define glyph_props() var1.u16[0] /* GDEF glyph properties */ |
+#define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */ |
+#define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */ |
+ |
+/* unicode_props */ |
+ |
+enum { |
+ MASK0_ZWJ = 0x20u, |
+ MASK0_ZWNJ = 0x40u, |
+ MASK0_IGNORABLE = 0x80u, |
+ MASK0_GEN_CAT = 0x1Fu |
+}; |
inline void |
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) |
{ |
+ /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */ |
info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) | |
- (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) | |
- (info->codepoint == 0x200C ? 0x40 : 0) | |
- (info->codepoint == 0x200D ? 0x20 : 0); |
+ (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) | |
+ (info->codepoint == 0x200C ? MASK0_ZWNJ : 0) | |
+ (info->codepoint == 0x200D ? MASK0_ZWJ : 0); |
info->unicode_props1() = unicode->modified_combining_class (info->codepoint); |
} |
+inline void |
+_hb_glyph_info_set_general_category (hb_glyph_info_t *info, |
+ hb_unicode_general_category_t gen_cat) |
+{ |
+ info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT); |
+} |
+ |
inline hb_unicode_general_category_t |
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info) |
{ |
- return (hb_unicode_general_category_t) (info->unicode_props0() & 0x1F); |
+ return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT); |
} |
inline void |
-_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class) |
+_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, |
+ unsigned int modified_class) |
{ |
info->unicode_props1() = modified_class; |
} |
@@ -79,43 +224,28 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) |
inline hb_bool_t |
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) |
{ |
- return !!(info->unicode_props0() & 0x80); |
+ return !!(info->unicode_props0() & MASK0_IGNORABLE); |
} |
inline hb_bool_t |
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) |
{ |
- return !!(info->unicode_props0() & 0x40); |
+ return !!(info->unicode_props0() & MASK0_ZWNJ); |
} |
inline hb_bool_t |
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info) |
{ |
- return !!(info->unicode_props0() & 0x20); |
+ return !!(info->unicode_props0() & MASK0_ZWJ); |
} |
+inline void |
+_hb_glyph_info_flip_joiners (hb_glyph_info_t *info) |
+{ |
+ info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ; |
+} |
-#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot) |
- |
-/* |
- * GDEF |
- */ |
- |
-typedef enum { |
- HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED = 1 << HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED, |
- HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 1 << HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH, |
- HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 1 << HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE, |
- HB_OT_LAYOUT_GLYPH_PROPS_MARK = 1 << HB_OT_LAYOUT_GLYPH_CLASS_MARK, |
- HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT = 1 << HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT |
-} hb_ot_layout_glyph_class_mask_t; |
- |
- |
- |
-/* |
- * GSUB/GPOS |
- */ |
- |
-/* lig_id / lig_comp |
+/* lig_props: aka lig_id / lig_comp |
* |
* When a ligature is formed: |
* |
@@ -125,7 +255,9 @@ typedef enum { |
* - The marks get lig_comp > 0, reflecting which component of the ligature |
* they were applied to. |
* - This is used in GPOS to attach marks to the right component of a ligature |
- * in MarkLigPos. |
+ * in MarkLigPos, |
+ * - Note that when marks are ligated together, much of the above is skipped |
+ * and the current lig_id reused. |
* |
* When a multiple-substitution is done: |
* |
@@ -135,139 +267,159 @@ typedef enum { |
* multiple substitution in MarkBasePos. |
* |
* The numbers are also used in GPOS to do mark-to-mark positioning only |
- * to marks that belong to the same component of a ligature in MarkMarPos. |
+ * to marks that belong to the same component of the same ligature. |
*/ |
+ |
+static inline void |
+_hb_glyph_info_clear_lig_props (hb_glyph_info_t *info) |
+{ |
+ info->lig_props() = 0; |
+} |
+ |
#define IS_LIG_BASE 0x10 |
+ |
static inline void |
-set_lig_props_for_ligature (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_num_comps) |
+_hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info, |
+ unsigned int lig_id, |
+ unsigned int lig_num_comps) |
{ |
- info.lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F); |
+ info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F); |
} |
+ |
static inline void |
-set_lig_props_for_mark (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp) |
+_hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info, |
+ unsigned int lig_id, |
+ unsigned int lig_comp) |
{ |
- info.lig_props() = (lig_id << 5) | (lig_comp & 0x0F); |
+ info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F); |
} |
+ |
static inline void |
-set_lig_props_for_component (hb_glyph_info_t &info, unsigned int comp) |
+_hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp) |
{ |
- set_lig_props_for_mark (info, 0, comp); |
+ _hb_glyph_info_set_lig_props_for_mark (info, 0, comp); |
} |
static inline unsigned int |
-get_lig_id (const hb_glyph_info_t &info) |
+_hb_glyph_info_get_lig_id (const hb_glyph_info_t *info) |
{ |
- return info.lig_props() >> 5; |
+ return info->lig_props() >> 5; |
} |
+ |
static inline bool |
-is_a_ligature (const hb_glyph_info_t &info) |
+_hb_glyph_info_ligated_internal (const hb_glyph_info_t *info) |
{ |
- return !!(info.lig_props() & IS_LIG_BASE); |
+ return !!(info->lig_props() & IS_LIG_BASE); |
} |
+ |
static inline unsigned int |
-get_lig_comp (const hb_glyph_info_t &info) |
+_hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info) |
{ |
- if (is_a_ligature (info)) |
+ if (_hb_glyph_info_ligated_internal (info)) |
return 0; |
else |
- return info.lig_props() & 0x0F; |
+ return info->lig_props() & 0x0F; |
} |
+ |
static inline unsigned int |
-get_lig_num_comps (const hb_glyph_info_t &info) |
+_hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info) |
{ |
- if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info)) |
- return info.lig_props() & 0x0F; |
+ if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && |
+ _hb_glyph_info_ligated_internal (info)) |
+ return info->lig_props() & 0x0F; |
else |
return 1; |
} |
-static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) { |
+static inline uint8_t |
+_hb_allocate_lig_id (hb_buffer_t *buffer) { |
uint8_t lig_id = buffer->next_serial () & 0x07; |
if (unlikely (!lig_id)) |
- lig_id = allocate_lig_id (buffer); /* in case of overflow */ |
+ lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */ |
return lig_id; |
} |
+/* glyph_props: */ |
-HB_INTERNAL hb_bool_t |
-hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, |
- unsigned int lookup_index, |
- const hb_codepoint_t *glyphs, |
- unsigned int glyphs_length, |
- hb_bool_t zero_context); |
- |
- |
-/* Should be called before all the substitute_lookup's are done. */ |
-HB_INTERNAL void |
-hb_ot_layout_substitute_start (hb_font_t *font, |
- hb_buffer_t *buffer); |
- |
-HB_INTERNAL hb_bool_t |
-hb_ot_layout_substitute_lookup (hb_font_t *font, |
- hb_buffer_t *buffer, |
- unsigned int lookup_index, |
- hb_mask_t mask, |
- hb_bool_t auto_zwj); |
- |
-/* Should be called after all the substitute_lookup's are done */ |
-HB_INTERNAL void |
-hb_ot_layout_substitute_finish (hb_font_t *font, |
- hb_buffer_t *buffer); |
- |
- |
-/* Should be called before all the position_lookup's are done. Resets positions to zero. */ |
-HB_INTERNAL void |
-hb_ot_layout_position_start (hb_font_t *font, |
- hb_buffer_t *buffer); |
- |
-HB_INTERNAL 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_bool_t auto_zwj); |
- |
-/* Should be called after all the position_lookup's are done */ |
-HB_INTERNAL void |
-hb_ot_layout_position_finish (hb_font_t *font, |
- hb_buffer_t *buffer); |
+inline void |
+_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props) |
+{ |
+ info->glyph_props() = props; |
+} |
+inline unsigned int |
+_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info) |
+{ |
+ return info->glyph_props(); |
+} |
+inline bool |
+_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info) |
+{ |
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH); |
+} |
-/* |
- * hb_ot_layout_t |
- */ |
+inline bool |
+_hb_glyph_info_is_ligature (const hb_glyph_info_t *info) |
+{ |
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE); |
+} |
-namespace OT { |
- struct GDEF; |
- struct GSUB; |
- struct GPOS; |
+inline bool |
+_hb_glyph_info_is_mark (const hb_glyph_info_t *info) |
+{ |
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK); |
} |
-struct hb_ot_layout_t |
+static inline bool |
+_hb_glyph_info_substituted (const hb_glyph_info_t *info) |
{ |
- hb_blob_t *gdef_blob; |
- hb_blob_t *gsub_blob; |
- hb_blob_t *gpos_blob; |
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED); |
+} |
- const struct OT::GDEF *gdef; |
- const struct OT::GSUB *gsub; |
- const struct OT::GPOS *gpos; |
+static inline bool |
+_hb_glyph_info_ligated (const hb_glyph_info_t *info) |
+{ |
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED); |
+} |
- unsigned int gsub_lookup_count; |
- unsigned int gpos_lookup_count; |
+/* Allocation / deallocation. */ |
- hb_set_digest_t *gsub_digests; |
- hb_set_digest_t *gpos_digests; |
-}; |
+inline void |
+_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer) |
+{ |
+ HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0); |
+ HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1); |
+} |
+inline void |
+_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer) |
+{ |
+ HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0); |
+ HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1); |
+} |
-HB_INTERNAL hb_ot_layout_t * |
-_hb_ot_layout_create (hb_face_t *face); |
+inline void |
+_hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer) |
+{ |
+ HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props); |
+ HB_BUFFER_ALLOCATE_VAR (buffer, lig_props); |
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable); |
+} |
-HB_INTERNAL void |
-_hb_ot_layout_destroy (hb_ot_layout_t *layout); |
+inline void |
+_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer) |
+{ |
+ HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); |
+ HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props); |
+ HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props); |
+} |
+/* Make sure no one directly touches our props... */ |
+#undef unicode_props0 |
+#undef unicode_props1 |
+#undef lig_props |
+#undef glyph_props |
#endif /* HB_OT_LAYOUT_PRIVATE_HH */ |