jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.cc
changeset 40435 553eb1a50733
parent 34414 e496a8d8fc8a
child 43232 8e39ad39979f
equal deleted inserted replaced
40434:49d6193f196f 40435:553eb1a50733
    68 
    68 
    69 struct hb_ft_font_t
    69 struct hb_ft_font_t
    70 {
    70 {
    71   FT_Face ft_face;
    71   FT_Face ft_face;
    72   int load_flags;
    72   int load_flags;
       
    73   bool symbol; /* Whether selected cmap is symbol cmap. */
    73   bool unref; /* Whether to destroy ft_face when done. */
    74   bool unref; /* Whether to destroy ft_face when done. */
    74 };
    75 };
    75 
    76 
    76 static hb_ft_font_t *
    77 static hb_ft_font_t *
    77 _hb_ft_font_create (FT_Face ft_face, bool unref)
    78 _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
    78 {
    79 {
    79   hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t));
    80   hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t));
    80 
    81 
    81   if (unlikely (!ft_font))
    82   if (unlikely (!ft_font))
    82     return NULL;
    83     return NULL;
    83 
    84 
    84   ft_font->ft_face = ft_face;
    85   ft_font->ft_face = ft_face;
       
    86   ft_font->symbol = symbol;
    85   ft_font->unref = unref;
    87   ft_font->unref = unref;
    86 
    88 
    87   ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
    89   ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
    88 
    90 
    89   return ft_font;
    91   return ft_font;
       
    92 }
       
    93 
       
    94 static void
       
    95 _hb_ft_face_destroy (FT_Face ft_face)
       
    96 {
       
    97   FT_Done_Face (ft_face);
    90 }
    98 }
    91 
    99 
    92 static void
   100 static void
    93 _hb_ft_font_destroy (hb_ft_font_t *ft_font)
   101 _hb_ft_font_destroy (hb_ft_font_t *ft_font)
    94 {
   102 {
    95   if (ft_font->unref)
   103   if (ft_font->unref)
    96     FT_Done_Face (ft_font->ft_face);
   104     _hb_ft_face_destroy (ft_font->ft_face);
    97 
   105 
    98   free (ft_font);
   106   free (ft_font);
    99 }
   107 }
   100 
   108 
   101 /**
   109 /**
   153 }
   161 }
   154 
   162 
   155 
   163 
   156 
   164 
   157 static hb_bool_t
   165 static hb_bool_t
   158 hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
   166 hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
   159                  void *font_data,
   167                          void *font_data,
   160                  hb_codepoint_t unicode,
   168                          hb_codepoint_t unicode,
   161                  hb_codepoint_t variation_selector,
   169                          hb_codepoint_t *glyph,
   162                  hb_codepoint_t *glyph,
   170                          void *user_data HB_UNUSED)
   163                  void *user_data HB_UNUSED)
   171 {
   164 
   172   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
   165 {
   173   unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode);
   166   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
   174 
   167   unsigned int g;
   175   if (unlikely (!g))
   168 
   176   {
   169   if (likely (!variation_selector))
   177     if (unlikely (ft_font->symbol) && unicode <= 0x00FFu)
   170     g = FT_Get_Char_Index (ft_font->ft_face, unicode);
   178     {
   171   else
   179       /* For symbol-encoded OpenType fonts, we duplicate the
   172     g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
   180        * U+F000..F0FF range at U+0000..U+00FF.  That's what
       
   181        * Windows seems to do, and that's hinted about at:
       
   182        * http://www.microsoft.com/typography/otspec/recom.htm
       
   183        * under "Non-Standard (Symbol) Fonts". */
       
   184       g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode);
       
   185       if (!g)
       
   186         return false;
       
   187     }
       
   188     else
       
   189       return false;
       
   190   }
       
   191 
       
   192   *glyph = g;
       
   193   return true;
       
   194 }
       
   195 
       
   196 static hb_bool_t
       
   197 hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
       
   198                            void *font_data,
       
   199                            hb_codepoint_t unicode,
       
   200                            hb_codepoint_t variation_selector,
       
   201                            hb_codepoint_t *glyph,
       
   202                            void *user_data HB_UNUSED)
       
   203 {
       
   204   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
       
   205   unsigned int g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
   173 
   206 
   174   if (unlikely (!g))
   207   if (unlikely (!g))
   175     return false;
   208     return false;
   176 
   209 
   177   *glyph = g;
   210   *glyph = g;
   212     v = -v;
   245     v = -v;
   213 
   246 
   214   /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
   247   /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
   215    * have a Y growing upward.  Hence the extra negation. */
   248    * have a Y growing upward.  Hence the extra negation. */
   216   return (-v + (1<<9)) >> 10;
   249   return (-v + (1<<9)) >> 10;
   217 }
       
   218 
       
   219 static hb_bool_t
       
   220 hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
       
   221                           void *font_data HB_UNUSED,
       
   222                           hb_codepoint_t glyph HB_UNUSED,
       
   223                           hb_position_t *x HB_UNUSED,
       
   224                           hb_position_t *y HB_UNUSED,
       
   225                           void *user_data HB_UNUSED)
       
   226 {
       
   227   /* We always work in the horizontal coordinates. */
       
   228   return true;
       
   229 }
   250 }
   230 
   251 
   231 static hb_bool_t
   252 static hb_bool_t
   232 hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
   253 hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
   233                           void *font_data,
   254                           void *font_data,
   270     return 0;
   291     return 0;
   271 
   292 
   272   return kerningv.x;
   293   return kerningv.x;
   273 }
   294 }
   274 
   295 
   275 static hb_position_t
       
   276 hb_ft_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
       
   277                            void *font_data HB_UNUSED,
       
   278                            hb_codepoint_t top_glyph HB_UNUSED,
       
   279                            hb_codepoint_t bottom_glyph HB_UNUSED,
       
   280                            void *user_data HB_UNUSED)
       
   281 {
       
   282   /* FreeType API doesn't support vertical kerning */
       
   283   return 0;
       
   284 }
       
   285 
       
   286 static hb_bool_t
   296 static hb_bool_t
   287 hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
   297 hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
   288                          void *font_data,
   298                          void *font_data,
   289                          hb_codepoint_t glyph,
   299                          hb_codepoint_t glyph,
   290                          hb_glyph_extents_t *extents,
   300                          hb_glyph_extents_t *extents,
   298 
   308 
   299   extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
   309   extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
   300   extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
   310   extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
   301   extents->width = ft_face->glyph->metrics.width;
   311   extents->width = ft_face->glyph->metrics.width;
   302   extents->height = -ft_face->glyph->metrics.height;
   312   extents->height = -ft_face->glyph->metrics.height;
       
   313   if (font->x_scale < 0)
       
   314   {
       
   315     extents->x_bearing = -extents->x_bearing;
       
   316     extents->width = -extents->width;
       
   317   }
       
   318   if (font->y_scale < 0)
       
   319   {
       
   320     extents->y_bearing = -extents->y_bearing;
       
   321     extents->height = -extents->height;
       
   322   }
   303   return true;
   323   return true;
   304 }
   324 }
   305 
   325 
   306 static hb_bool_t
   326 static hb_bool_t
   307 hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
   327 hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
   377   }
   397   }
   378 
   398 
   379   return *glyph != 0;
   399   return *glyph != 0;
   380 }
   400 }
   381 
   401 
       
   402 static hb_bool_t
       
   403 hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
       
   404                           void *font_data,
       
   405                           hb_font_extents_t *metrics,
       
   406                           void *user_data HB_UNUSED)
       
   407 {
       
   408   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
       
   409   FT_Face ft_face = ft_font->ft_face;
       
   410   metrics->ascender = ft_face->size->metrics.ascender;
       
   411   metrics->descender = ft_face->size->metrics.descender;
       
   412   metrics->line_gap = ft_face->size->metrics.height - (ft_face->size->metrics.ascender - ft_face->size->metrics.descender);
       
   413   if (font->y_scale < 0)
       
   414   {
       
   415     metrics->ascender = -metrics->ascender;
       
   416     metrics->descender = -metrics->descender;
       
   417     metrics->line_gap = -metrics->line_gap;
       
   418   }
       
   419   return true;
       
   420 }
       
   421 
       
   422 static hb_font_funcs_t *static_ft_funcs = NULL;
       
   423 
       
   424 #ifdef HB_USE_ATEXIT
       
   425 static
       
   426 void free_static_ft_funcs (void)
       
   427 {
       
   428   hb_font_funcs_destroy (static_ft_funcs);
       
   429 }
       
   430 #endif
   382 
   431 
   383 static void
   432 static void
   384 _hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
   433 _hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
   385 {
   434 {
   386   static const hb_font_funcs_t ft_ffuncs = {
   435 retry:
   387     HB_OBJECT_HEADER_STATIC,
   436   hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ft_funcs);
   388 
   437 
   389     true, /* immutable */
   438   if (unlikely (!funcs))
   390 
   439   {
   391     {
   440     funcs = hb_font_funcs_create ();
   392 #define HB_FONT_FUNC_IMPLEMENT(name) hb_ft_get_##name,
   441 
   393       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
   442     hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, NULL, NULL);
   394 #undef HB_FONT_FUNC_IMPLEMENT
   443     //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, NULL, NULL);
       
   444     hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, NULL, NULL);
       
   445     hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, NULL, NULL);
       
   446     hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, NULL, NULL);
       
   447     hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, NULL, NULL);
       
   448     //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, NULL, NULL);
       
   449     hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, NULL, NULL);
       
   450     hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, NULL, NULL);
       
   451     //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, NULL, NULL);
       
   452     hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, NULL, NULL);
       
   453     hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, NULL, NULL);
       
   454     hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, NULL, NULL);
       
   455     hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, NULL, NULL);
       
   456 
       
   457     hb_font_funcs_make_immutable (funcs);
       
   458 
       
   459     if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, NULL, funcs)) {
       
   460       hb_font_funcs_destroy (funcs);
       
   461       goto retry;
   395     }
   462     }
       
   463 
       
   464 #ifdef HB_USE_ATEXIT
       
   465     atexit (free_static_ft_funcs); /* First person registers atexit() callback. */
       
   466 #endif
   396   };
   467   };
   397 
   468 
       
   469   bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
       
   470 
   398   hb_font_set_funcs (font,
   471   hb_font_set_funcs (font,
   399                      const_cast<hb_font_funcs_t *> (&ft_ffuncs),
   472                      funcs,
   400                      _hb_ft_font_create (ft_face, unref),
   473                      _hb_ft_font_create (ft_face, symbol, unref),
   401                      (hb_destroy_func_t) _hb_ft_font_destroy);
   474                      (hb_destroy_func_t) _hb_ft_font_destroy);
   402 }
   475 }
   403 
   476 
   404 
   477 
   405 static hb_blob_t *
   478 static hb_blob_t *
   475  **/
   548  **/
   476 hb_face_t *
   549 hb_face_t *
   477 hb_ft_face_create_referenced (FT_Face ft_face)
   550 hb_ft_face_create_referenced (FT_Face ft_face)
   478 {
   551 {
   479   FT_Reference_Face (ft_face);
   552   FT_Reference_Face (ft_face);
   480   return hb_ft_face_create (ft_face, (hb_destroy_func_t) FT_Done_Face);
   553   return hb_ft_face_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy);
   481 }
   554 }
   482 
   555 
   483 static void
   556 static void
   484 hb_ft_face_finalize (FT_Face ft_face)
   557 hb_ft_face_finalize (FT_Face ft_face)
   485 {
   558 {
   555  **/
   628  **/
   556 hb_font_t *
   629 hb_font_t *
   557 hb_ft_font_create_referenced (FT_Face ft_face)
   630 hb_ft_font_create_referenced (FT_Face ft_face)
   558 {
   631 {
   559   FT_Reference_Face (ft_face);
   632   FT_Reference_Face (ft_face);
   560   return hb_ft_font_create (ft_face, (hb_destroy_func_t) FT_Done_Face);
   633   return hb_ft_font_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy);
   561 }
   634 }
   562 
   635 
   563 
   636 
   564 /* Thread-safe, lock-free, FT_Library */
   637 /* Thread-safe, lock-free, FT_Library */
   565 
   638 
   624     hb_blob_destroy (blob);
   697     hb_blob_destroy (blob);
   625     DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed");
   698     DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed");
   626     return;
   699     return;
   627   }
   700   }
   628 
   701 
   629   FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
   702   if (FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE))
       
   703     FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL);
   630 
   704 
   631   FT_Set_Char_Size (ft_face,
   705   FT_Set_Char_Size (ft_face,
   632                     abs (font->x_scale), abs (font->y_scale),
   706                     abs (font->x_scale), abs (font->y_scale),
   633                     0, 0);
   707                     0, 0);
   634 #if 0
   708 #if 0