src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.cc
changeset 48274 51772bf1fb0c
parent 47216 71c04702a3d5
child 50352 25db2c8f3cf8
equal deleted inserted replaced
48273:e2065f7505eb 48274:51772bf1fb0c
    68                               unsigned int                    num_user_features)
    68                               unsigned int                    num_user_features)
    69 {
    69 {
    70   hb_ot_map_builder_t *map = &planner->map;
    70   hb_ot_map_builder_t *map = &planner->map;
    71 
    71 
    72   map->add_global_bool_feature (HB_TAG('r','v','r','n'));
    72   map->add_global_bool_feature (HB_TAG('r','v','r','n'));
    73   map->add_gsub_pause (NULL);
    73   map->add_gsub_pause (nullptr);
    74 
    74 
    75   switch (props->direction) {
    75   switch (props->direction) {
    76     case HB_DIRECTION_LTR:
    76     case HB_DIRECTION_LTR:
    77       map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
    77       map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
    78       map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
    78       map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
   126 
   126 
   127 /*
   127 /*
   128  * shaper face data
   128  * shaper face data
   129  */
   129  */
   130 
   130 
       
   131 HB_SHAPER_DATA_ENSURE_DEFINE(ot, face)
       
   132 
   131 hb_ot_shaper_face_data_t *
   133 hb_ot_shaper_face_data_t *
   132 _hb_ot_shaper_face_data_create (hb_face_t *face)
   134 _hb_ot_shaper_face_data_create (hb_face_t *face)
   133 {
   135 {
   134   return _hb_ot_layout_create (face);
   136   return _hb_ot_layout_create (face);
   135 }
   137 }
   142 
   144 
   143 
   145 
   144 /*
   146 /*
   145  * shaper font data
   147  * shaper font data
   146  */
   148  */
       
   149 
       
   150 HB_SHAPER_DATA_ENSURE_DEFINE(ot, font)
   147 
   151 
   148 struct hb_ot_shaper_font_data_t {};
   152 struct hb_ot_shaper_font_data_t {};
   149 
   153 
   150 hb_ot_shaper_font_data_t *
   154 hb_ot_shaper_font_data_t *
   151 _hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED)
   155 _hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED)
   170                                       const int          *coords,
   174                                       const int          *coords,
   171                                       unsigned int        num_coords)
   175                                       unsigned int        num_coords)
   172 {
   176 {
   173   hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
   177   hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
   174   if (unlikely (!plan))
   178   if (unlikely (!plan))
   175     return NULL;
   179     return nullptr;
   176 
   180 
   177   hb_ot_shape_planner_t planner (shape_plan);
   181   hb_ot_shape_planner_t planner (shape_plan);
   178 
   182 
   179   planner.shaper = hb_ot_shape_complex_categorize (&planner);
   183   planner.shaper = hb_ot_shape_complex_categorize (&planner);
   180 
   184 
   184   planner.compile (*plan, coords, num_coords);
   188   planner.compile (*plan, coords, num_coords);
   185 
   189 
   186   if (plan->shaper->data_create) {
   190   if (plan->shaper->data_create) {
   187     plan->data = plan->shaper->data_create (plan);
   191     plan->data = plan->shaper->data_create (plan);
   188     if (unlikely (!plan->data))
   192     if (unlikely (!plan->data))
   189       return NULL;
   193       return nullptr;
   190   }
   194   }
   191 
   195 
   192   return plan;
   196   return plan;
   193 }
   197 }
   194 
   198 
   269 }
   273 }
   270 
   274 
   271 static void
   275 static void
   272 hb_form_clusters (hb_buffer_t *buffer)
   276 hb_form_clusters (hb_buffer_t *buffer)
   273 {
   277 {
   274   if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
   278   if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII))
   275       buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
       
   276     return;
   279     return;
   277 
   280 
   278   /* Loop duplicated in hb_ensure_native_direction(), and in _hb-coretext.cc */
   281   /* Loop duplicated in hb_ensure_native_direction(), and in _hb-coretext.cc */
   279   unsigned int base = 0;
   282   unsigned int base = 0;
   280   unsigned int count = buffer->len;
   283   unsigned int count = buffer->len;
   282   for (unsigned int i = 1; i < count; i++)
   285   for (unsigned int i = 1; i < count; i++)
   283   {
   286   {
   284     if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])) &&
   287     if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])) &&
   285                 !_hb_glyph_info_is_joiner (&info[i])))
   288                 !_hb_glyph_info_is_joiner (&info[i])))
   286     {
   289     {
   287       buffer->merge_clusters (base, i);
   290       if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
       
   291         buffer->merge_clusters (base, i);
       
   292       else
       
   293         buffer->unsafe_to_break (base, i);
   288       base = i;
   294       base = i;
   289     }
   295     }
   290   }
   296   }
   291   buffer->merge_clusters (base, count);
   297   if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
       
   298     buffer->merge_clusters (base, count);
       
   299   else
       
   300     buffer->unsafe_to_break (base, count);
   292 }
   301 }
   293 
   302 
   294 static void
   303 static void
   295 hb_ensure_native_direction (hb_buffer_t *buffer)
   304 hb_ensure_native_direction (hb_buffer_t *buffer)
   296 {
   305 {
   360       !c->plan->has_frac)
   369       !c->plan->has_frac)
   361     return;
   370     return;
   362 
   371 
   363   hb_buffer_t *buffer = c->buffer;
   372   hb_buffer_t *buffer = c->buffer;
   364 
   373 
   365   /* TODO look in pre/post context text also. */
   374   hb_mask_t pre_mask, post_mask;
       
   375   if (HB_DIRECTION_IS_FORWARD (buffer->props.direction))
       
   376   {
       
   377     pre_mask = c->plan->numr_mask | c->plan->frac_mask;
       
   378     post_mask = c->plan->frac_mask | c->plan->dnom_mask;
       
   379   }
       
   380   else
       
   381   {
       
   382     pre_mask = c->plan->frac_mask | c->plan->dnom_mask;
       
   383     post_mask = c->plan->numr_mask | c->plan->frac_mask;
       
   384   }
       
   385 
   366   unsigned int count = buffer->len;
   386   unsigned int count = buffer->len;
   367   hb_glyph_info_t *info = buffer->info;
   387   hb_glyph_info_t *info = buffer->info;
   368   for (unsigned int i = 0; i < count; i++)
   388   for (unsigned int i = 0; i < count; i++)
   369   {
   389   {
   370     if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */
   390     if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */
   377       while (end < count &&
   397       while (end < count &&
   378              _hb_glyph_info_get_general_category (&info[end]) ==
   398              _hb_glyph_info_get_general_category (&info[end]) ==
   379              HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
   399              HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
   380         end++;
   400         end++;
   381 
   401 
       
   402       buffer->unsafe_to_break (start, end);
       
   403 
   382       for (unsigned int j = start; j < i; j++)
   404       for (unsigned int j = start; j < i; j++)
   383         info[j].mask |= c->plan->numr_mask | c->plan->frac_mask;
   405         info[j].mask |= pre_mask;
   384       info[i].mask |= c->plan->frac_mask;
   406       info[i].mask |= c->plan->frac_mask;
   385       for (unsigned int j = i + 1; j < end; j++)
   407       for (unsigned int j = i + 1; j < end; j++)
   386         info[j].mask |= c->plan->frac_mask | c->plan->dnom_mask;
   408         info[j].mask |= post_mask;
   387 
   409 
   388       i = end - 1;
   410       i = end - 1;
   389     }
   411     }
   390   }
   412   }
   391 }
   413 }
   492         if (j)
   514         if (j)
   493         {
   515         {
   494           /* Merge cluster backward. */
   516           /* Merge cluster backward. */
   495           if (cluster < info[j - 1].cluster)
   517           if (cluster < info[j - 1].cluster)
   496           {
   518           {
       
   519             unsigned int mask = info[i].mask;
   497             unsigned int old_cluster = info[j - 1].cluster;
   520             unsigned int old_cluster = info[j - 1].cluster;
   498             for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
   521             for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
   499               info[k - 1].cluster = cluster;
   522               buffer->set_cluster (info[k - 1], cluster, mask);
   500           }
   523           }
   501           continue;
   524           continue;
   502         }
   525         }
   503 
   526 
   504         if (i + 1 < count)
   527         if (i + 1 < count)
   560 static inline void
   583 static inline void
   561 hb_ot_substitute_default (hb_ot_shape_context_t *c)
   584 hb_ot_substitute_default (hb_ot_shape_context_t *c)
   562 {
   585 {
   563   hb_buffer_t *buffer = c->buffer;
   586   hb_buffer_t *buffer = c->buffer;
   564 
   587 
   565   hb_ot_shape_initialize_masks (c);
       
   566 
       
   567   hb_ot_mirror_chars (c);
   588   hb_ot_mirror_chars (c);
   568 
   589 
   569   HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
   590   HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
   570 
   591 
   571   _hb_ot_shape_normalize (c->plan, buffer, c->font);
   592   _hb_ot_shape_normalize (c->plan, buffer, c->font);
   670 }
   691 }
   671 
   692 
   672 static inline void
   693 static inline void
   673 hb_ot_position_complex (hb_ot_shape_context_t *c)
   694 hb_ot_position_complex (hb_ot_shape_context_t *c)
   674 {
   695 {
   675   hb_ot_layout_position_start (c->font, c->buffer);
       
   676 
       
   677   unsigned int count = c->buffer->len;
   696   unsigned int count = c->buffer->len;
       
   697   hb_glyph_info_t *info = c->buffer->info;
       
   698   hb_glyph_position_t *pos = c->buffer->pos;
   678 
   699 
   679   /* If the font has no GPOS, AND, no fallback positioning will
   700   /* If the font has no GPOS, AND, no fallback positioning will
   680    * happen, AND, direction is forward, then when zeroing mark
   701    * happen, AND, direction is forward, then when zeroing mark
   681    * widths, we shift the mark with it, such that the mark
   702    * widths, we shift the mark with it, such that the mark
   682    * is positioned hanging over the previous glyph.  When
   703    * is positioned hanging over the previous glyph.  When
   687    */
   708    */
   688   bool adjust_offsets_when_zeroing = c->fallback_positioning &&
   709   bool adjust_offsets_when_zeroing = c->fallback_positioning &&
   689                                      !c->plan->shaper->fallback_position &&
   710                                      !c->plan->shaper->fallback_position &&
   690                                      HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
   711                                      HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
   691 
   712 
       
   713   /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
       
   714 
       
   715   /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
       
   716   if (c->font->has_glyph_h_origin_func ())
       
   717     for (unsigned int i = 0; i < count; i++)
       
   718       c->font->add_glyph_h_origin (info[i].codepoint,
       
   719                                    &pos[i].x_offset,
       
   720                                    &pos[i].y_offset);
       
   721 
       
   722   hb_ot_layout_position_start (c->font, c->buffer);
       
   723 
   692   switch (c->plan->shaper->zero_width_marks)
   724   switch (c->plan->shaper->zero_width_marks)
   693   {
   725   {
   694     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
   726     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
   695       zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
   727       zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
   696       break;
   728       break;
   700     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
   732     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
   701       break;
   733       break;
   702   }
   734   }
   703 
   735 
   704   if (likely (!c->fallback_positioning))
   736   if (likely (!c->fallback_positioning))
   705   {
       
   706     hb_glyph_info_t *info = c->buffer->info;
       
   707     hb_glyph_position_t *pos = c->buffer->pos;
       
   708 
       
   709     /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
       
   710 
       
   711     /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
       
   712     if (c->font->has_glyph_h_origin_func ())
       
   713       for (unsigned int i = 0; i < count; i++)
       
   714         c->font->add_glyph_h_origin (info[i].codepoint,
       
   715                                      &pos[i].x_offset,
       
   716                                      &pos[i].y_offset);
       
   717 
       
   718     c->plan->position (c->font, c->buffer);
   737     c->plan->position (c->font, c->buffer);
   719 
       
   720     /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
       
   721     if (c->font->has_glyph_h_origin_func ())
       
   722       for (unsigned int i = 0; i < count; i++)
       
   723         c->font->subtract_glyph_h_origin (info[i].codepoint,
       
   724                                           &pos[i].x_offset,
       
   725                                           &pos[i].y_offset);
       
   726 
       
   727   }
       
   728 
   738 
   729   switch (c->plan->shaper->zero_width_marks)
   739   switch (c->plan->shaper->zero_width_marks)
   730   {
   740   {
   731     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
   741     case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
   732       zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
   742       zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
   740 
   750 
   741   /* Finishing off GPOS has to follow a certain order. */
   751   /* Finishing off GPOS has to follow a certain order. */
   742   hb_ot_layout_position_finish_advances (c->font, c->buffer);
   752   hb_ot_layout_position_finish_advances (c->font, c->buffer);
   743   hb_ot_zero_width_default_ignorables (c);
   753   hb_ot_zero_width_default_ignorables (c);
   744   hb_ot_layout_position_finish_offsets (c->font, c->buffer);
   754   hb_ot_layout_position_finish_offsets (c->font, c->buffer);
       
   755 
       
   756   /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
       
   757   if (c->font->has_glyph_h_origin_func ())
       
   758     for (unsigned int i = 0; i < count; i++)
       
   759       c->font->subtract_glyph_h_origin (info[i].codepoint,
       
   760                                         &pos[i].x_offset,
       
   761                                         &pos[i].y_offset);
   745 }
   762 }
   746 
   763 
   747 static inline void
   764 static inline void
   748 hb_ot_position (hb_ot_shape_context_t *c)
   765 hb_ot_position (hb_ot_shape_context_t *c)
   749 {
   766 {
   765     _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
   782     _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
   766 
   783 
   767   _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
   784   _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
   768 }
   785 }
   769 
   786 
       
   787 static inline void
       
   788 hb_propagate_flags (hb_buffer_t *buffer)
       
   789 {
       
   790   /* Propagate cluster-level glyph flags to be the same on all cluster glyphs.
       
   791    * Simplifies using them. */
       
   792 
       
   793   if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK))
       
   794     return;
       
   795 
       
   796   hb_glyph_info_t *info = buffer->info;
       
   797 
       
   798   foreach_cluster (buffer, start, end)
       
   799   {
       
   800     unsigned int mask = 0;
       
   801     for (unsigned int i = start; i < end; i++)
       
   802       if (info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
       
   803       {
       
   804          mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
       
   805          break;
       
   806       }
       
   807     if (mask)
       
   808       for (unsigned int i = start; i < end; i++)
       
   809         info[i].mask |= mask;
       
   810   }
       
   811 }
   770 
   812 
   771 /* Pull it all together! */
   813 /* Pull it all together! */
   772 
   814 
   773 static void
   815 static void
   774 hb_ot_shape_internal (hb_ot_shape_context_t *c)
   816 hb_ot_shape_internal (hb_ot_shape_context_t *c)
   791 
   833 
   792   _hb_buffer_allocate_unicode_vars (c->buffer);
   834   _hb_buffer_allocate_unicode_vars (c->buffer);
   793 
   835 
   794   c->buffer->clear_output ();
   836   c->buffer->clear_output ();
   795 
   837 
       
   838   hb_ot_shape_initialize_masks (c);
   796   hb_set_unicode_props (c->buffer);
   839   hb_set_unicode_props (c->buffer);
   797   hb_insert_dotted_circle (c->buffer, c->font);
   840   hb_insert_dotted_circle (c->buffer, c->font);
       
   841 
   798   hb_form_clusters (c->buffer);
   842   hb_form_clusters (c->buffer);
   799 
   843 
   800   hb_ensure_native_direction (c->buffer);
   844   hb_ensure_native_direction (c->buffer);
   801 
   845 
   802   if (c->plan->shaper->preprocess_text)
   846   if (c->plan->shaper->preprocess_text)
   807 
   851 
   808   hb_ot_hide_default_ignorables (c);
   852   hb_ot_hide_default_ignorables (c);
   809 
   853 
   810   if (c->plan->shaper->postprocess_glyphs)
   854   if (c->plan->shaper->postprocess_glyphs)
   811     c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
   855     c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
       
   856 
       
   857   hb_propagate_flags (c->buffer);
   812 
   858 
   813   _hb_buffer_deallocate_unicode_vars (c->buffer);
   859   _hb_buffer_deallocate_unicode_vars (c->buffer);
   814 
   860 
   815   c->buffer->props.direction = c->target_direction;
   861   c->buffer->props.direction = c->target_direction;
   816 
   862 
   880                             unsigned int        num_features,
   926                             unsigned int        num_features,
   881                             hb_set_t           *glyphs)
   927                             hb_set_t           *glyphs)
   882 {
   928 {
   883   hb_ot_shape_plan_t plan;
   929   hb_ot_shape_plan_t plan;
   884 
   930 
   885   const char *shapers[] = {"ot", NULL};
   931   const char *shapers[] = {"ot", nullptr};
   886   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
   932   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
   887                                                              features, num_features, shapers);
   933                                                              features, num_features, shapers);
   888 
   934 
   889   bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
   935   bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
   890 
   936 
   891   unsigned int count = buffer->len;
   937   unsigned int count = buffer->len;
   892   hb_glyph_info_t *info = buffer->info;
   938   hb_glyph_info_t *info = buffer->info;
   893   for (unsigned int i = 0; i < count; i++)
   939   for (unsigned int i = 0; i < count; i++)
   894     add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs);
   940     add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs);
   895 
   941 
   896   hb_set_t lookups;
   942   hb_set_t *lookups = hb_set_create ();
   897   lookups.init ();
   943   hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, lookups);
   898   hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups);
       
   899 
   944 
   900   /* And find transitive closure. */
   945   /* And find transitive closure. */
   901   hb_set_t copy;
   946   hb_set_t *copy = hb_set_create ();
   902   copy.init ();
       
   903   do {
   947   do {
   904     copy.set (glyphs);
   948     copy->set (glyphs);
   905     for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index);)
   949     for (hb_codepoint_t lookup_index = -1; hb_set_next (lookups, &lookup_index);)
   906       hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
   950       hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
   907   } while (!copy.is_equal (glyphs));
   951   } while (!copy->is_equal (glyphs));
       
   952   hb_set_destroy (copy);
       
   953 
       
   954   hb_set_destroy (lookups);
   908 
   955 
   909   hb_shape_plan_destroy (shape_plan);
   956   hb_shape_plan_destroy (shape_plan);
   910 }
   957 }