src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hangul.cc
changeset 48274 51772bf1fb0c
parent 47216 71c04702a3d5
child 50826 f5b95be8b6e2
equal deleted inserted replaced
48273:e2065f7505eb 48274:51772bf1fb0c
    30 /* Hangul shaper */
    30 /* Hangul shaper */
    31 
    31 
    32 
    32 
    33 /* Same order as the feature array below */
    33 /* Same order as the feature array below */
    34 enum {
    34 enum {
    35   NONE,
    35   _JMO,
    36 
    36 
    37   LJMO,
    37   LJMO,
    38   VJMO,
    38   VJMO,
    39   TJMO,
    39   TJMO,
    40 
    40 
    78 static void *
    78 static void *
    79 data_create_hangul (const hb_ot_shape_plan_t *plan)
    79 data_create_hangul (const hb_ot_shape_plan_t *plan)
    80 {
    80 {
    81   hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t));
    81   hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t));
    82   if (unlikely (!hangul_plan))
    82   if (unlikely (!hangul_plan))
    83     return NULL;
    83     return nullptr;
    84 
    84 
    85   for (unsigned int i = 0; i < HANGUL_FEATURE_COUNT; i++)
    85   for (unsigned int i = 0; i < HANGUL_FEATURE_COUNT; i++)
    86     hangul_plan->mask_array[i] = plan->map.get_1_mask (hangul_features[i]);
    86     hangul_plan->mask_array[i] = plan->map.get_1_mask (hangul_features[i]);
    87 
    87 
    88   return hangul_plan;
    88   return hangul_plan;
   103 #define TCount 28u
   103 #define TCount 28u
   104 #define SBase 0xAC00u
   104 #define SBase 0xAC00u
   105 #define NCount (VCount * TCount)
   105 #define NCount (VCount * TCount)
   106 #define SCount (LCount * NCount)
   106 #define SCount (LCount * NCount)
   107 
   107 
   108 #define isCombiningL(u) (hb_in_range ((u), LBase, LBase+LCount-1))
   108 #define isCombiningL(u) (hb_in_range<hb_codepoint_t> ((u), LBase, LBase+LCount-1))
   109 #define isCombiningV(u) (hb_in_range ((u), VBase, VBase+VCount-1))
   109 #define isCombiningV(u) (hb_in_range<hb_codepoint_t> ((u), VBase, VBase+VCount-1))
   110 #define isCombiningT(u) (hb_in_range ((u), TBase+1, TBase+TCount-1))
   110 #define isCombiningT(u) (hb_in_range<hb_codepoint_t> ((u), TBase+1, TBase+TCount-1))
   111 #define isCombinedS(u) (hb_in_range ((u), SBase, SBase+SCount-1))
   111 #define isCombinedS(u) (hb_in_range<hb_codepoint_t> ((u), SBase, SBase+SCount-1))
   112 
   112 
   113 #define isL(u) (hb_in_ranges ((u), 0x1100u, 0x115Fu, 0xA960u, 0xA97Cu))
   113 #define isL(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1100u, 0x115Fu, 0xA960u, 0xA97Cu))
   114 #define isV(u) (hb_in_ranges ((u), 0x1160u, 0x11A7u, 0xD7B0u, 0xD7C6u))
   114 #define isV(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1160u, 0x11A7u, 0xD7B0u, 0xD7C6u))
   115 #define isT(u) (hb_in_ranges ((u), 0x11A8u, 0x11FFu, 0xD7CBu, 0xD7FBu))
   115 #define isT(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x11A8u, 0x11FFu, 0xD7CBu, 0xD7FBu))
   116 
   116 
   117 #define isHangulTone(u) (hb_in_range ((u), 0x302Eu, 0x302Fu))
   117 #define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302Eu, 0x302Fu))
   118 
   118 
   119 /* buffer var allocations */
   119 /* buffer var allocations */
   120 #define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
   120 #define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
   121 
   121 
   122 static bool
   122 static bool
   200        * I didn't bother for now.
   200        * I didn't bother for now.
   201        */
   201        */
   202       if (start < end && end == buffer->out_len)
   202       if (start < end && end == buffer->out_len)
   203       {
   203       {
   204         /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
   204         /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
       
   205         buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
   205         buffer->next_glyph ();
   206         buffer->next_glyph ();
   206         if (!is_zero_width_char (font, u))
   207         if (!is_zero_width_char (font, u))
   207         {
   208         {
   208           buffer->merge_out_clusters (start, end + 1);
   209           buffer->merge_out_clusters (start, end + 1);
   209           hb_glyph_info_t *info = buffer->out_info;
   210           hb_glyph_info_t *info = buffer->out_info;
   256           if (isT (t))
   257           if (isT (t))
   257             tindex = t - TBase; /* Only used if isCombiningT (t); otherwise invalid. */
   258             tindex = t - TBase; /* Only used if isCombiningT (t); otherwise invalid. */
   258           else
   259           else
   259             t = 0; /* The next character was not a trailing jamo. */
   260             t = 0; /* The next character was not a trailing jamo. */
   260         }
   261         }
       
   262         buffer->unsafe_to_break (buffer->idx, buffer->idx + (t ? 3 : 2));
   261 
   263 
   262         /* We've got a syllable <L,V,T?>; see if it can potentially be composed. */
   264         /* We've got a syllable <L,V,T?>; see if it can potentially be composed. */
   263         if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t)))
   265         if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t)))
   264         {
   266         {
   265           /* Try to compose; if this succeeds, end is set to start+1. */
   267           /* Try to compose; if this succeeds, end is set to start+1. */
   320           if (unlikely (buffer->in_error))
   322           if (unlikely (buffer->in_error))
   321             return;
   323             return;
   322           end = start + 1;
   324           end = start + 1;
   323           continue;
   325           continue;
   324         }
   326         }
       
   327         else
       
   328           buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); /* Mark unsafe between LV and T. */
   325       }
   329       }
   326 
   330 
   327       /* Otherwise, decompose if font doesn't support <LV> or <LVT>,
   331       /* Otherwise, decompose if font doesn't support <LV> or <LVT>,
   328        * or if having non-combining <LV,T>.  Note that we already handled
   332        * or if having non-combining <LV,T>.  Note that we already handled
   329        * combining <LV,T> above. */
   333        * combining <LV,T> above. */
   366             info[i++].hangul_shaping_feature() = TJMO;
   370             info[i++].hangul_shaping_feature() = TJMO;
   367           if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
   371           if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
   368             buffer->merge_out_clusters (start, end);
   372             buffer->merge_out_clusters (start, end);
   369           continue;
   373           continue;
   370         }
   374         }
       
   375         else if ((!tindex && buffer->idx + 1 < count && isT (buffer->cur(+1).codepoint)))
       
   376           buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); /* Mark unsafe between LV and T. */
   371       }
   377       }
   372 
   378 
   373       if (has_glyph)
   379       if (has_glyph)
   374       {
   380       {
   375         /* We didn't decompose the S, so just advance past it. */
   381         /* We didn't decompose the S, so just advance past it. */
   406 }
   412 }
   407 
   413 
   408 
   414 
   409 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
   415 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
   410 {
   416 {
   411   "hangul",
       
   412   collect_features_hangul,
   417   collect_features_hangul,
   413   override_features_hangul,
   418   override_features_hangul,
   414   data_create_hangul,
   419   data_create_hangul,
   415   data_destroy_hangul,
   420   data_destroy_hangul,
   416   preprocess_text_hangul,
   421   preprocess_text_hangul,
   417   NULL, /* postprocess_glyphs */
   422   nullptr, /* postprocess_glyphs */
   418   HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
   423   HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
   419   NULL, /* decompose */
   424   nullptr, /* decompose */
   420   NULL, /* compose */
   425   nullptr, /* compose */
   421   setup_masks_hangul,
   426   setup_masks_hangul,
   422   NULL, /* disable_otl */
   427   nullptr, /* disable_otl */
       
   428   nullptr, /* reorder_marks */
   423   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   429   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   424   false, /* fallback_position */
   430   false, /* fallback_position */
   425 };
   431 };