src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize.cc
changeset 48274 51772bf1fb0c
parent 47216 71c04702a3d5
child 50352 25db2c8f3cf8
equal deleted inserted replaced
48273:e2065f7505eb 48274:51772bf1fb0c
    89 }
    89 }
    90 
    90 
    91 static inline void
    91 static inline void
    92 set_glyph (hb_glyph_info_t &info, hb_font_t *font)
    92 set_glyph (hb_glyph_info_t &info, hb_font_t *font)
    93 {
    93 {
    94   font->get_nominal_glyph (info.codepoint, &info.glyph_index());
    94   (void) font->get_nominal_glyph (info.codepoint, &info.glyph_index());
    95 }
    95 }
    96 
    96 
    97 static inline void
    97 static inline void
    98 output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
    98 output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
    99 {
    99 {
   343     unsigned int end;
   343     unsigned int end;
   344     for (end = i + 1; end < count; end++)
   344     for (end = i + 1; end < count; end++)
   345       if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
   345       if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
   346         break;
   346         break;
   347 
   347 
   348     /* We are going to do a O(n^2).  Only do this if the sequence is short. */
   348     /* We are going to do a O(n^2).  Only do this if the sequence is short,
   349     if (end - i > 10) {
   349      * but not too short ;). */
       
   350     if (end - i < 2 || end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
   350       i = end;
   351       i = end;
   351       continue;
   352       continue;
   352     }
   353     }
   353 
   354 
   354     buffer->sort (i, end, compare_combining_class);
   355     buffer->sort (i, end, compare_combining_class);
       
   356 
       
   357     if (plan->shaper->reorder_marks)
       
   358       plan->shaper->reorder_marks (plan, buffer, i, end);
   355 
   359 
   356     i = end;
   360     i = end;
   357   }
   361   }
   358 
   362 
   359 
   363 
   367    * ccc=0 chars with their previous Starter. */
   371    * ccc=0 chars with their previous Starter. */
   368 
   372 
   369   buffer->clear_output ();
   373   buffer->clear_output ();
   370   count = buffer->len;
   374   count = buffer->len;
   371   unsigned int starter = 0;
   375   unsigned int starter = 0;
       
   376   bool combine = true;
   372   buffer->next_glyph ();
   377   buffer->next_glyph ();
   373   while (buffer->idx < count && !buffer->in_error)
   378   while (buffer->idx < count && !buffer->in_error)
   374   {
   379   {
   375     hb_codepoint_t composed, glyph;
   380     hb_codepoint_t composed, glyph;
   376     if (/* We don't try to compose a non-mark character with it's preceding starter.
   381     if (combine &&
       
   382         /* We don't try to compose a non-mark character with it's preceding starter.
   377          * This is both an optimization to avoid trying to compose every two neighboring
   383          * This is both an optimization to avoid trying to compose every two neighboring
   378          * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
   384          * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
   379          * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
   385          * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
   380         HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) &&
   386         HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
   381         /* If there's anything between the starter and this char, they should have CCC
       
   382          * smaller than this character's. */
       
   383         (starter == buffer->out_len - 1 ||
       
   384          _hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
       
   385         /* And compose. */
       
   386         c.compose (&c,
       
   387                    buffer->out_info[starter].codepoint,
       
   388                    buffer->cur().codepoint,
       
   389                    &composed) &&
       
   390         /* And the font has glyph for the composite. */
       
   391         font->get_nominal_glyph (composed, &glyph))
       
   392     {
   387     {
   393       /* Composes. */
   388       if (/* If there's anything between the starter and this char, they should have CCC
   394       buffer->next_glyph (); /* Copy to out-buffer. */
   389            * smaller than this character's. */
   395       if (unlikely (buffer->in_error))
   390           (starter == buffer->out_len - 1 ||
   396         return;
   391            info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
   397       buffer->merge_out_clusters (starter, buffer->out_len);
   392           /* And compose. */
   398       buffer->out_len--; /* Remove the second composable. */
   393           c.compose (&c,
   399       /* Modify starter and carry on. */
   394                      buffer->out_info[starter].codepoint,
   400       buffer->out_info[starter].codepoint = composed;
   395                      buffer->cur().codepoint,
   401       buffer->out_info[starter].glyph_index() = glyph;
   396                      &composed) &&
   402       _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
   397           /* And the font has glyph for the composite. */
   403 
   398           font->get_nominal_glyph (composed, &glyph))
   404       continue;
   399       {
       
   400         /* Composes. */
       
   401         buffer->next_glyph (); /* Copy to out-buffer. */
       
   402         if (unlikely (buffer->in_error))
       
   403           return;
       
   404         buffer->merge_out_clusters (starter, buffer->out_len);
       
   405         buffer->out_len--; /* Remove the second composable. */
       
   406         /* Modify starter and carry on. */
       
   407         buffer->out_info[starter].codepoint = composed;
       
   408         buffer->out_info[starter].glyph_index() = glyph;
       
   409         _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
       
   410 
       
   411         continue;
       
   412       }
       
   413       else if (/* We sometimes custom-tailor the sorted order of marks. In that case, stop
       
   414                 * trying to combine as soon as combining-class drops. */
       
   415                starter < buffer->out_len - 1 &&
       
   416                info_cc (buffer->prev()) > info_cc (buffer->cur()))
       
   417         combine = false;
   405     }
   418     }
   406 
   419 
   407     /* Blocked, or doesn't compose. */
   420     /* Blocked, or doesn't compose. */
   408     buffer->next_glyph ();
   421     buffer->next_glyph ();
   409 
   422 
   410     if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
   423     if (info_cc (buffer->prev()) == 0)
       
   424     {
   411       starter = buffer->out_len - 1;
   425       starter = buffer->out_len - 1;
       
   426       combine = true;
       
   427     }
   412   }
   428   }
   413   buffer->swap_buffers ();
   429   buffer->swap_buffers ();
   414 
   430 
   415 }
   431 }