< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize.cc

Print this page




  74 decompose_unicode (const hb_ot_shape_normalize_context_t *c,
  75                    hb_codepoint_t  ab,
  76                    hb_codepoint_t *a,
  77                    hb_codepoint_t *b)
  78 {
  79   return (bool) c->unicode->decompose (ab, a, b);
  80 }
  81 
  82 static bool
  83 compose_unicode (const hb_ot_shape_normalize_context_t *c,
  84                  hb_codepoint_t  a,
  85                  hb_codepoint_t  b,
  86                  hb_codepoint_t *ab)
  87 {
  88   return (bool) c->unicode->compose (a, b, ab);
  89 }
  90 
  91 static inline void
  92 set_glyph (hb_glyph_info_t &info, hb_font_t *font)
  93 {
  94   font->get_nominal_glyph (info.codepoint, &info.glyph_index());
  95 }
  96 
  97 static inline void
  98 output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
  99 {
 100   buffer->cur().glyph_index() = glyph;
 101   buffer->output_glyph (unichar); /* This is very confusing indeed. */
 102   _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer);
 103 }
 104 
 105 static inline void
 106 next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
 107 {
 108   buffer->cur().glyph_index() = glyph;
 109   buffer->next_glyph ();
 110 }
 111 
 112 static inline void
 113 skip_char (hb_buffer_t *buffer)
 114 {


 328         break;
 329 
 330     decompose_cluster (&c, end, might_short_circuit, always_short_circuit);
 331   }
 332   buffer->swap_buffers ();
 333 
 334 
 335   /* Second round, reorder (inplace) */
 336 
 337   count = buffer->len;
 338   for (unsigned int i = 0; i < count; i++)
 339   {
 340     if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
 341       continue;
 342 
 343     unsigned int end;
 344     for (end = i + 1; end < count; end++)
 345       if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
 346         break;
 347 
 348     /* We are going to do a O(n^2).  Only do this if the sequence is short. */
 349     if (end - i > 10) {

 350       i = end;
 351       continue;
 352     }
 353 
 354     buffer->sort (i, end, compare_combining_class);
 355 



 356     i = end;
 357   }
 358 
 359 
 360   if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
 361       mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
 362     return;
 363 
 364   /* Third round, recompose */
 365 
 366   /* As noted in the comment earlier, we don't try to combine
 367    * ccc=0 chars with their previous Starter. */
 368 
 369   buffer->clear_output ();
 370   count = buffer->len;
 371   unsigned int starter = 0;

 372   buffer->next_glyph ();
 373   while (buffer->idx < count && !buffer->in_error)
 374   {
 375     hb_codepoint_t composed, glyph;
 376     if (/* 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
 378          * 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. */
 380         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     {
 393       /* Composes. */
 394       buffer->next_glyph (); /* Copy to out-buffer. */
 395       if (unlikely (buffer->in_error))
 396         return;
 397       buffer->merge_out_clusters (starter, buffer->out_len);
 398       buffer->out_len--; /* Remove the second composable. */
 399       /* Modify starter and carry on. */
 400       buffer->out_info[starter].codepoint = composed;
 401       buffer->out_info[starter].glyph_index() = glyph;
 402       _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
 403 
 404       continue;
 405     }






 406 
 407     /* Blocked, or doesn't compose. */
 408     buffer->next_glyph ();
 409 
 410     if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)

 411       starter = buffer->out_len - 1;


 412   }
 413   buffer->swap_buffers ();
 414 
 415 }


  74 decompose_unicode (const hb_ot_shape_normalize_context_t *c,
  75                    hb_codepoint_t  ab,
  76                    hb_codepoint_t *a,
  77                    hb_codepoint_t *b)
  78 {
  79   return (bool) c->unicode->decompose (ab, a, b);
  80 }
  81 
  82 static bool
  83 compose_unicode (const hb_ot_shape_normalize_context_t *c,
  84                  hb_codepoint_t  a,
  85                  hb_codepoint_t  b,
  86                  hb_codepoint_t *ab)
  87 {
  88   return (bool) c->unicode->compose (a, b, ab);
  89 }
  90 
  91 static inline void
  92 set_glyph (hb_glyph_info_t &info, hb_font_t *font)
  93 {
  94   (void) font->get_nominal_glyph (info.codepoint, &info.glyph_index());
  95 }
  96 
  97 static inline void
  98 output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
  99 {
 100   buffer->cur().glyph_index() = glyph;
 101   buffer->output_glyph (unichar); /* This is very confusing indeed. */
 102   _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer);
 103 }
 104 
 105 static inline void
 106 next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
 107 {
 108   buffer->cur().glyph_index() = glyph;
 109   buffer->next_glyph ();
 110 }
 111 
 112 static inline void
 113 skip_char (hb_buffer_t *buffer)
 114 {


 328         break;
 329 
 330     decompose_cluster (&c, end, might_short_circuit, always_short_circuit);
 331   }
 332   buffer->swap_buffers ();
 333 
 334 
 335   /* Second round, reorder (inplace) */
 336 
 337   count = buffer->len;
 338   for (unsigned int i = 0; i < count; i++)
 339   {
 340     if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
 341       continue;
 342 
 343     unsigned int end;
 344     for (end = i + 1; end < count; end++)
 345       if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
 346         break;
 347 
 348     /* We are going to do a O(n^2).  Only do this if the sequence is short,
 349      * but not too short ;). */
 350     if (end - i < 2 || end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
 351       i = end;
 352       continue;
 353     }
 354 
 355     buffer->sort (i, end, compare_combining_class);
 356 
 357     if (plan->shaper->reorder_marks)
 358       plan->shaper->reorder_marks (plan, buffer, i, end);
 359 
 360     i = end;
 361   }
 362 
 363 
 364   if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
 365       mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
 366     return;
 367 
 368   /* Third round, recompose */
 369 
 370   /* As noted in the comment earlier, we don't try to combine
 371    * ccc=0 chars with their previous Starter. */
 372 
 373   buffer->clear_output ();
 374   count = buffer->len;
 375   unsigned int starter = 0;
 376   bool combine = true;
 377   buffer->next_glyph ();
 378   while (buffer->idx < count && !buffer->in_error)
 379   {
 380     hb_codepoint_t composed, glyph;
 381     if (combine &&
 382         /* We don't try to compose a non-mark character with it's preceding starter.
 383          * This is both an optimization to avoid trying to compose every two neighboring
 384          * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
 385          * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
 386         HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
 387     {
 388       if (/* If there's anything between the starter and this char, they should have CCC
 389            * smaller than this character's. */
 390           (starter == buffer->out_len - 1 ||
 391            info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
 392           /* And compose. */
 393           c.compose (&c,
 394                      buffer->out_info[starter].codepoint,
 395                      buffer->cur().codepoint,
 396                      &composed) &&
 397           /* And the font has glyph for the composite. */
 398           font->get_nominal_glyph (composed, &glyph))
 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;
 418     }
 419 
 420     /* Blocked, or doesn't compose. */
 421     buffer->next_glyph ();
 422 
 423     if (info_cc (buffer->prev()) == 0)
 424     {
 425       starter = buffer->out_len - 1;
 426       combine = true;
 427     }
 428   }
 429   buffer->swap_buffers ();
 430 
 431 }
< prev index next >