Imported Upstream version 1.7.6
[platform/upstream/harfbuzz.git] / src / hb-ot-shape-normalize.cc
index 94a3d7d..62cbb9d 100644 (file)
@@ -346,13 +346,16 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
         break;
 
     /* We are going to do a O(n^2).  Only do this if the sequence is short. */
-    if (end - i > 10) {
+    if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
       i = end;
       continue;
     }
 
     buffer->sort (i, end, compare_combining_class);
 
+    if (plan->shaper->reorder_marks)
+      plan->shaper->reorder_marks (plan, buffer, i, end);
+
     i = end;
   }
 
@@ -377,39 +380,54 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
         * This is both an optimization to avoid trying to compose every two neighboring
         * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
         * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
-       HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) &&
-       /* If there's anything between the starter and this char, they should have CCC
-        * smaller than this character's. */
-       (starter == buffer->out_len - 1 ||
-        _hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
-       /* And compose. */
-       c.compose (&c,
-                  buffer->out_info[starter].codepoint,
-                  buffer->cur().codepoint,
-                  &composed) &&
-       /* And the font has glyph for the composite. */
-       font->get_nominal_glyph (composed, &glyph))
+       HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
     {
-      /* Composes. */
-      buffer->next_glyph (); /* Copy to out-buffer. */
-      if (unlikely (buffer->in_error))
-        return;
-      buffer->merge_out_clusters (starter, buffer->out_len);
-      buffer->out_len--; /* Remove the second composable. */
-      /* Modify starter and carry on. */
-      buffer->out_info[starter].codepoint = composed;
-      buffer->out_info[starter].glyph_index() = glyph;
-      _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
-
-      continue;
+      if (/* If there's anything between the starter and this char, they should have CCC
+          * smaller than this character's. */
+         (starter == buffer->out_len - 1 ||
+          info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
+         /* And compose. */
+         c.compose (&c,
+                    buffer->out_info[starter].codepoint,
+                    buffer->cur().codepoint,
+                    &composed) &&
+         /* And the font has glyph for the composite. */
+         font->get_nominal_glyph (composed, &glyph))
+      {
+       /* Composes. */
+       buffer->next_glyph (); /* Copy to out-buffer. */
+       if (unlikely (buffer->in_error))
+         return;
+       buffer->merge_out_clusters (starter, buffer->out_len);
+       buffer->out_len--; /* Remove the second composable. */
+       /* Modify starter and carry on. */
+       buffer->out_info[starter].codepoint = composed;
+       buffer->out_info[starter].glyph_index() = glyph;
+       _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
+
+       continue;
+      }
     }
 
     /* Blocked, or doesn't compose. */
     buffer->next_glyph ();
 
-    if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
+    if (info_cc (buffer->prev()) == 0)
       starter = buffer->out_len - 1;
   }
   buffer->swap_buffers ();
 
+  if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
+  {
+    /* For all CGJ, check if it prevented any reordering at all.
+     * If it did NOT, then make it skippable.
+     * https://github.com/harfbuzz/harfbuzz/issues/554
+     */
+    for (unsigned int i = 1; i + 1 < buffer->len; i++)
+      if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
+         info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1]))
+      {
+       _hb_glyph_info_unhide (&buffer->info[i]);
+      }
+  }
 }