Revert "Imported Upstream version 1.2.7"
[platform/upstream/harfbuzz.git] / src / hb-ot-layout-private.hh
index 778b2c4..47fecd2 100644 (file)
 #include "hb-set-private.hh"
 
 
-/* Private API corresponding to hb-ot-layout.h: */
-
-HB_INTERNAL hb_bool_t
-hb_ot_layout_table_find_feature (hb_face_t    *face,
-                                hb_tag_t      table_tag,
-                                hb_tag_t      feature_tag,
-                                unsigned int *feature_index);
-
-
 /*
  * GDEF
  */
 
-enum hb_ot_layout_glyph_props_flags_t
+typedef enum
 {
   /* The following three match LookupFlags::Ignore* numbers. */
   HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH  = 0x02u,
@@ -64,8 +55,7 @@ enum hb_ot_layout_glyph_props_flags_t
   HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE     = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
                                          HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
                                          HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED
-};
-HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t);
+} hb_ot_layout_glyph_class_mask_t;
 
 
 /*
@@ -99,20 +89,21 @@ hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
                                const hb_ot_layout_lookup_accelerator_t &accel);
 
 
-/* Should be called before all the position_lookup's are done. */
+/* Should be called after all the substitute_lookup's are done */
 HB_INTERNAL void
-hb_ot_layout_position_start (hb_font_t    *font,
-                            hb_buffer_t  *buffer);
+hb_ot_layout_substitute_finish (hb_font_t    *font,
+                               hb_buffer_t  *buffer);
+
 
-/* Should be called after all the position_lookup's are done, to finish advances. */
+/* Should be called before all the position_lookup's are done.  Resets positions to zero. */
 HB_INTERNAL void
-hb_ot_layout_position_finish_advances (hb_font_t    *font,
-                                      hb_buffer_t  *buffer);
+hb_ot_layout_position_start (hb_font_t    *font,
+                            hb_buffer_t  *buffer);
 
-/* Should be called after hb_ot_layout_position_finish_advances, to finish offsets. */
+/* Should be called after all the position_lookup's are done */
 HB_INTERNAL void
-hb_ot_layout_position_finish_offsets (hb_font_t    *font,
-                                     hb_buffer_t  *buffer);
+hb_ot_layout_position_finish (hb_font_t    *font,
+                             hb_buffer_t  *buffer);
 
 
 
@@ -180,224 +171,82 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout);
  */
 
 /* buffer var allocations, used during the entire shaping process */
-#define unicode_props()                var2.u16[0]
+#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 */
 
-
-/* loop over syllables */
-
-#define foreach_syllable(buffer, start, end) \
-  for (unsigned int \
-       _count = buffer->len, \
-       start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \
-       start < _count; \
-       start = end, end = _next_syllable (buffer, start))
-
-static inline unsigned int
-_next_syllable (hb_buffer_t *buffer, unsigned int start)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-
-  unsigned int syllable = info[start].syllable();
-  while (++start < count && syllable == info[start].syllable())
-    ;
-
-  return start;
-}
-
-
 /* unicode_props */
 
-/* Design:
- * unicode_props() is a two-byte number.  The low byte includes:
- * - General_Category: 5 bits.
- * - A bit each for:
- *   * Is it Default_Ignorable(); we have a modified Default_Ignorable().
- *   * Whether it's one of the three Mongolian Free Variation Selectors.
- *   * One free bit right now.
- *
- * The high-byte has different meanings, switched by the Gen-Cat:
- * - For Mn,Mc,Me: the modified Combining_Class.
- * - For Cf: whether it's ZWJ, ZWNJ, or something else.
- * - For Ws: index of which space character this is, if space fallback
- *   is needed, ie. we don't set this by default, only if asked to.
- */
-
-enum hb_unicode_props_flags_t {
-  UPROPS_MASK_GEN_CAT  = 0x001Fu,
-  UPROPS_MASK_IGNORABLE        = 0x0020u,
-  UPROPS_MASK_FVS      = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3 */
-
-  /* If GEN_CAT=FORMAT, top byte masks: */
-  UPROPS_MASK_Cf_ZWJ   = 0x0100u,
-  UPROPS_MASK_Cf_ZWNJ  = 0x0200u
+enum {
+  MASK0_ZWJ       = 0x20u,
+  MASK0_ZWNJ      = 0x40u,
+  MASK0_IGNORABLE = 0x80u,
+  MASK0_GEN_CAT   = 0x1Fu
 };
-HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t);
 
 static inline void
-_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
+_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
 {
-  hb_unicode_funcs_t *unicode = buffer->unicode;
-  unsigned int u = info->codepoint;
-  unsigned int gen_cat = (unsigned int) unicode->general_category (u);
-  unsigned int props = gen_cat;
-
-  if (u >= 0x80)
-  {
-    buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII;
-    if (unlikely (unicode->is_default_ignorable (u)))
-    {
-      buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
-      props |=  UPROPS_MASK_IGNORABLE;
-      if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ;
-      if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ;
-      /* Mongolian Free Variation Selectors need to be remembered
-       * because although we need to hide them like default-ignorables,
-       * they need to non-ignorable during shaping.  This is similar to
-       * what we do for joiners in Indic-like shapers, but since the
-       * FVSes are GC=Mn, we have use a separate bit to remember them.
-       * Fixes:
-       * https://github.com/behdad/harfbuzz/issues/234
-       */
-      if (unlikely (hb_in_range (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_FVS;
-    }
-    else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat)))
-    {
-      /* The above check is just an optimization to let in only things we need further
-       * processing on. */
-
-      /* Only Mn and Mc can have non-zero ccc:
-       * http://www.unicode.org/policies/stability_policy.html#Property_Value
-       * """
-       * Canonical_Combining_Class, General_Category
-       * All characters other than those with General_Category property values
-       * Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining_Class
-       * property value 0.
-       * 1.1.5+
-       * """
-       *
-       * Also, all Mn's that are Default_Ignorable, have ccc=0, hence
-       * the "else if".
-       */
-      props |= unicode->modified_combining_class (info->codepoint)<<8;
-
-      /* Recategorize emoji skin-tone modifiers as Unicode mark, so they
-       * behave correctly in non-native directionality.  They originally
-       * are MODIFIER_SYMBOL.  Fixes:
-       * https://github.com/behdad/harfbuzz/issues/169
-       */
-      if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu)))
-      {
-       props = gen_cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
-      }
-    }
-  }
-
-  info->unicode_props() = props;
+  /* 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) ? MASK0_IGNORABLE : 0) |
+                          (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) |
+                          (info->codepoint == 0x200Du ? MASK0_ZWJ : 0);
+  info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
 }
 
 static inline void
 _hb_glyph_info_set_general_category (hb_glyph_info_t *info,
                                     hb_unicode_general_category_t gen_cat)
 {
-  /* Clears top-byte. */
-  info->unicode_props() = (unsigned int) gen_cat | (info->unicode_props() & (0xFF & ~UPROPS_MASK_GEN_CAT));
+  info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
 }
 
 static 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_props() & UPROPS_MASK_GEN_CAT);
+  return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT);
 }
 
-static inline bool
-_hb_glyph_info_is_unicode_mark (const hb_glyph_info_t *info)
-{
-  return HB_UNICODE_GENERAL_CATEGORY_IS_MARK (info->unicode_props() & UPROPS_MASK_GEN_CAT);
-}
 static inline void
 _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
                                             unsigned int modified_class)
 {
-  if (unlikely (!_hb_glyph_info_is_unicode_mark (info)))
-    return;
-  info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF);
+  info->unicode_props1() = modified_class;
 }
+
 static inline unsigned int
 _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
 {
-  return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
-}
-
-static inline bool
-_hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info)
-{
-  return _hb_glyph_info_get_general_category (info) ==
-        HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR;
+  return info->unicode_props1();
 }
-static inline void
-_hb_glyph_info_set_unicode_space_fallback_type (hb_glyph_info_t *info, hb_unicode_funcs_t::space_t s)
-{
-  if (unlikely (!_hb_glyph_info_is_unicode_space (info)))
-    return;
-  info->unicode_props() = (((unsigned int) s)<<8) | (info->unicode_props() & 0xFF);
-}
-static inline hb_unicode_funcs_t::space_t
-_hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info)
-{
-  return _hb_glyph_info_is_unicode_space (info) ?
-        (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) :
-        hb_unicode_funcs_t::NOT_SPACE;
-}
-
-static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
 
 static inline hb_bool_t
 _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
 {
-  return (info->unicode_props() & UPROPS_MASK_IGNORABLE) &&
-        !_hb_glyph_info_ligated (info);
-}
-static inline hb_bool_t
-_hb_glyph_info_is_default_ignorable_and_not_fvs (const hb_glyph_info_t *info)
-{
-  return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_FVS))
-         == UPROPS_MASK_IGNORABLE) &&
-        !_hb_glyph_info_ligated (info);
+  return !!(info->unicode_props0() & MASK0_IGNORABLE);
 }
 
-static inline bool
-_hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)
-{
-  return _hb_glyph_info_get_general_category (info) ==
-        HB_UNICODE_GENERAL_CATEGORY_FORMAT;
-}
 static inline hb_bool_t
 _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
 {
-  return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWNJ);
+  return !!(info->unicode_props0() & MASK0_ZWNJ);
 }
+
 static inline hb_bool_t
 _hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
 {
-  return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ);
-}
-static inline hb_bool_t
-_hb_glyph_info_is_joiner (const hb_glyph_info_t *info)
-{
-  return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ));
+  return !!(info->unicode_props0() & MASK0_ZWJ);
 }
+
 static inline void
 _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
 {
-  if (!_hb_glyph_info_is_unicode_format (info))
-    return;
-  info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ;
+  info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
 }
 
 /* lig_props: aka lig_id / lig_comp
@@ -557,31 +406,28 @@ _hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info)
                           HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
 }
 
-static inline void
-_hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
-{
-  info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
-}
-
 
 /* Allocation / deallocation. */
 
 static inline void
 _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
 {
-  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props);
+  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
+  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
 }
 
 static inline void
 _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
 {
-  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
 }
 
 static inline void
 _hb_buffer_assert_unicode_vars (hb_buffer_t *buffer)
 {
-  HB_BUFFER_ASSERT_VAR (buffer, unicode_props);
+  HB_BUFFER_ASSERT_VAR (buffer, unicode_props0);
+  HB_BUFFER_ASSERT_VAR (buffer, unicode_props1);
 }
 
 static inline void