Imported Upstream version 2.6.4
[platform/upstream/harfbuzz.git] / src / hb-ot-shape.cc
index 7fff305..5d9a70c 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
+#ifdef HB_NO_OT_LAYOUT
+#error "Cannot compile 'ot' shaper with HB_NO_OT_LAYOUT."
+#endif
+
 #include "hb-shaper-impl.hh"
 
 #include "hb-ot-shape.hh"
@@ -55,7 +63,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
                              const hb_feature_t             *user_features,
                              unsigned int                    num_user_features);
 
-static bool
+#ifndef HB_NO_AAT_SHAPE
+static inline bool
 _hb_apply_morx (hb_face_t *face)
 {
   if (hb_options ().aat &&
@@ -69,14 +78,17 @@ _hb_apply_morx (hb_face_t *face)
                                               0, nullptr, nullptr)) &&
         hb_aat_layout_has_substitution (face);
 }
+#endif
 
 hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t                     *face,
                                              const hb_segment_properties_t *props) :
                                                face (face),
                                                props (*props),
                                                map (face, props),
-                                               aat_map (face, props),
-                                               apply_morx (_hb_apply_morx (face))
+                                               aat_map (face, props)
+#ifndef HB_NO_AAT_SHAPE
+                                               , apply_morx (_hb_apply_morx (face))
+#endif
 {
   shaper = hb_ot_shape_complex_categorize (this);
 
@@ -94,21 +106,30 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t           &plan,
   plan.props = props;
   plan.shaper = shaper;
   map.compile (plan.map, key);
+#ifndef HB_NO_AAT_SHAPE
   if (apply_morx)
     aat_map.compile (plan.aat_map);
+#endif
 
+#ifndef HB_NO_OT_SHAPE_FRACTIONS
   plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
   plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
   plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
   plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
+#endif
+
   plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
   hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ?
                      HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
+#ifndef HB_NO_OT_KERN
   plan.kern_mask = plan.map.get_mask (kern_tag);
-  plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
-
   plan.requested_kerning = !!plan.kern_mask;
+#endif
+#ifndef HB_NO_AAT_SHAPE
+  plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
   plan.requested_tracking = !!plan.trak_mask;
+#endif
+
   bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX;
   bool disable_gpos = plan.shaper->gpos_tag &&
                      plan.shaper->gpos_tag != plan.map.chosen_script[1];
@@ -124,42 +145,65 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t           &plan,
    * Decide who does substitutions. GSUB, morx, or fallback.
    */
 
+#ifndef HB_NO_AAT_SHAPE
   plan.apply_morx = apply_morx;
+#endif
 
   /*
    * Decide who does positioning. GPOS, kerx, kern, or fallback.
    */
 
-  if (hb_options ().aat && hb_aat_layout_has_positioning (face))
+  if (0)
+    ;
+#ifndef HB_NO_AAT_SHAPE
+  else if (hb_options ().aat && hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
+#endif
   else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face))
     plan.apply_gpos = true;
+#ifndef HB_NO_AAT_SHAPE
   else if (hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
+#endif
 
   if (!plan.apply_kerx && !has_gpos_kern)
   {
     /* Apparently Apple applies kerx if GPOS kern was not applied. */
+#ifndef HB_NO_AAT_SHAPE
     if (hb_aat_layout_has_positioning (face))
       plan.apply_kerx = true;
-    else if (hb_ot_layout_has_kerning (face))
+    else
+#endif
+#ifndef HB_NO_OT_KERN
+    if (hb_ot_layout_has_kerning (face))
       plan.apply_kern = true;
+#endif
   }
 
   plan.zero_marks = script_zero_marks &&
                    !plan.apply_kerx &&
-                   (!plan.apply_kern || !hb_ot_layout_has_machine_kerning (face));
+                   (!plan.apply_kern
+#ifndef HB_NO_OT_KERN
+                    || !hb_ot_layout_has_machine_kerning (face)
+#endif
+                   );
   plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
 
   plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos &&
                                              !plan.apply_kerx &&
-                                             (!plan.apply_kern || !hb_ot_layout_has_cross_kerning (face));
+                                             (!plan.apply_kern
+#ifndef HB_NO_OT_KERN
+                                              || !hb_ot_layout_has_cross_kerning (face)
+#endif
+                                             );
 
   plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing &&
                                   script_fallback_mark_positioning;
 
+#ifndef HB_NO_AAT_SHAPE
   /* Currently we always apply trak. */
   plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
+#endif
 }
 
 bool
@@ -167,7 +211,9 @@ hb_ot_shape_plan_t::init0 (hb_face_t                     *face,
                           const hb_shape_plan_key_t     *key)
 {
   map.init ();
+#ifndef HB_NO_AAT_SHAPE
   aat_map.init ();
+#endif
 
   hb_ot_shape_planner_t planner (face,
                                 &key->props);
@@ -195,16 +241,20 @@ hb_ot_shape_plan_t::fini ()
     shaper->data_destroy (const_cast<void *> (data));
 
   map.fini ();
+#ifndef HB_NO_AAT_SHAPE
   aat_map.fini ();
+#endif
 }
 
 void
 hb_ot_shape_plan_t::substitute (hb_font_t   *font,
                                hb_buffer_t *buffer) const
 {
+#ifndef HB_NO_AAT_SHAPE
   if (unlikely (apply_morx))
     hb_aat_layout_substitute (this, font, buffer);
   else
+#endif
     map.substitute (this, font, buffer);
 }
 
@@ -214,21 +264,29 @@ hb_ot_shape_plan_t::position (hb_font_t   *font,
 {
   if (this->apply_gpos)
     map.position (this, font, buffer);
+#ifndef HB_NO_AAT_SHAPE
   else if (this->apply_kerx)
     hb_aat_layout_position (this, font, buffer);
+#endif
+#ifndef HB_NO_OT_KERN
   else if (this->apply_kern)
     hb_ot_layout_kern (this, font, buffer);
+#endif
   else
     _hb_ot_shape_fallback_kern (this, font, buffer);
 
+#ifndef HB_NO_AAT_SHAPE
   if (this->apply_trak)
     hb_aat_layout_track (this, font, buffer);
+#endif
 }
 
 
 static const hb_ot_map_feature_t
 common_features[] =
 {
+  {HB_TAG('a','b','v','m'), F_GLOBAL},
+  {HB_TAG('b','l','w','m'), F_GLOBAL},
   {HB_TAG('c','c','m','p'), F_GLOBAL},
   {HB_TAG('l','o','c','l'), F_GLOBAL},
   {HB_TAG('m','a','r','k'), F_GLOBAL_MANUAL_JOINERS},
@@ -243,6 +301,7 @@ horizontal_features[] =
   {HB_TAG('c','a','l','t'), F_GLOBAL},
   {HB_TAG('c','l','i','g'), F_GLOBAL},
   {HB_TAG('c','u','r','s'), F_GLOBAL},
+  {HB_TAG('d','i','s','t'), F_GLOBAL},
   {HB_TAG('k','e','r','n'), F_GLOBAL_HAS_FALLBACK},
   {HB_TAG('l','i','g','a'), F_GLOBAL},
   {HB_TAG('r','c','l','t'), F_GLOBAL},
@@ -274,18 +333,22 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
       break;
   }
 
+#ifndef HB_NO_OT_SHAPE_FRACTIONS
   /* Automatic fractions. */
   map->add_feature (HB_TAG ('f','r','a','c'));
   map->add_feature (HB_TAG ('n','u','m','r'));
   map->add_feature (HB_TAG ('d','n','o','m'));
+#endif
 
   /* Random! */
   map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE);
 
+#ifndef HB_NO_AAT_SHAPE
   /* Tracking.  We enable dummy feature here just to allow disabling
    * AAT 'trak' table using features.
    * https://github.com/harfbuzz/harfbuzz/issues/1303 */
   map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK);
+#endif
 
   map->enable_feature (HB_TAG ('H','A','R','F'));
 
@@ -318,6 +381,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
                      feature->value);
   }
 
+#ifndef HB_NO_AAT_SHAPE
   if (planner->apply_morx)
   {
     hb_aat_map_builder_t *aat_map = &planner->aat_map;
@@ -327,6 +391,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
       aat_map->add_feature (feature->tag, feature->value);
     }
   }
+#endif
 
   if (planner->shaper->override_features)
     planner->shaper->override_features (planner);
@@ -417,17 +482,19 @@ hb_set_unicode_props (hb_buffer_t *buffer)
     {
        _hb_glyph_info_set_continuation (&info[i]);
     }
+#ifndef HB_NO_EMOJI_SEQUENCES
     else if (unlikely (_hb_glyph_info_is_zwj (&info[i])))
     {
       _hb_glyph_info_set_continuation (&info[i]);
       if (i + 1 < count &&
          _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint))
       {
-        i++;
+       i++;
        _hb_glyph_info_set_unicode_props (&info[i], buffer);
        _hb_glyph_info_set_continuation (&info[i]);
       }
     }
+#endif
     /* Or part of the Other_Grapheme_Extend that is not marks.
      * As of Unicode 11 that is just:
      *
@@ -551,6 +618,10 @@ hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
 static inline void
 hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
 {
+#ifdef HB_NO_OT_SHAPE_FRACTIONS
+  return;
+#endif
+
   if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
       !c->plan->has_frac)
     return;
@@ -579,19 +650,19 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
       while (start &&
             _hb_glyph_info_get_general_category (&info[start - 1]) ==
             HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
-        start--;
+       start--;
       while (end < count &&
             _hb_glyph_info_get_general_category (&info[end]) ==
             HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
-        end++;
+       end++;
 
       buffer->unsafe_to_break (start, end);
 
       for (unsigned int j = start; j < i; j++)
-        info[j].mask |= pre_mask;
+       info[j].mask |= pre_mask;
       info[i].mask |= c->plan->frac_mask;
       for (unsigned int j = i + 1; j < end; j++)
-        info[j].mask |= post_mask;
+       info[j].mask |= post_mask;
 
       i = end - 1;
     }
@@ -761,8 +832,10 @@ static inline void
 hb_ot_substitute_post (const hb_ot_shape_context_t *c)
 {
   hb_ot_hide_default_ignorables (c->buffer, c->font);
+#ifndef HB_NO_AAT_SHAPE
   if (c->plan->apply_morx)
     hb_aat_layout_remove_deleted_glyphs (c->buffer);
+#endif
 
   if (c->plan->shaper->postprocess_glyphs)
     c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
@@ -796,7 +869,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
     if (_hb_glyph_info_is_mark (&info[i]))
     {
       if (adjust_offsets)
-        adjust_mark_offsets (&buffer->pos[i]);
+       adjust_mark_offsets (&buffer->pos[i]);
       zero_mark_width (&buffer->pos[i]);
     }
 }
@@ -812,7 +885,7 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
   if (HB_DIRECTION_IS_HORIZONTAL (direction))
   {
     c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]),
-                                   &pos[0].x_advance, sizeof(pos[0]));
+                                  &pos[0].x_advance, sizeof(pos[0]));
     /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
     if (c->font->has_glyph_h_origin_func ())
       for (unsigned int i = 0; i < count; i++)
@@ -823,7 +896,7 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
   else
   {
     c->font->get_glyph_v_advances (count, &info[0].codepoint, sizeof(info[0]),
-                                   &pos[0].y_advance, sizeof(pos[0]));
+                                  &pos[0].y_advance, sizeof(pos[0]));
     for (unsigned int i = 0; i < count; i++)
     {
       c->font->subtract_glyph_v_origin (info[i].codepoint,
@@ -896,8 +969,10 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
   /* Finish off.  Has to follow a certain order. */
   hb_ot_layout_position_finish_advances (c->font, c->buffer);
   hb_ot_zero_width_default_ignorables (c->buffer);
+#ifndef HB_NO_AAT_SHAPE
   if (c->plan->apply_morx)
     hb_aat_layout_zero_width_deleted_glyphs (c->buffer);
+#endif
   hb_ot_layout_position_finish_offsets (c->font, c->buffer);
 
   /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
@@ -962,12 +1037,12 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
   c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
   if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR)))
   {
-    c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR,
+    c->buffer->max_len = hb_max (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR,
                              (unsigned) HB_BUFFER_MAX_LEN_MIN);
   }
   if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR)))
   {
-    c->buffer->max_ops = MAX (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR,
+    c->buffer->max_ops = hb_max (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR,
                              (unsigned) HB_BUFFER_MAX_OPS_MIN);
   }
 
@@ -1084,3 +1159,6 @@ hb_ot_shape_glyphs_closure (hb_font_t          *font,
 
   hb_shape_plan_destroy (shape_plan);
 }
+
+
+#endif