src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font-private.hh
changeset 54232 7c11a7cc7c1d
parent 54231 e4813eded7cb
child 54233 9413f1a4dc2b
equal deleted inserted replaced
54231:e4813eded7cb 54232:7c11a7cc7c1d
     1 /*
       
     2  * Copyright © 2009  Red Hat, Inc.
       
     3  * Copyright © 2011  Google, Inc.
       
     4  *
       
     5  *  This is part of HarfBuzz, a text shaping library.
       
     6  *
       
     7  * Permission is hereby granted, without written agreement and without
       
     8  * license or royalty fees, to use, copy, modify, and distribute this
       
     9  * software and its documentation for any purpose, provided that the
       
    10  * above copyright notice and the following two paragraphs appear in
       
    11  * all copies of this software.
       
    12  *
       
    13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
       
    14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
       
    15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
       
    16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
       
    17  * DAMAGE.
       
    18  *
       
    19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
       
    20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
       
    21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
       
    22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
       
    23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
       
    24  *
       
    25  * Red Hat Author(s): Behdad Esfahbod
       
    26  * Google Author(s): Behdad Esfahbod
       
    27  */
       
    28 
       
    29 #ifndef HB_FONT_PRIVATE_HH
       
    30 #define HB_FONT_PRIVATE_HH
       
    31 
       
    32 #include "hb-private.hh"
       
    33 
       
    34 #include "hb-object-private.hh"
       
    35 #include "hb-face-private.hh"
       
    36 #include "hb-shaper-private.hh"
       
    37 
       
    38 
       
    39 
       
    40 /*
       
    41  * hb_font_funcs_t
       
    42  */
       
    43 
       
    44 #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
       
    45   HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
       
    46   HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
       
    47   HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
       
    48   HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
       
    49   HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
       
    50   HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
       
    51   HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
       
    52   HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
       
    53   HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
       
    54   HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
       
    55   HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
       
    56   HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
       
    57   HB_FONT_FUNC_IMPLEMENT (glyph_name) \
       
    58   HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
       
    59   /* ^--- Add new callbacks here */
       
    60 
       
    61 struct hb_font_funcs_t {
       
    62   hb_object_header_t header;
       
    63   ASSERT_POD ();
       
    64 
       
    65   hb_bool_t immutable;
       
    66 
       
    67   struct {
       
    68 #define HB_FONT_FUNC_IMPLEMENT(name) void *name;
       
    69     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
       
    70 #undef HB_FONT_FUNC_IMPLEMENT
       
    71   } user_data;
       
    72 
       
    73   struct {
       
    74 #define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
       
    75     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
       
    76 #undef HB_FONT_FUNC_IMPLEMENT
       
    77   } destroy;
       
    78 
       
    79   /* Don't access these directly.  Call font->get_*() instead. */
       
    80   union get_t {
       
    81     struct get_funcs_t {
       
    82 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
       
    83       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
       
    84 #undef HB_FONT_FUNC_IMPLEMENT
       
    85     } f;
       
    86     void (*array[0
       
    87 #define HB_FONT_FUNC_IMPLEMENT(name) +1
       
    88       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
       
    89 #undef HB_FONT_FUNC_IMPLEMENT
       
    90                 ]) (void);
       
    91   } get;
       
    92 };
       
    93 
       
    94 
       
    95 
       
    96 /*
       
    97  * hb_font_t
       
    98  */
       
    99 
       
   100 struct hb_font_t {
       
   101   hb_object_header_t header;
       
   102   ASSERT_POD ();
       
   103 
       
   104   hb_bool_t immutable;
       
   105 
       
   106   hb_font_t *parent;
       
   107   hb_face_t *face;
       
   108 
       
   109   int x_scale;
       
   110   int y_scale;
       
   111 
       
   112   unsigned int x_ppem;
       
   113   unsigned int y_ppem;
       
   114 
       
   115   float ptem;
       
   116 
       
   117   /* Font variation coordinates. */
       
   118   unsigned int num_coords;
       
   119   int *coords;
       
   120 
       
   121   hb_font_funcs_t   *klass;
       
   122   void              *user_data;
       
   123   hb_destroy_func_t  destroy;
       
   124 
       
   125   struct hb_shaper_data_t shaper_data;
       
   126 
       
   127 
       
   128   /* Convert from font-space to user-space */
       
   129   inline int dir_scale (hb_direction_t direction)
       
   130   { return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
       
   131   inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
       
   132   inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
       
   133   inline hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
       
   134   inline hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
       
   135   inline float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
       
   136   inline float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
       
   137   inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
       
   138   { return em_scale (v, dir_scale (direction)); }
       
   139 
       
   140   /* Convert from parent-font user-space to our user-space */
       
   141   inline hb_position_t parent_scale_x_distance (hb_position_t v) {
       
   142     if (unlikely (parent && parent->x_scale != x_scale))
       
   143       return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
       
   144     return v;
       
   145   }
       
   146   inline hb_position_t parent_scale_y_distance (hb_position_t v) {
       
   147     if (unlikely (parent && parent->y_scale != y_scale))
       
   148       return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
       
   149     return v;
       
   150   }
       
   151   inline hb_position_t parent_scale_x_position (hb_position_t v) {
       
   152     return parent_scale_x_distance (v);
       
   153   }
       
   154   inline hb_position_t parent_scale_y_position (hb_position_t v) {
       
   155     return parent_scale_y_distance (v);
       
   156   }
       
   157 
       
   158   inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
       
   159     *x = parent_scale_x_distance (*x);
       
   160     *y = parent_scale_y_distance (*y);
       
   161   }
       
   162   inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
       
   163     *x = parent_scale_x_position (*x);
       
   164     *y = parent_scale_y_position (*y);
       
   165   }
       
   166 
       
   167 
       
   168   /* Public getters */
       
   169 
       
   170   HB_INTERNAL bool has_func (unsigned int i);
       
   171 
       
   172   /* has_* ... */
       
   173 #define HB_FONT_FUNC_IMPLEMENT(name) \
       
   174   bool \
       
   175   has_##name##_func (void) \
       
   176   { \
       
   177     hb_font_funcs_t *funcs = this->klass; \
       
   178     unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
       
   179     return has_func (i); \
       
   180   }
       
   181   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
       
   182 #undef HB_FONT_FUNC_IMPLEMENT
       
   183 
       
   184   inline hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
       
   185   {
       
   186     memset (extents, 0, sizeof (*extents));
       
   187     return klass->get.f.font_h_extents (this, user_data,
       
   188                                         extents,
       
   189                                         klass->user_data.font_h_extents);
       
   190   }
       
   191   inline hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
       
   192   {
       
   193     memset (extents, 0, sizeof (*extents));
       
   194     return klass->get.f.font_v_extents (this, user_data,
       
   195                                         extents,
       
   196                                         klass->user_data.font_v_extents);
       
   197   }
       
   198 
       
   199   inline bool has_glyph (hb_codepoint_t unicode)
       
   200   {
       
   201     hb_codepoint_t glyph;
       
   202     return get_nominal_glyph (unicode, &glyph);
       
   203   }
       
   204 
       
   205   inline hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
       
   206                                       hb_codepoint_t *glyph)
       
   207   {
       
   208     *glyph = 0;
       
   209     return klass->get.f.nominal_glyph (this, user_data,
       
   210                                        unicode, glyph,
       
   211                                        klass->user_data.nominal_glyph);
       
   212   }
       
   213 
       
   214   inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
       
   215                                         hb_codepoint_t *glyph)
       
   216   {
       
   217     *glyph = 0;
       
   218     return klass->get.f.variation_glyph (this, user_data,
       
   219                                          unicode, variation_selector, glyph,
       
   220                                          klass->user_data.variation_glyph);
       
   221   }
       
   222 
       
   223   inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
       
   224   {
       
   225     return klass->get.f.glyph_h_advance (this, user_data,
       
   226                                          glyph,
       
   227                                          klass->user_data.glyph_h_advance);
       
   228   }
       
   229 
       
   230   inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
       
   231   {
       
   232     return klass->get.f.glyph_v_advance (this, user_data,
       
   233                                          glyph,
       
   234                                          klass->user_data.glyph_v_advance);
       
   235   }
       
   236 
       
   237   inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
       
   238                                        hb_position_t *x, hb_position_t *y)
       
   239   {
       
   240     *x = *y = 0;
       
   241     return klass->get.f.glyph_h_origin (this, user_data,
       
   242                                         glyph, x, y,
       
   243                                         klass->user_data.glyph_h_origin);
       
   244   }
       
   245 
       
   246   inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
       
   247                                        hb_position_t *x, hb_position_t *y)
       
   248   {
       
   249     *x = *y = 0;
       
   250     return klass->get.f.glyph_v_origin (this, user_data,
       
   251                                         glyph, x, y,
       
   252                                         klass->user_data.glyph_v_origin);
       
   253   }
       
   254 
       
   255   inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
       
   256   {
       
   257     return klass->get.f.glyph_h_kerning (this, user_data,
       
   258                                          left_glyph, right_glyph,
       
   259                                          klass->user_data.glyph_h_kerning);
       
   260   }
       
   261 
       
   262   inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
       
   263   {
       
   264     return klass->get.f.glyph_v_kerning (this, user_data,
       
   265                                          top_glyph, bottom_glyph,
       
   266                                          klass->user_data.glyph_v_kerning);
       
   267   }
       
   268 
       
   269   inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
       
   270                                       hb_glyph_extents_t *extents)
       
   271   {
       
   272     memset (extents, 0, sizeof (*extents));
       
   273     return klass->get.f.glyph_extents (this, user_data,
       
   274                                        glyph,
       
   275                                        extents,
       
   276                                        klass->user_data.glyph_extents);
       
   277   }
       
   278 
       
   279   inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
       
   280                                             hb_position_t *x, hb_position_t *y)
       
   281   {
       
   282     *x = *y = 0;
       
   283     return klass->get.f.glyph_contour_point (this, user_data,
       
   284                                              glyph, point_index,
       
   285                                              x, y,
       
   286                                              klass->user_data.glyph_contour_point);
       
   287   }
       
   288 
       
   289   inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
       
   290                                    char *name, unsigned int size)
       
   291   {
       
   292     if (size) *name = '\0';
       
   293     return klass->get.f.glyph_name (this, user_data,
       
   294                                     glyph,
       
   295                                     name, size,
       
   296                                     klass->user_data.glyph_name);
       
   297   }
       
   298 
       
   299   inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
       
   300                                         hb_codepoint_t *glyph)
       
   301   {
       
   302     *glyph = 0;
       
   303     if (len == -1) len = strlen (name);
       
   304     return klass->get.f.glyph_from_name (this, user_data,
       
   305                                          name, len,
       
   306                                          glyph,
       
   307                                          klass->user_data.glyph_from_name);
       
   308   }
       
   309 
       
   310 
       
   311   /* A bit higher-level, and with fallback */
       
   312 
       
   313   inline void get_h_extents_with_fallback (hb_font_extents_t *extents)
       
   314   {
       
   315     if (!get_font_h_extents (extents))
       
   316     {
       
   317       extents->ascender = y_scale * .8;
       
   318       extents->descender = extents->ascender - y_scale;
       
   319       extents->line_gap = 0;
       
   320     }
       
   321   }
       
   322   inline void get_v_extents_with_fallback (hb_font_extents_t *extents)
       
   323   {
       
   324     if (!get_font_v_extents (extents))
       
   325     {
       
   326       extents->ascender = x_scale / 2;
       
   327       extents->descender = extents->ascender - x_scale;
       
   328       extents->line_gap = 0;
       
   329     }
       
   330   }
       
   331 
       
   332   inline void get_extents_for_direction (hb_direction_t direction,
       
   333                                          hb_font_extents_t *extents)
       
   334   {
       
   335     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
       
   336       get_h_extents_with_fallback (extents);
       
   337     else
       
   338       get_v_extents_with_fallback (extents);
       
   339   }
       
   340 
       
   341   inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
       
   342                                                hb_direction_t direction,
       
   343                                                hb_position_t *x, hb_position_t *y)
       
   344   {
       
   345     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
       
   346       *x = get_glyph_h_advance (glyph);
       
   347       *y = 0;
       
   348     } else {
       
   349       *x = 0;
       
   350       *y = get_glyph_v_advance (glyph);
       
   351     }
       
   352   }
       
   353 
       
   354   inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
       
   355                                              hb_position_t *x, hb_position_t *y)
       
   356   {
       
   357     *x = get_glyph_h_advance (glyph) / 2;
       
   358 
       
   359     /* TODO cache this somehow?! */
       
   360     hb_font_extents_t extents;
       
   361     get_h_extents_with_fallback (&extents);
       
   362     *y = extents.ascender;
       
   363   }
       
   364 
       
   365   inline void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph,
       
   366                                                 hb_position_t *x, hb_position_t *y)
       
   367   {
       
   368     if (!get_glyph_h_origin (glyph, x, y) &&
       
   369          get_glyph_v_origin (glyph, x, y))
       
   370     {
       
   371       hb_position_t dx, dy;
       
   372       guess_v_origin_minus_h_origin (glyph, &dx, &dy);
       
   373       *x -= dx; *y -= dy;
       
   374     }
       
   375   }
       
   376   inline void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph,
       
   377                                                 hb_position_t *x, hb_position_t *y)
       
   378   {
       
   379     if (!get_glyph_v_origin (glyph, x, y) &&
       
   380          get_glyph_h_origin (glyph, x, y))
       
   381     {
       
   382       hb_position_t dx, dy;
       
   383       guess_v_origin_minus_h_origin (glyph, &dx, &dy);
       
   384       *x += dx; *y += dy;
       
   385     }
       
   386   }
       
   387 
       
   388   inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
       
   389                                               hb_direction_t direction,
       
   390                                               hb_position_t *x, hb_position_t *y)
       
   391   {
       
   392     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
       
   393       get_glyph_h_origin_with_fallback (glyph, x, y);
       
   394     else
       
   395       get_glyph_v_origin_with_fallback (glyph, x, y);
       
   396   }
       
   397 
       
   398   inline void add_glyph_h_origin (hb_codepoint_t glyph,
       
   399                                   hb_position_t *x, hb_position_t *y)
       
   400   {
       
   401     hb_position_t origin_x, origin_y;
       
   402 
       
   403     get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
       
   404 
       
   405     *x += origin_x;
       
   406     *y += origin_y;
       
   407   }
       
   408   inline void add_glyph_v_origin (hb_codepoint_t glyph,
       
   409                                   hb_position_t *x, hb_position_t *y)
       
   410   {
       
   411     hb_position_t origin_x, origin_y;
       
   412 
       
   413     get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
       
   414 
       
   415     *x += origin_x;
       
   416     *y += origin_y;
       
   417   }
       
   418   inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
       
   419                                               hb_direction_t direction,
       
   420                                               hb_position_t *x, hb_position_t *y)
       
   421   {
       
   422     hb_position_t origin_x, origin_y;
       
   423 
       
   424     get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
       
   425 
       
   426     *x += origin_x;
       
   427     *y += origin_y;
       
   428   }
       
   429 
       
   430   inline void subtract_glyph_h_origin (hb_codepoint_t glyph,
       
   431                                        hb_position_t *x, hb_position_t *y)
       
   432   {
       
   433     hb_position_t origin_x, origin_y;
       
   434 
       
   435     get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
       
   436 
       
   437     *x -= origin_x;
       
   438     *y -= origin_y;
       
   439   }
       
   440   inline void subtract_glyph_v_origin (hb_codepoint_t glyph,
       
   441                                        hb_position_t *x, hb_position_t *y)
       
   442   {
       
   443     hb_position_t origin_x, origin_y;
       
   444 
       
   445     get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
       
   446 
       
   447     *x -= origin_x;
       
   448     *y -= origin_y;
       
   449   }
       
   450   inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
       
   451                                                    hb_direction_t direction,
       
   452                                                    hb_position_t *x, hb_position_t *y)
       
   453   {
       
   454     hb_position_t origin_x, origin_y;
       
   455 
       
   456     get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
       
   457 
       
   458     *x -= origin_x;
       
   459     *y -= origin_y;
       
   460   }
       
   461 
       
   462   inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
       
   463                                                hb_direction_t direction,
       
   464                                                hb_position_t *x, hb_position_t *y)
       
   465   {
       
   466     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
       
   467       *x = get_glyph_h_kerning (first_glyph, second_glyph);
       
   468       *y = 0;
       
   469     } else {
       
   470       *x = 0;
       
   471       *y = get_glyph_v_kerning (first_glyph, second_glyph);
       
   472     }
       
   473   }
       
   474 
       
   475   inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
       
   476                                                  hb_direction_t direction,
       
   477                                                  hb_glyph_extents_t *extents)
       
   478   {
       
   479     hb_bool_t ret = get_glyph_extents (glyph, extents);
       
   480 
       
   481     if (ret)
       
   482       subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
       
   483 
       
   484     return ret;
       
   485   }
       
   486 
       
   487   inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
       
   488                                                        hb_direction_t direction,
       
   489                                                        hb_position_t *x, hb_position_t *y)
       
   490   {
       
   491     hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
       
   492 
       
   493     if (ret)
       
   494       subtract_glyph_origin_for_direction (glyph, direction, x, y);
       
   495 
       
   496     return ret;
       
   497   }
       
   498 
       
   499   /* Generates gidDDD if glyph has no name. */
       
   500   inline void
       
   501   glyph_to_string (hb_codepoint_t glyph,
       
   502                    char *s, unsigned int size)
       
   503   {
       
   504     if (get_glyph_name (glyph, s, size)) return;
       
   505 
       
   506     if (size && snprintf (s, size, "gid%u", glyph) < 0)
       
   507       *s = '\0';
       
   508   }
       
   509 
       
   510   /* Parses gidDDD and uniUUUU strings automatically. */
       
   511   inline hb_bool_t
       
   512   glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
       
   513                      hb_codepoint_t *glyph)
       
   514   {
       
   515     if (get_glyph_from_name (s, len, glyph)) return true;
       
   516 
       
   517     if (len == -1) len = strlen (s);
       
   518 
       
   519     /* Straight glyph index. */
       
   520     if (hb_codepoint_parse (s, len, 10, glyph))
       
   521       return true;
       
   522 
       
   523     if (len > 3)
       
   524     {
       
   525       /* gidDDD syntax for glyph indices. */
       
   526       if (0 == strncmp (s, "gid", 3) &&
       
   527           hb_codepoint_parse (s + 3, len - 3, 10, glyph))
       
   528         return true;
       
   529 
       
   530       /* uniUUUU and other Unicode character indices. */
       
   531       hb_codepoint_t unichar;
       
   532       if (0 == strncmp (s, "uni", 3) &&
       
   533           hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
       
   534           get_nominal_glyph (unichar, glyph))
       
   535         return true;
       
   536     }
       
   537 
       
   538     return false;
       
   539   }
       
   540 
       
   541   inline hb_position_t em_scale (int16_t v, int scale)
       
   542   {
       
   543     int upem = face->get_upem ();
       
   544     int64_t scaled = v * (int64_t) scale;
       
   545     scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
       
   546     return (hb_position_t) (scaled / upem);
       
   547   }
       
   548   inline hb_position_t em_scalef (float v, int scale)
       
   549   {
       
   550     return (hb_position_t) round (v * scale / face->get_upem ());
       
   551   }
       
   552   inline float em_fscale (int16_t v, int scale)
       
   553   {
       
   554     return (float) v * scale / face->get_upem ();
       
   555   }
       
   556 };
       
   557 
       
   558 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
       
   559 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
       
   560 #include "hb-shaper-list.hh"
       
   561 #undef HB_SHAPER_IMPLEMENT
       
   562 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
       
   563 
       
   564 
       
   565 #endif /* HB_FONT_PRIVATE_HH */