gfx/harfbuzz/src/hb-font-private.hh

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     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  */
    29 #ifndef HB_FONT_PRIVATE_HH
    30 #define HB_FONT_PRIVATE_HH
    32 #include "hb-private.hh"
    34 #include "hb-object-private.hh"
    35 #include "hb-face-private.hh"
    36 #include "hb-shaper-private.hh"
    40 /*
    41  * hb_font_funcs_t
    42  */
    44 #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
    45   HB_FONT_FUNC_IMPLEMENT (glyph) \
    46   HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
    47   HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
    48   HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
    49   HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
    50   HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
    51   HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
    52   HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
    53   HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
    54   HB_FONT_FUNC_IMPLEMENT (glyph_name) \
    55   HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
    56   /* ^--- Add new callbacks here */
    58 struct hb_font_funcs_t {
    59   hb_object_header_t header;
    60   ASSERT_POD ();
    62   hb_bool_t immutable;
    64   /* Don't access these directly.  Call hb_font_get_*() instead. */
    66   struct {
    67 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
    68     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    69 #undef HB_FONT_FUNC_IMPLEMENT
    70   } get;
    72   struct {
    73 #define HB_FONT_FUNC_IMPLEMENT(name) void *name;
    74     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    75 #undef HB_FONT_FUNC_IMPLEMENT
    76   } user_data;
    78   struct {
    79 #define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
    80     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    81 #undef HB_FONT_FUNC_IMPLEMENT
    82   } destroy;
    83 };
    87 /*
    88  * hb_font_t
    89  */
    91 struct hb_font_t {
    92   hb_object_header_t header;
    93   ASSERT_POD ();
    95   hb_bool_t immutable;
    97   hb_font_t *parent;
    98   hb_face_t *face;
   100   int x_scale;
   101   int y_scale;
   103   unsigned int x_ppem;
   104   unsigned int y_ppem;
   106   hb_font_funcs_t   *klass;
   107   void              *user_data;
   108   hb_destroy_func_t  destroy;
   110   struct hb_shaper_data_t shaper_data;
   113   /* Convert from font-space to user-space */
   114   inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
   115   inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); }
   117   /* Convert from parent-font user-space to our user-space */
   118   inline hb_position_t parent_scale_x_distance (hb_position_t v) {
   119     if (unlikely (parent && parent->x_scale != x_scale))
   120       return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
   121     return v;
   122   }
   123   inline hb_position_t parent_scale_y_distance (hb_position_t v) {
   124     if (unlikely (parent && parent->y_scale != y_scale))
   125       return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
   126     return v;
   127   }
   128   inline hb_position_t parent_scale_x_position (hb_position_t v) {
   129     return parent_scale_x_distance (v);
   130   }
   131   inline hb_position_t parent_scale_y_position (hb_position_t v) {
   132     return parent_scale_y_distance (v);
   133   }
   135   inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
   136     *x = parent_scale_x_distance (*x);
   137     *y = parent_scale_y_distance (*y);
   138   }
   139   inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
   140     *x = parent_scale_x_position (*x);
   141     *y = parent_scale_y_position (*y);
   142   }
   145   /* Public getters */
   147   inline hb_bool_t has_glyph (hb_codepoint_t unicode)
   148   {
   149     hb_codepoint_t glyph;
   150     return get_glyph (unicode, 0, &glyph);
   151   }
   153   inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
   154 			      hb_codepoint_t *glyph)
   155   {
   156     *glyph = 0;
   157     return klass->get.glyph (this, user_data,
   158 			     unicode, variation_selector, glyph,
   159 			     klass->user_data.glyph);
   160   }
   162   inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
   163   {
   164     return klass->get.glyph_h_advance (this, user_data,
   165 				       glyph,
   166 				       klass->user_data.glyph_h_advance);
   167   }
   169   inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
   170   {
   171     return klass->get.glyph_v_advance (this, user_data,
   172 				       glyph,
   173 				       klass->user_data.glyph_v_advance);
   174   }
   176   inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
   177 				       hb_position_t *x, hb_position_t *y)
   178   {
   179     *x = *y = 0;
   180     return klass->get.glyph_h_origin (this, user_data,
   181 				      glyph, x, y,
   182 				      klass->user_data.glyph_h_origin);
   183   }
   185   inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
   186 				       hb_position_t *x, hb_position_t *y)
   187   {
   188     *x = *y = 0;
   189     return klass->get.glyph_v_origin (this, user_data,
   190 				      glyph, x, y,
   191 				      klass->user_data.glyph_v_origin);
   192   }
   194   inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
   195   {
   196     return klass->get.glyph_h_kerning (this, user_data,
   197 				       left_glyph, right_glyph,
   198 				       klass->user_data.glyph_h_kerning);
   199   }
   201   inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
   202   {
   203     return klass->get.glyph_v_kerning (this, user_data,
   204 				       top_glyph, bottom_glyph,
   205 				       klass->user_data.glyph_v_kerning);
   206   }
   208   inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
   209 				      hb_glyph_extents_t *extents)
   210   {
   211     memset (extents, 0, sizeof (*extents));
   212     return klass->get.glyph_extents (this, user_data,
   213 				     glyph,
   214 				     extents,
   215 				     klass->user_data.glyph_extents);
   216   }
   218   inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
   219 					    hb_position_t *x, hb_position_t *y)
   220   {
   221     *x = *y = 0;
   222     return klass->get.glyph_contour_point (this, user_data,
   223 					   glyph, point_index,
   224 					   x, y,
   225 					   klass->user_data.glyph_contour_point);
   226   }
   228   inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
   229 				   char *name, unsigned int size)
   230   {
   231     if (size) *name = '\0';
   232     return klass->get.glyph_name (this, user_data,
   233 				  glyph,
   234 				  name, size,
   235 				  klass->user_data.glyph_name);
   236   }
   238   inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
   239 					hb_codepoint_t *glyph)
   240   {
   241     *glyph = 0;
   242     if (len == -1) len = strlen (name);
   243     return klass->get.glyph_from_name (this, user_data,
   244 				       name, len,
   245 				       glyph,
   246 				       klass->user_data.glyph_from_name);
   247   }
   250   /* A bit higher-level, and with fallback */
   252   inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
   253 					       hb_direction_t direction,
   254 					       hb_position_t *x, hb_position_t *y)
   255   {
   256     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
   257       *x = get_glyph_h_advance (glyph);
   258       *y = 0;
   259     } else {
   260       *x = 0;
   261       *y = get_glyph_v_advance (glyph);
   262     }
   263   }
   265   /* Internal only */
   266   inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
   267 					     hb_position_t *x, hb_position_t *y)
   268   {
   269     *x = get_glyph_h_advance (glyph) / 2;
   271     /* TODO use font_metics.ascent */
   272     *y = y_scale;
   273   }
   275   inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
   276 					      hb_direction_t direction,
   277 					      hb_position_t *x, hb_position_t *y)
   278   {
   279     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
   280     {
   281       if (!get_glyph_h_origin (glyph, x, y) &&
   282 	   get_glyph_v_origin (glyph, x, y))
   283       {
   284 	hb_position_t dx, dy;
   285 	guess_v_origin_minus_h_origin (glyph, &dx, &dy);
   286 	*x -= dx; *y -= dy;
   287       }
   288     }
   289     else
   290     {
   291       if (!get_glyph_v_origin (glyph, x, y) &&
   292 	   get_glyph_h_origin (glyph, x, y))
   293       {
   294 	hb_position_t dx, dy;
   295 	guess_v_origin_minus_h_origin (glyph, &dx, &dy);
   296 	*x += dx; *y += dy;
   297       }
   298     }
   299   }
   301   inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
   302 					      hb_direction_t direction,
   303 					      hb_position_t *x, hb_position_t *y)
   304   {
   305     hb_position_t origin_x, origin_y;
   307     get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
   309     *x += origin_x;
   310     *y += origin_y;
   311   }
   313   inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
   314 						   hb_direction_t direction,
   315 						   hb_position_t *x, hb_position_t *y)
   316   {
   317     hb_position_t origin_x, origin_y;
   319     get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
   321     *x -= origin_x;
   322     *y -= origin_y;
   323   }
   325   inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
   326 					       hb_direction_t direction,
   327 					       hb_position_t *x, hb_position_t *y)
   328   {
   329     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
   330       *x = get_glyph_h_kerning (first_glyph, second_glyph);
   331       *y = 0;
   332     } else {
   333       *x = 0;
   334       *y = get_glyph_v_kerning (first_glyph, second_glyph);
   335     }
   336   }
   338   inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
   339 						 hb_direction_t direction,
   340 						 hb_glyph_extents_t *extents)
   341   {
   342     hb_bool_t ret = get_glyph_extents (glyph, extents);
   344     if (ret)
   345       subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
   347     return ret;
   348   }
   350   inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
   351 						       hb_direction_t direction,
   352 						       hb_position_t *x, hb_position_t *y)
   353   {
   354     hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
   356     if (ret)
   357       subtract_glyph_origin_for_direction (glyph, direction, x, y);
   359     return ret;
   360   }
   362   /* Generates gidDDD if glyph has no name. */
   363   inline void
   364   glyph_to_string (hb_codepoint_t glyph,
   365 		   char *s, unsigned int size)
   366   {
   367     if (get_glyph_name (glyph, s, size)) return;
   369     if (size && snprintf (s, size, "gid%u", glyph) < 0)
   370       *s = '\0';
   371   }
   373   /* Parses gidDDD and uniUUUU strings automatically. */
   374   inline hb_bool_t
   375   glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
   376 		     hb_codepoint_t *glyph)
   377   {
   378     if (get_glyph_from_name (s, len, glyph)) return true;
   380     if (len == -1) len = strlen (s);
   382     /* Straight glyph index. */
   383     if (hb_codepoint_parse (s, len, 10, glyph))
   384       return true;
   386     if (len > 3)
   387     {
   388       /* gidDDD syntax for glyph indices. */
   389       if (0 == strncmp (s, "gid", 3) &&
   390 	  hb_codepoint_parse (s + 3, len - 3, 10, glyph))
   391 	return true;
   393       /* uniUUUU and other Unicode character indices. */
   394       hb_codepoint_t unichar;
   395       if (0 == strncmp (s, "uni", 3) &&
   396 	  hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
   397 	  get_glyph (unichar, 0, glyph))
   398 	return true;
   399     }
   401     return false;
   402   }
   404   private:
   405   inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); }
   406 };
   408 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
   409 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
   410 #include "hb-shaper-list.hh"
   411 #undef HB_SHAPER_IMPLEMENT
   412 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
   415 #endif /* HB_FONT_PRIVATE_HH */

mercurial