Implement the Unicode Canonical Composition algorithm
[framework/uifw/harfbuzz.git] / src / hb-ot-shape.cc
index 584ffbd..929a662 100644 (file)
 HB_BEGIN_DECLS
 
 
-hb_tag_t early_features[] = {
+hb_tag_t common_features[] = {
   HB_TAG('c','c','m','p'),
   HB_TAG('l','o','c','l'),
-};
-
-hb_tag_t common_features[] = {
   HB_TAG('m','a','r','k'),
   HB_TAG('m','k','m','k'),
   HB_TAG('r','l','i','g'),
@@ -94,8 +91,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
       planner->map.add_bool_feature (array[i]); \
   } HB_STMT_END
 
-  ADD_FEATURES (early_features);
-
   hb_ot_shape_complex_collect_features (planner->shaper, &planner->map, props);
 
   ADD_FEATURES (common_features);
@@ -181,60 +176,49 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
 
 /* Prepare */
 
-static inline hb_bool_t
-is_variation_selector (hb_codepoint_t unicode)
-{
-  return unlikely ((unicode >=  0x180B && unicode <=  0x180D) || /* MONGOLIAN FREE VARIATION SELECTOR ONE..THREE */
-                  (unicode >=  0xFE00 && unicode <=  0xFE0F) || /* VARIATION SELECTOR-1..16 */
-                  (unicode >= 0xE0100 && unicode <= 0xE01EF));  /* VARIATION SELECTOR-17..256 */
-}
-
-static void
-hb_set_unicode_props (hb_ot_shape_context_t *c)
+void
+_hb_set_unicode_props (hb_buffer_t *buffer)
 {
-  hb_unicode_funcs_t *unicode = c->buffer->unicode;
-  hb_glyph_info_t *info = c->buffer->info;
-
-  unsigned int count = c->buffer->len;
-  for (unsigned int i = 1; i < count; i++) {
-    info[i].general_category() = unicode->get_general_category (info[i].codepoint);
-    info[i].combining_class() = unicode->get_combining_class (info[i].codepoint);
-  }
+  unsigned int count = buffer->len;
+  for (unsigned int i = 1; i < count; i++)
+    hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode);
 }
 
 static void
-hb_form_clusters (hb_ot_shape_context_t *c)
+hb_form_clusters (hb_buffer_t *buffer)
 {
-  unsigned int count = c->buffer->len;
+  unsigned int count = buffer->len;
   for (unsigned int i = 1; i < count; i++)
-    /* TODO: Match other mark types too? */
-    if (c->buffer->info[i].general_category() == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
-      c->buffer->info[i].cluster = c->buffer->info[i - 1].cluster;
+    if (FLAG (buffer->info[i].general_category()) &
+       (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) |
+        FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
+        FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
+      buffer->info[i].cluster = buffer->info[i - 1].cluster;
 }
 
 static void
-hb_ensure_native_direction (hb_ot_shape_context_t *c)
+hb_ensure_native_direction (hb_buffer_t *buffer)
 {
-  hb_direction_t direction = c->buffer->props.direction;
+  hb_direction_t direction = buffer->props.direction;
 
   /* TODO vertical:
    * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType
    * Ogham fonts are supposed to be implemented BTT or not.  Need to research that
    * first. */
-  if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (c->buffer->props.script)) ||
+  if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) ||
       (HB_DIRECTION_IS_VERTICAL   (direction) && direction != HB_DIRECTION_TTB))
   {
-    hb_buffer_reverse_clusters (c->buffer);
-    c->buffer->props.direction = HB_DIRECTION_REVERSE (c->buffer->props.direction);
+    hb_buffer_reverse_clusters (buffer);
+    buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction);
   }
 }
 
 static void
-hb_reset_glyph_infos (hb_ot_shape_context_t *c)
+hb_reset_glyph_infos (hb_buffer_t *buffer)
 {
-  unsigned int count = c->buffer->len;
+  unsigned int count = buffer->len;
   for (unsigned int i = 0; i < count; i++)
-    c->buffer->info[i].var1.u32 = c->buffer->info[i].var2.u32 = 0;
+    buffer->info[i].var1.u32 = buffer->info[i].var2.u32 = 0;
 }
 
 
@@ -252,7 +236,7 @@ hb_mirror_chars (hb_ot_shape_context_t *c)
 
   unsigned int count = c->buffer->len;
   for (unsigned int i = 0; i < count; i++) {
-    hb_codepoint_t codepoint = unicode->get_mirroring (c->buffer->info[i].codepoint);
+    hb_codepoint_t codepoint = hb_unicode_mirroring (unicode, c->buffer->info[i].codepoint);
     if (likely (codepoint == c->buffer->info[i].codepoint))
       c->buffer->info[i].mask |= rtlm_mask; /* XXX this should be moved to before setting user-feature masks */
     else
@@ -264,27 +248,29 @@ static void
 hb_map_glyphs (hb_font_t    *font,
               hb_buffer_t  *buffer)
 {
+  hb_codepoint_t glyph;
+
   if (unlikely (!buffer->len))
     return;
 
-  hb_codepoint_t glyph;
   buffer->clear_output ();
+
   unsigned int count = buffer->len - 1;
-  for (buffer->i = 0; buffer->i < count;) {
-    if (unlikely (is_variation_selector (buffer->info[buffer->i + 1].codepoint))) {
-      hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, buffer->info[buffer->i + 1].codepoint, &glyph);
+  for (buffer->idx = 0; buffer->idx < count;) {
+    if (unlikely (is_variation_selector (buffer->info[buffer->idx + 1].codepoint))) {
+      hb_font_get_glyph (font, buffer->info[buffer->idx].codepoint, buffer->info[buffer->idx + 1].codepoint, &glyph);
       buffer->replace_glyph (glyph);
-      buffer->i++;
+      buffer->skip_glyph ();
     } else {
-      hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, 0, &glyph);
+      hb_font_get_glyph (font, buffer->info[buffer->idx].codepoint, 0, &glyph);
       buffer->replace_glyph (glyph);
     }
   }
-  if (likely (buffer->i < buffer->len)) {
-    hb_font_get_glyph (font, buffer->info[buffer->i].codepoint, 0, &glyph);
+  if (likely (buffer->idx < buffer->len)) {
+    hb_font_get_glyph (font, buffer->info[buffer->idx].codepoint, 0, &glyph);
     buffer->replace_glyph (glyph);
   }
-  buffer->swap ();
+  buffer->swap_buffers ();
 }
 
 static void
@@ -367,19 +353,20 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
   /* Save the original direction, we use it later. */
   c->target_direction = c->buffer->props.direction;
 
-  hb_reset_glyph_infos (c); /* BUFFER: Clear buffer var1 and var2 */
+  hb_reset_glyph_infos (c->buffer); /* BUFFER: Clear buffer var1 and var2 */
+
+  _hb_set_unicode_props (c->buffer); /* BUFFER: Set general_category and combining_class in var1 */
 
-  hb_set_unicode_props (c); /* BUFFER: Set general_category and combining_class in var1 */
+  hb_form_clusters (c->buffer);
 
-  hb_ensure_native_direction (c);
+  hb_ensure_native_direction (c->buffer);
 
-  hb_form_clusters (c);
+  _hb_ot_shape_normalize (c);
 
   hb_ot_shape_setup_masks (c); /* BUFFER: Clobbers var2 */
 
   /* SUBSTITUTE */
   {
-    /* Mirroring needs to see the original direction */
     hb_mirror_chars (c);
 
     hb_substitute_default (c);