src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-fallback.hh
changeset 54232 7c11a7cc7c1d
parent 50352 25db2c8f3cf8
equal deleted inserted replaced
54231:e4813eded7cb 54232:7c11a7cc7c1d
    25  */
    25  */
    26 
    26 
    27 #ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
    27 #ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
    28 #define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
    28 #define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
    29 
    29 
    30 #include "hb-private.hh"
    30 #include "hb.hh"
    31 
    31 
    32 #include "hb-ot-shape-private.hh"
    32 #include "hb-ot-shape.hh"
    33 #include "hb-ot-layout-gsub-table.hh"
    33 #include "hb-ot-layout-gsub-table.hh"
    34 
    34 
    35 
    35 
    36 /* Features ordered the same as the entries in shaping_table rows,
    36 /* Features ordered the same as the entries in shaping_table rows,
    37  * followed by rlig.  Don't change. */
    37  * followed by rlig.  Don't change. */
    77 
    77 
    78   /* Bubble-sort or something equally good!
    78   /* Bubble-sort or something equally good!
    79    * May not be good-enough for presidential candidate interviews, but good-enough for us... */
    79    * May not be good-enough for presidential candidate interviews, but good-enough for us... */
    80   hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]);
    80   hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]);
    81 
    81 
    82   OT::Supplier<OT::GlyphID> glyphs_supplier      (glyphs, num_glyphs);
       
    83   OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
       
    84 
    82 
    85   /* Each glyph takes four bytes max, and there's some overhead. */
    83   /* Each glyph takes four bytes max, and there's some overhead. */
    86   char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
    84   char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
    87   OT::hb_serialize_context_t c (buf, sizeof (buf));
    85   hb_serialize_context_t c (buf, sizeof (buf));
    88   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
    86   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
    89   bool ret = lookup->serialize_single (&c,
    87   bool ret = lookup->serialize_single (&c,
    90                                        OT::LookupFlag::IgnoreMarks,
    88                                        OT::LookupFlag::IgnoreMarks,
    91                                        glyphs_supplier,
    89                                        hb_array (glyphs, num_glyphs),
    92                                        substitutes_supplier,
    90                                        hb_array (substitutes, num_glyphs));
    93                                        num_glyphs);
       
    94   c.end_serialize ();
    91   c.end_serialize ();
    95   /* TODO sanitize the results? */
    92   /* TODO sanitize the results? */
    96 
    93 
    97   return ret ? c.copy<OT::SubstLookup> () : nullptr;
    94   return ret ? c.copy<OT::SubstLookup> () : nullptr;
    98 }
    95 }
   153   }
   150   }
   154 
   151 
   155   if (!num_ligatures)
   152   if (!num_ligatures)
   156     return nullptr;
   153     return nullptr;
   157 
   154 
   158   OT::Supplier<OT::GlyphID>   first_glyphs_supplier                      (first_glyphs, num_first_glyphs);
       
   159   OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier    (ligature_per_first_glyph_count_list, num_first_glyphs);
       
   160   OT::Supplier<OT::GlyphID>   ligatures_supplier                         (ligature_list, num_ligatures);
       
   161   OT::Supplier<unsigned int > component_count_supplier                   (component_count_list, num_ligatures);
       
   162   OT::Supplier<OT::GlyphID>   component_supplier                         (component_list, num_ligatures);
       
   163 
   155 
   164   /* 16 bytes per ligature ought to be enough... */
   156   /* 16 bytes per ligature ought to be enough... */
   165   char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
   157   char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
   166   OT::hb_serialize_context_t c (buf, sizeof (buf));
   158   hb_serialize_context_t c (buf, sizeof (buf));
   167   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
   159   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
   168   bool ret = lookup->serialize_ligature (&c,
   160   bool ret = lookup->serialize_ligature (&c,
   169                                          OT::LookupFlag::IgnoreMarks,
   161                                          OT::LookupFlag::IgnoreMarks,
   170                                          first_glyphs_supplier,
   162                                          hb_array (first_glyphs, num_first_glyphs),
   171                                          ligature_per_first_glyph_count_supplier,
   163                                          hb_array (ligature_per_first_glyph_count_list, num_first_glyphs),
   172                                          num_first_glyphs,
   164                                          hb_array (ligature_list, num_ligatures),
   173                                          ligatures_supplier,
   165                                          hb_array (component_count_list, num_ligatures),
   174                                          component_count_supplier,
   166                                          hb_array (component_list, num_ligatures));
   175                                          component_supplier);
       
   176 
       
   177   c.end_serialize ();
   167   c.end_serialize ();
   178   /* TODO sanitize the results? */
   168   /* TODO sanitize the results? */
   179 
   169 
   180   return ret ? c.copy<OT::SubstLookup> () : nullptr;
   170   return ret ? c.copy<OT::SubstLookup> () : nullptr;
   181 }
   171 }
   193 
   183 
   194 #define ARABIC_FALLBACK_MAX_LOOKUPS 5
   184 #define ARABIC_FALLBACK_MAX_LOOKUPS 5
   195 
   185 
   196 struct arabic_fallback_plan_t
   186 struct arabic_fallback_plan_t
   197 {
   187 {
   198   ASSERT_POD ();
       
   199 
       
   200   unsigned int num_lookups;
   188   unsigned int num_lookups;
   201   bool free_lookups;
   189   bool free_lookups;
   202 
   190 
   203   hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
   191   hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
   204   OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
   192   OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
   205   hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
   193   OT::hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
   206 };
   194 };
   207 
   195 
   208 static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
   196 #if defined(_WIN32) && !defined(HB_NO_WIN1256)
   209 
       
   210 #if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256)
       
   211 #define HB_WITH_WIN1256
   197 #define HB_WITH_WIN1256
   212 #endif
   198 #endif
   213 
   199 
   214 #ifdef HB_WITH_WIN1256
   200 #ifdef HB_WITH_WIN1256
   215 #include "hb-ot-shape-complex-arabic-win1256.hh"
   201 #include "hb-ot-shape-complex-arabic-win1256.hh"
   216 #endif
   202 #endif
   217 
   203 
   218 struct ManifestLookup {
   204 struct ManifestLookup
       
   205 {
       
   206   public:
   219   OT::Tag tag;
   207   OT::Tag tag;
   220   OT::OffsetTo<OT::SubstLookup> lookupOffset;
   208   OT::OffsetTo<OT::SubstLookup> lookupOffset;
       
   209   public:
       
   210   DEFINE_SIZE_STATIC (6);
   221 };
   211 };
   222 typedef OT::ArrayOf<ManifestLookup> Manifest;
   212 typedef OT::ArrayOf<ManifestLookup> Manifest;
   223 
   213 
   224 static bool
   214 static bool
   225 arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan,
   215 arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUSED,
   226                                    const hb_ot_shape_plan_t *plan,
   216                                    const hb_ot_shape_plan_t *plan HB_UNUSED,
   227                                    hb_font_t *font)
   217                                    hb_font_t *font HB_UNUSED)
   228 {
   218 {
   229 #ifdef HB_WITH_WIN1256
   219 #ifdef HB_WITH_WIN1256
   230   /* Does this font look like it's Windows-1256-encoded? */
   220   /* Does this font look like it's Windows-1256-encoded? */
   231   hb_codepoint_t g;
   221   hb_codepoint_t g;
   232   if (!(hb_font_get_glyph (font, 0x0627u, 0, &g) && g == 199 /* ALEF */ &&
   222   if (!(hb_font_get_glyph (font, 0x0627u, 0, &g) && g == 199 /* ALEF */ &&
   297 arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
   287 arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
   298                              hb_font_t *font)
   288                              hb_font_t *font)
   299 {
   289 {
   300   arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
   290   arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
   301   if (unlikely (!fallback_plan))
   291   if (unlikely (!fallback_plan))
   302     return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
   292     return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t));
   303 
   293 
   304   fallback_plan->num_lookups = 0;
   294   fallback_plan->num_lookups = 0;
   305   fallback_plan->free_lookups = false;
   295   fallback_plan->free_lookups = false;
   306 
   296 
   307   /* Try synthesizing GSUB table using Unicode Arabic Presentation Forms,
   297   /* Try synthesizing GSUB table using Unicode Arabic Presentation Forms,
   312   /* See if this looks like a Windows-1256-encoded font.  If it does, use a
   302   /* See if this looks like a Windows-1256-encoded font.  If it does, use a
   313    * hand-coded GSUB table. */
   303    * hand-coded GSUB table. */
   314   if (arabic_fallback_plan_init_win1256 (fallback_plan, plan, font))
   304   if (arabic_fallback_plan_init_win1256 (fallback_plan, plan, font))
   315     return fallback_plan;
   305     return fallback_plan;
   316 
   306 
       
   307   assert (fallback_plan->num_lookups == 0);
   317   free (fallback_plan);
   308   free (fallback_plan);
   318   return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
   309   return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t));
   319 }
   310 }
   320 
   311 
   321 static void
   312 static void
   322 arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
   313 arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
   323 {
   314 {
   324   if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
   315   if (!fallback_plan || fallback_plan->num_lookups == 0)
   325     return;
   316     return;
   326 
   317 
   327   for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
   318   for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
   328     if (fallback_plan->lookup_array[i])
   319     if (fallback_plan->lookup_array[i])
   329     {
   320     {