LCOV - code coverage report
Current view: directory - gfx/harfbuzz/src - hb-font.cc (source / functions) Found Hit Coverage
Test: app.info Lines: 331 4 1.2 %
Date: 2012-06-02 Functions: 81 2 2.5 %

       1                 : /*
       2                 :  * Copyright © 2009  Red Hat, Inc.
       3                 :  *
       4                 :  *  This is part of HarfBuzz, a text shaping library.
       5                 :  *
       6                 :  * Permission is hereby granted, without written agreement and without
       7                 :  * license or royalty fees, to use, copy, modify, and distribute this
       8                 :  * software and its documentation for any purpose, provided that the
       9                 :  * above copyright notice and the following two paragraphs appear in
      10                 :  * all copies of this software.
      11                 :  *
      12                 :  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
      13                 :  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
      14                 :  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
      15                 :  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
      16                 :  * DAMAGE.
      17                 :  *
      18                 :  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
      19                 :  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
      20                 :  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
      21                 :  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
      22                 :  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
      23                 :  *
      24                 :  * Red Hat Author(s): Behdad Esfahbod
      25                 :  */
      26                 : 
      27                 : #include "hb-private.hh"
      28                 : 
      29                 : #include "hb-ot-layout-private.hh"
      30                 : 
      31                 : #include "hb-font-private.hh"
      32                 : #include "hb-blob.h"
      33                 : #include "hb-open-file-private.hh"
      34                 : #include "hb-ot-head-table.hh"
      35                 : 
      36                 : #include <string.h>
      37                 : 
      38                 : 
      39                 : 
      40                 : /*
      41                 :  * hb_font_funcs_t
      42                 :  */
      43                 : 
      44                 : static hb_bool_t
      45               0 : hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
      46                 :                        void *font_data HB_UNUSED,
      47                 :                        hb_codepoint_t unicode,
      48                 :                        hb_codepoint_t variation_selector,
      49                 :                        hb_codepoint_t *glyph,
      50                 :                        void *user_data HB_UNUSED)
      51                 : {
      52               0 :   if (font->parent)
      53               0 :     return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph);
      54                 : 
      55               0 :   *glyph = 0;
      56               0 :   return FALSE;
      57                 : }
      58                 : 
      59                 : static hb_position_t
      60               0 : hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
      61                 :                                  void *font_data HB_UNUSED,
      62                 :                                  hb_codepoint_t glyph,
      63                 :                                  void *user_data HB_UNUSED)
      64                 : {
      65               0 :   if (font->parent)
      66               0 :     return font->parent_scale_x_distance (hb_font_get_glyph_h_advance (font->parent, glyph));
      67                 : 
      68               0 :   return font->x_scale;
      69                 : }
      70                 : 
      71                 : static hb_position_t
      72               0 : hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
      73                 :                                  void *font_data HB_UNUSED,
      74                 :                                  hb_codepoint_t glyph,
      75                 :                                  void *user_data HB_UNUSED)
      76                 : {
      77               0 :   if (font->parent)
      78               0 :     return font->parent_scale_y_distance (hb_font_get_glyph_v_advance (font->parent, glyph));
      79                 : 
      80               0 :   return font->y_scale;
      81                 : }
      82                 : 
      83                 : static hb_bool_t
      84               0 : hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
      85                 :                                 void *font_data HB_UNUSED,
      86                 :                                 hb_codepoint_t glyph,
      87                 :                                 hb_position_t *x,
      88                 :                                 hb_position_t *y,
      89                 :                                 void *user_data HB_UNUSED)
      90                 : {
      91               0 :   if (font->parent) {
      92                 :     hb_bool_t ret = hb_font_get_glyph_h_origin (font->parent,
      93                 :                                                 glyph,
      94               0 :                                                 x, y);
      95               0 :     if (ret)
      96               0 :       font->parent_scale_position (x, y);
      97               0 :     return ret;
      98                 :   }
      99                 : 
     100               0 :   *x = *y = 0;
     101               0 :   return FALSE;
     102                 : }
     103                 : 
     104                 : static hb_bool_t
     105               0 : hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
     106                 :                                 void *font_data HB_UNUSED,
     107                 :                                 hb_codepoint_t glyph,
     108                 :                                 hb_position_t *x,
     109                 :                                 hb_position_t *y,
     110                 :                                 void *user_data HB_UNUSED)
     111                 : {
     112               0 :   if (font->parent) {
     113                 :     hb_bool_t ret = hb_font_get_glyph_v_origin (font->parent,
     114                 :                                                 glyph,
     115               0 :                                                 x, y);
     116               0 :     if (ret)
     117               0 :       font->parent_scale_position (x, y);
     118               0 :     return ret;
     119                 :   }
     120                 : 
     121               0 :   *x = *y = 0;
     122               0 :   return FALSE;
     123                 : }
     124                 : 
     125                 : static hb_position_t
     126               0 : hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
     127                 :                                  void *font_data HB_UNUSED,
     128                 :                                  hb_codepoint_t left_glyph,
     129                 :                                  hb_codepoint_t right_glyph,
     130                 :                                  void *user_data HB_UNUSED)
     131                 : {
     132               0 :   if (font->parent)
     133               0 :     return font->parent_scale_x_distance (hb_font_get_glyph_h_kerning (font->parent, left_glyph, right_glyph));
     134                 : 
     135               0 :   return 0;
     136                 : }
     137                 : 
     138                 : static hb_position_t
     139               0 : hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
     140                 :                                  void *font_data HB_UNUSED,
     141                 :                                  hb_codepoint_t top_glyph,
     142                 :                                  hb_codepoint_t bottom_glyph,
     143                 :                                  void *user_data HB_UNUSED)
     144                 : {
     145               0 :   if (font->parent)
     146               0 :     return font->parent_scale_y_distance (hb_font_get_glyph_v_kerning (font->parent, top_glyph, bottom_glyph));
     147                 : 
     148               0 :   return 0;
     149                 : }
     150                 : 
     151                 : static hb_bool_t
     152               0 : hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
     153                 :                                void *font_data HB_UNUSED,
     154                 :                                hb_codepoint_t glyph,
     155                 :                                hb_glyph_extents_t *extents,
     156                 :                                void *user_data HB_UNUSED)
     157                 : {
     158               0 :   if (font->parent) {
     159                 :     hb_bool_t ret = hb_font_get_glyph_extents (font->parent,
     160                 :                                                glyph,
     161               0 :                                                extents);
     162               0 :     if (ret) {
     163               0 :       font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
     164               0 :       font->parent_scale_distance (&extents->width, &extents->height);
     165                 :     }
     166               0 :     return ret;
     167                 :   }
     168                 : 
     169               0 :   memset (extents, 0, sizeof (*extents));
     170               0 :   return FALSE;
     171                 : }
     172                 : 
     173                 : static hb_bool_t
     174               0 : hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
     175                 :                                      void *font_data HB_UNUSED,
     176                 :                                      hb_codepoint_t glyph,
     177                 :                                      unsigned int point_index,
     178                 :                                      hb_position_t *x,
     179                 :                                      hb_position_t *y,
     180                 :                                      void *user_data HB_UNUSED)
     181                 : {
     182               0 :   if (font->parent) {
     183                 :     hb_bool_t ret = hb_font_get_glyph_contour_point (font->parent,
     184                 :                                                      glyph, point_index,
     185               0 :                                                      x, y);
     186               0 :     if (ret)
     187               0 :       font->parent_scale_position (x, y);
     188               0 :     return ret;
     189                 :   }
     190                 : 
     191               0 :   *x = *y = 0;
     192               0 :   return FALSE;
     193                 : }
     194                 : 
     195                 : 
     196                 : static hb_font_funcs_t _hb_font_funcs_nil = {
     197                 :   HB_OBJECT_HEADER_STATIC,
     198                 : 
     199                 :   TRUE, /* immutable */
     200                 : 
     201                 :   {
     202                 : #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
     203                 :     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
     204                 : #undef HB_FONT_FUNC_IMPLEMENT
     205                 :   }
     206            1464 : };
     207                 : 
     208                 : 
     209                 : hb_font_funcs_t *
     210               0 : hb_font_funcs_create (void)
     211                 : {
     212                 :   hb_font_funcs_t *ffuncs;
     213                 : 
     214               0 :   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
     215               0 :     return &_hb_font_funcs_nil;
     216                 : 
     217               0 :   ffuncs->get = _hb_font_funcs_nil.get;
     218                 : 
     219               0 :   return ffuncs;
     220                 : }
     221                 : 
     222                 : hb_font_funcs_t *
     223               0 : hb_font_funcs_get_empty (void)
     224                 : {
     225               0 :   return &_hb_font_funcs_nil;
     226                 : }
     227                 : 
     228                 : hb_font_funcs_t *
     229               0 : hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
     230                 : {
     231               0 :   return hb_object_reference (ffuncs);
     232                 : }
     233                 : 
     234                 : void
     235               0 : hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
     236                 : {
     237               0 :   if (!hb_object_destroy (ffuncs)) return;
     238                 : 
     239                 : #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
     240                 :   ffuncs->destroy.name (ffuncs->user_data.name);
     241               0 :   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
     242                 : #undef HB_FONT_FUNC_IMPLEMENT
     243                 : 
     244               0 :   free (ffuncs);
     245                 : }
     246                 : 
     247                 : hb_bool_t
     248               0 : hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
     249                 :                              hb_user_data_key_t *key,
     250                 :                              void *              data,
     251                 :                              hb_destroy_func_t   destroy,
     252                 :                              hb_bool_t           replace)
     253                 : {
     254               0 :   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
     255                 : }
     256                 : 
     257                 : void *
     258               0 : hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
     259                 :                              hb_user_data_key_t *key)
     260                 : {
     261               0 :   return hb_object_get_user_data (ffuncs, key);
     262                 : }
     263                 : 
     264                 : 
     265                 : void
     266               0 : hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
     267                 : {
     268               0 :   if (hb_object_is_inert (ffuncs))
     269               0 :     return;
     270                 : 
     271               0 :   ffuncs->immutable = TRUE;
     272                 : }
     273                 : 
     274                 : hb_bool_t
     275               0 : hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
     276                 : {
     277               0 :   return ffuncs->immutable;
     278                 : }
     279                 : 
     280                 : 
     281                 : #define HB_FONT_FUNC_IMPLEMENT(name) \
     282                 :                                                                          \
     283                 : void                                                                     \
     284                 : hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
     285                 :                                  hb_font_get_##name##_func_t  func,      \
     286                 :                                  void                        *user_data, \
     287                 :                                  hb_destroy_func_t            destroy)   \
     288                 : {                                                                        \
     289                 :   if (ffuncs->immutable) {                                               \
     290                 :     if (destroy)                                                         \
     291                 :       destroy (user_data);                                               \
     292                 :     return;                                                              \
     293                 :   }                                                                      \
     294                 :                                                                          \
     295                 :   if (ffuncs->destroy.name)                                              \
     296                 :     ffuncs->destroy.name (ffuncs->user_data.name);                       \
     297                 :                                                                          \
     298                 :   if (func) {                                                            \
     299                 :     ffuncs->get.name = func;                                             \
     300                 :     ffuncs->user_data.name = user_data;                                  \
     301                 :     ffuncs->destroy.name = destroy;                                      \
     302                 :   } else {                                                               \
     303                 :     ffuncs->get.name = hb_font_get_##name##_nil;                         \
     304                 :     ffuncs->user_data.name = NULL;                                       \
     305                 :     ffuncs->destroy.name = NULL;                                         \
     306                 :   }                                                                      \
     307                 : }
     308                 : 
     309               0 : HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
     310                 : #undef HB_FONT_FUNC_IMPLEMENT
     311                 : 
     312                 : 
     313                 : hb_bool_t
     314               0 : hb_font_get_glyph (hb_font_t *font,
     315                 :                    hb_codepoint_t unicode, hb_codepoint_t variation_selector,
     316                 :                    hb_codepoint_t *glyph)
     317                 : {
     318               0 :   *glyph = 0;
     319                 :   return font->klass->get.glyph (font, font->user_data,
     320                 :                                  unicode, variation_selector, glyph,
     321               0 :                                  font->klass->user_data.glyph);
     322                 : }
     323                 : 
     324                 : hb_position_t
     325               0 : hb_font_get_glyph_h_advance (hb_font_t *font,
     326                 :                              hb_codepoint_t glyph)
     327                 : {
     328                 :   return font->klass->get.glyph_h_advance (font, font->user_data,
     329                 :                                            glyph,
     330               0 :                                            font->klass->user_data.glyph_h_advance);
     331                 : }
     332                 : 
     333                 : hb_position_t
     334               0 : hb_font_get_glyph_v_advance (hb_font_t *font,
     335                 :                              hb_codepoint_t glyph)
     336                 : {
     337                 :   return font->klass->get.glyph_v_advance (font, font->user_data,
     338                 :                                            glyph,
     339               0 :                                            font->klass->user_data.glyph_v_advance);
     340                 : }
     341                 : 
     342                 : hb_bool_t
     343               0 : hb_font_get_glyph_h_origin (hb_font_t *font,
     344                 :                             hb_codepoint_t glyph,
     345                 :                             hb_position_t *x, hb_position_t *y)
     346                 : {
     347               0 :   *x = *y = 0;
     348                 :   return font->klass->get.glyph_h_origin (font, font->user_data,
     349                 :                                            glyph, x, y,
     350               0 :                                            font->klass->user_data.glyph_h_origin);
     351                 : }
     352                 : 
     353                 : hb_bool_t
     354               0 : hb_font_get_glyph_v_origin (hb_font_t *font,
     355                 :                             hb_codepoint_t glyph,
     356                 :                             hb_position_t *x, hb_position_t *y)
     357                 : {
     358               0 :   *x = *y = 0;
     359                 :   return font->klass->get.glyph_v_origin (font, font->user_data,
     360                 :                                            glyph, x, y,
     361               0 :                                            font->klass->user_data.glyph_v_origin);
     362                 : }
     363                 : 
     364                 : hb_position_t
     365               0 : hb_font_get_glyph_h_kerning (hb_font_t *font,
     366                 :                              hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
     367                 : {
     368                 :   return font->klass->get.glyph_h_kerning (font, font->user_data,
     369                 :                                            left_glyph, right_glyph,
     370               0 :                                            font->klass->user_data.glyph_h_kerning);
     371                 : }
     372                 : 
     373                 : hb_position_t
     374               0 : hb_font_get_glyph_v_kerning (hb_font_t *font,
     375                 :                              hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
     376                 : {
     377                 :   return font->klass->get.glyph_v_kerning (font, font->user_data,
     378                 :                                      left_glyph, right_glyph,
     379               0 :                                      font->klass->user_data.glyph_v_kerning);
     380                 : }
     381                 : 
     382                 : hb_bool_t
     383               0 : hb_font_get_glyph_extents (hb_font_t *font,
     384                 :                            hb_codepoint_t glyph,
     385                 :                            hb_glyph_extents_t *extents)
     386                 : {
     387               0 :   memset (extents, 0, sizeof (*extents));
     388                 :   return font->klass->get.glyph_extents (font, font->user_data,
     389                 :                                          glyph,
     390                 :                                          extents,
     391               0 :                                          font->klass->user_data.glyph_extents);
     392                 : }
     393                 : 
     394                 : hb_bool_t
     395               0 : hb_font_get_glyph_contour_point (hb_font_t *font,
     396                 :                                  hb_codepoint_t glyph, unsigned int point_index,
     397                 :                                  hb_position_t *x, hb_position_t *y)
     398                 : {
     399               0 :   *x = *y = 0;
     400                 :   return font->klass->get.glyph_contour_point (font, font->user_data,
     401                 :                                                glyph, point_index,
     402                 :                                                x, y,
     403               0 :                                                font->klass->user_data.glyph_contour_point);
     404                 : }
     405                 : 
     406                 : 
     407                 : /* A bit higher-level, and with fallback */
     408                 : 
     409                 : void
     410               0 : hb_font_get_glyph_advance_for_direction (hb_font_t *font,
     411                 :                                          hb_codepoint_t glyph,
     412                 :                                          hb_direction_t direction,
     413                 :                                          hb_position_t *x, hb_position_t *y)
     414                 : {
     415               0 :   if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
     416               0 :     *x = hb_font_get_glyph_h_advance (font, glyph);
     417               0 :     *y = 0;
     418                 :   } else {
     419               0 :     *x = 0;
     420               0 :     *y = hb_font_get_glyph_v_advance (font, glyph);
     421                 :   }
     422               0 : }
     423                 : 
     424                 : static void
     425               0 : guess_v_origin_minus_h_origin (hb_font_t *font,
     426                 :                                hb_codepoint_t glyph,
     427                 :                                hb_position_t *x, hb_position_t *y)
     428                 : {
     429               0 :   *x = hb_font_get_glyph_h_advance (font, glyph) / 2;
     430                 : 
     431                 :   /* TODO use font_metics.ascent */
     432               0 :   *y = font->y_scale;
     433               0 : }
     434                 : 
     435                 : 
     436                 : void
     437               0 : hb_font_get_glyph_origin_for_direction (hb_font_t *font,
     438                 :                                         hb_codepoint_t glyph,
     439                 :                                         hb_direction_t direction,
     440                 :                                         hb_position_t *x, hb_position_t *y)
     441                 : {
     442               0 :   if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
     443               0 :     hb_bool_t ret = hb_font_get_glyph_h_origin (font, glyph, x, y);
     444               0 :     if (!ret && (ret = hb_font_get_glyph_v_origin (font, glyph, x, y))) {
     445                 :       hb_position_t dx, dy;
     446               0 :       guess_v_origin_minus_h_origin (font, glyph, &dx, &dy);
     447               0 :       *x -= dx; *y -= dy;
     448                 :     }
     449                 :   } else {
     450               0 :     hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x, y);
     451               0 :     if (!ret && (ret = hb_font_get_glyph_h_origin (font, glyph, x, y))) {
     452                 :       hb_position_t dx, dy;
     453               0 :       guess_v_origin_minus_h_origin (font, glyph, &dx, &dy);
     454               0 :       *x += dx; *y += dy;
     455                 :     }
     456                 :   }
     457               0 : }
     458                 : 
     459                 : void
     460               0 : hb_font_add_glyph_origin_for_direction (hb_font_t *font,
     461                 :                                         hb_codepoint_t glyph,
     462                 :                                         hb_direction_t direction,
     463                 :                                         hb_position_t *x, hb_position_t *y)
     464                 : {
     465                 :   hb_position_t origin_x, origin_y;
     466                 : 
     467               0 :   hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &origin_y);
     468                 : 
     469               0 :   *x += origin_x;
     470               0 :   *y += origin_y;
     471               0 : }
     472                 : 
     473                 : void
     474               0 : hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
     475                 :                                              hb_codepoint_t glyph,
     476                 :                                              hb_direction_t direction,
     477                 :                                              hb_position_t *x, hb_position_t *y)
     478                 : {
     479                 :   hb_position_t origin_x, origin_y;
     480                 : 
     481               0 :   hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &origin_y);
     482                 : 
     483               0 :   *x -= origin_x;
     484               0 :   *y -= origin_y;
     485               0 : }
     486                 : 
     487                 : void
     488               0 : hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
     489                 :                                          hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
     490                 :                                          hb_direction_t direction,
     491                 :                                          hb_position_t *x, hb_position_t *y)
     492                 : {
     493               0 :   if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
     494               0 :     *x = hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph);
     495               0 :     *y = 0;
     496                 :   } else {
     497               0 :     *x = 0;
     498               0 :     *y = hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph);
     499                 :   }
     500               0 : }
     501                 : 
     502                 : hb_bool_t
     503               0 : hb_font_get_glyph_extents_for_origin (hb_font_t *font,
     504                 :                                       hb_codepoint_t glyph,
     505                 :                                       hb_direction_t direction,
     506                 :                                       hb_glyph_extents_t *extents)
     507                 : {
     508               0 :   hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, extents);
     509                 : 
     510               0 :   if (ret)
     511               0 :     hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, &extents->x_bearing, &extents->y_bearing);
     512                 : 
     513               0 :   return ret;
     514                 : }
     515                 : 
     516                 : hb_bool_t
     517               0 : hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
     518                 :                                             hb_codepoint_t glyph, unsigned int point_index,
     519                 :                                             hb_direction_t direction,
     520                 :                                             hb_position_t *x, hb_position_t *y)
     521                 : {
     522               0 :   hb_bool_t ret = hb_font_get_glyph_contour_point (font, glyph, point_index, x, y);
     523                 : 
     524               0 :   if (ret)
     525               0 :     hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, x, y);
     526                 : 
     527               0 :   return ret;
     528                 : }
     529                 : 
     530                 : 
     531                 : /*
     532                 :  * hb_face_t
     533                 :  */
     534                 : 
     535                 : static hb_face_t _hb_face_nil = {
     536                 :   HB_OBJECT_HEADER_STATIC,
     537                 : 
     538                 :   TRUE, /* immutable */
     539                 : 
     540                 :   NULL, /* reference_table */
     541                 :   NULL, /* user_data */
     542                 :   NULL, /* destroy */
     543                 : 
     544                 :   NULL, /* ot_layout */
     545                 : 
     546                 :   0,    /* index */
     547                 :   1000  /* upem */
     548            1464 : };
     549                 : 
     550                 : 
     551                 : hb_face_t *
     552               0 : hb_face_create_for_tables (hb_reference_table_func_t  reference_table,
     553                 :                            void                      *user_data,
     554                 :                            hb_destroy_func_t          destroy)
     555                 : {
     556                 :   hb_face_t *face;
     557                 : 
     558               0 :   if (!reference_table || !(face = hb_object_create<hb_face_t> ())) {
     559               0 :     if (destroy)
     560               0 :       destroy (user_data);
     561               0 :     return &_hb_face_nil;
     562                 :   }
     563                 : 
     564               0 :   face->reference_table = reference_table;
     565               0 :   face->user_data = user_data;
     566               0 :   face->destroy = destroy;
     567                 : 
     568               0 :   face->ot_layout = _hb_ot_layout_create (face);
     569                 : 
     570               0 :   face->upem = 0;
     571                 : 
     572               0 :   return face;
     573                 : }
     574                 : 
     575                 : 
     576                 : typedef struct _hb_face_for_data_closure_t {
     577                 :   hb_blob_t *blob;
     578                 :   unsigned int  index;
     579                 : } hb_face_for_data_closure_t;
     580                 : 
     581                 : static hb_face_for_data_closure_t *
     582               0 : _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
     583                 : {
     584                 :   hb_face_for_data_closure_t *closure;
     585                 : 
     586               0 :   closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t));
     587               0 :   if (unlikely (!closure))
     588               0 :     return NULL;
     589                 : 
     590               0 :   closure->blob = blob;
     591               0 :   closure->index = index;
     592                 : 
     593               0 :   return closure;
     594                 : }
     595                 : 
     596                 : static void
     597               0 : _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
     598                 : {
     599               0 :   hb_blob_destroy (closure->blob);
     600               0 :   free (closure);
     601               0 : }
     602                 : 
     603                 : static hb_blob_t *
     604               0 : _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
     605                 : {
     606               0 :   hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
     607                 : 
     608               0 :   if (tag == HB_TAG_NONE)
     609               0 :     return hb_blob_reference (data->blob);
     610                 : 
     611               0 :   const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance (data->blob);
     612               0 :   const OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
     613                 : 
     614               0 :   const OpenTypeTable &table = ot_face.get_table_by_tag (tag);
     615                 : 
     616               0 :   hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
     617                 : 
     618               0 :   return blob;
     619                 : }
     620                 : 
     621                 : hb_face_t *
     622               0 : hb_face_create (hb_blob_t    *blob,
     623                 :                 unsigned int  index)
     624                 : {
     625                 :   hb_face_t *face;
     626                 : 
     627               0 :   if (unlikely (!blob || !hb_blob_get_length (blob)))
     628               0 :     return &_hb_face_nil;
     629                 : 
     630               0 :   hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Sanitizer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
     631                 : 
     632               0 :   if (unlikely (!closure))
     633               0 :     return &_hb_face_nil;
     634                 : 
     635                 :   face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
     636                 :                                     closure,
     637               0 :                                     (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
     638                 : 
     639               0 :   hb_face_set_index (face, index);
     640                 : 
     641               0 :   return face;
     642                 : }
     643                 : 
     644                 : hb_face_t *
     645               0 : hb_face_get_empty (void)
     646                 : {
     647               0 :   return &_hb_face_nil;
     648                 : }
     649                 : 
     650                 : 
     651                 : hb_face_t *
     652               0 : hb_face_reference (hb_face_t *face)
     653                 : {
     654               0 :   return hb_object_reference (face);
     655                 : }
     656                 : 
     657                 : void
     658               0 : hb_face_destroy (hb_face_t *face)
     659                 : {
     660               0 :   if (!hb_object_destroy (face)) return;
     661                 : 
     662               0 :   _hb_ot_layout_destroy (face->ot_layout);
     663                 : 
     664               0 :   if (face->destroy)
     665               0 :     face->destroy (face->user_data);
     666                 : 
     667               0 :   free (face);
     668                 : }
     669                 : 
     670                 : hb_bool_t
     671               0 : hb_face_set_user_data (hb_face_t          *face,
     672                 :                        hb_user_data_key_t *key,
     673                 :                        void *              data,
     674                 :                        hb_destroy_func_t   destroy,
     675                 :                        hb_bool_t           replace)
     676                 : {
     677               0 :   return hb_object_set_user_data (face, key, data, destroy, replace);
     678                 : }
     679                 : 
     680                 : void *
     681               0 : hb_face_get_user_data (hb_face_t          *face,
     682                 :                        hb_user_data_key_t *key)
     683                 : {
     684               0 :   return hb_object_get_user_data (face, key);
     685                 : }
     686                 : 
     687                 : void
     688               0 : hb_face_make_immutable (hb_face_t *face)
     689                 : {
     690               0 :   if (hb_object_is_inert (face))
     691               0 :     return;
     692                 : 
     693               0 :   face->immutable = true;
     694                 : }
     695                 : 
     696                 : hb_bool_t
     697               0 : hb_face_is_immutable (hb_face_t *face)
     698                 : {
     699               0 :   return face->immutable;
     700                 : }
     701                 : 
     702                 : 
     703                 : hb_blob_t *
     704               0 : hb_face_reference_table (hb_face_t *face,
     705                 :                          hb_tag_t   tag)
     706                 : {
     707                 :   hb_blob_t *blob;
     708                 : 
     709               0 :   if (unlikely (!face || !face->reference_table))
     710               0 :     return hb_blob_get_empty ();
     711                 : 
     712               0 :   blob = face->reference_table (face, tag, face->user_data);
     713               0 :   if (unlikely (!blob))
     714               0 :     return hb_blob_get_empty ();
     715                 : 
     716               0 :   return blob;
     717                 : }
     718                 : 
     719                 : hb_blob_t *
     720               0 : hb_face_reference_blob (hb_face_t *face)
     721                 : {
     722               0 :   return hb_face_reference_table (face, HB_TAG_NONE);
     723                 : }
     724                 : 
     725                 : void
     726               0 : hb_face_set_index (hb_face_t    *face,
     727                 :                    unsigned int  index)
     728                 : {
     729               0 :   if (hb_object_is_inert (face))
     730               0 :     return;
     731                 : 
     732               0 :   face->index = 0;
     733                 : }
     734                 : 
     735                 : unsigned int
     736               0 : hb_face_get_index (hb_face_t    *face)
     737                 : {
     738               0 :   return face->index;
     739                 : }
     740                 : 
     741                 : void
     742               0 : hb_face_set_upem (hb_face_t    *face,
     743                 :                   unsigned int  upem)
     744                 : {
     745               0 :   if (hb_object_is_inert (face))
     746               0 :     return;
     747                 : 
     748               0 :   face->upem = upem;
     749                 : }
     750                 : 
     751                 : unsigned int
     752               0 : hb_face_get_upem (hb_face_t *face)
     753                 : {
     754               0 :   if (unlikely (!face->upem)) {
     755               0 :     hb_blob_t *head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (face, HB_OT_TAG_head));
     756               0 :     const head *head_table = Sanitizer<head>::lock_instance (head_blob);
     757               0 :     face->upem = head_table->get_upem ();
     758               0 :     hb_blob_destroy (head_blob);
     759                 :   }
     760               0 :   return face->upem;
     761                 : }
     762                 : 
     763                 : 
     764                 : /*
     765                 :  * hb_font_t
     766                 :  */
     767                 : 
     768                 : static hb_font_t _hb_font_nil = {
     769                 :   HB_OBJECT_HEADER_STATIC,
     770                 : 
     771                 :   TRUE, /* immutable */
     772                 : 
     773                 :   NULL, /* parent */
     774                 :   &_hb_face_nil,
     775                 : 
     776                 :   0, /* x_scale */
     777                 :   0, /* y_scale */
     778                 : 
     779                 :   0, /* x_ppem */
     780                 :   0, /* y_ppem */
     781                 : 
     782                 :   &_hb_font_funcs_nil, /* klass */
     783                 :   NULL, /* user_data */
     784                 :   NULL  /* destroy */
     785            1464 : };
     786                 : 
     787                 : hb_font_t *
     788               0 : hb_font_create (hb_face_t *face)
     789                 : {
     790                 :   hb_font_t *font;
     791                 : 
     792               0 :   if (unlikely (!face))
     793               0 :     face = &_hb_face_nil;
     794               0 :   if (unlikely (hb_object_is_inert (face)))
     795               0 :     return &_hb_font_nil;
     796               0 :   if (!(font = hb_object_create<hb_font_t> ()))
     797               0 :     return &_hb_font_nil;
     798                 : 
     799               0 :   hb_face_make_immutable (face);
     800               0 :   font->face = hb_face_reference (face);
     801               0 :   font->klass = &_hb_font_funcs_nil;
     802                 : 
     803               0 :   return font;
     804                 : }
     805                 : 
     806                 : hb_font_t *
     807               0 : hb_font_create_sub_font (hb_font_t *parent)
     808                 : {
     809               0 :   if (unlikely (!parent))
     810               0 :     return &_hb_font_nil;
     811                 : 
     812               0 :   hb_font_t *font = hb_font_create (parent->face);
     813                 : 
     814               0 :   if (unlikely (hb_object_is_inert (font)))
     815               0 :     return font;
     816                 : 
     817               0 :   hb_font_make_immutable (parent);
     818               0 :   font->parent = hb_font_reference (parent);
     819                 : 
     820               0 :   font->x_scale = parent->x_scale;
     821               0 :   font->y_scale = parent->y_scale;
     822               0 :   font->x_ppem = parent->x_ppem;
     823               0 :   font->y_ppem = parent->y_ppem;
     824                 : 
     825               0 :   font->klass = &_hb_font_funcs_nil;
     826                 : 
     827               0 :   return font;
     828                 : }
     829                 : 
     830                 : hb_font_t *
     831               0 : hb_font_get_empty (void)
     832                 : {
     833               0 :   return &_hb_font_nil;
     834                 : }
     835                 : 
     836                 : hb_font_t *
     837               0 : hb_font_reference (hb_font_t *font)
     838                 : {
     839               0 :   return hb_object_reference (font);
     840                 : }
     841                 : 
     842                 : void
     843               0 : hb_font_destroy (hb_font_t *font)
     844                 : {
     845               0 :   if (!hb_object_destroy (font)) return;
     846                 : 
     847               0 :   hb_font_destroy (font->parent);
     848               0 :   hb_face_destroy (font->face);
     849               0 :   hb_font_funcs_destroy (font->klass);
     850               0 :   if (font->destroy)
     851               0 :     font->destroy (font->user_data);
     852                 : 
     853               0 :   free (font);
     854                 : }
     855                 : 
     856                 : hb_bool_t
     857               0 : hb_font_set_user_data (hb_font_t          *font,
     858                 :                        hb_user_data_key_t *key,
     859                 :                        void *              data,
     860                 :                        hb_destroy_func_t   destroy,
     861                 :                        hb_bool_t           replace)
     862                 : {
     863               0 :   return hb_object_set_user_data (font, key, data, destroy, replace);
     864                 : }
     865                 : 
     866                 : void *
     867               0 : hb_font_get_user_data (hb_font_t          *font,
     868                 :                        hb_user_data_key_t *key)
     869                 : {
     870               0 :   return hb_object_get_user_data (font, key);
     871                 : }
     872                 : 
     873                 : void
     874               0 : hb_font_make_immutable (hb_font_t *font)
     875                 : {
     876               0 :   if (hb_object_is_inert (font))
     877               0 :     return;
     878                 : 
     879               0 :   font->immutable = true;
     880                 : }
     881                 : 
     882                 : hb_bool_t
     883               0 : hb_font_is_immutable (hb_font_t *font)
     884                 : {
     885               0 :   return font->immutable;
     886                 : }
     887                 : 
     888                 : hb_font_t *
     889               0 : hb_font_get_parent (hb_font_t *font)
     890                 : {
     891               0 :   return font->parent;
     892                 : }
     893                 : 
     894                 : hb_face_t *
     895               0 : hb_font_get_face (hb_font_t *font)
     896                 : {
     897               0 :   return font->face;
     898                 : }
     899                 : 
     900                 : 
     901                 : void
     902               0 : hb_font_set_funcs (hb_font_t         *font,
     903                 :                    hb_font_funcs_t   *klass,
     904                 :                    void              *user_data,
     905                 :                    hb_destroy_func_t  destroy)
     906                 : {
     907               0 :   if (font->immutable) {
     908               0 :     if (destroy)
     909               0 :       destroy (user_data);
     910               0 :     return;
     911                 :   }
     912                 : 
     913               0 :   if (font->destroy)
     914               0 :     font->destroy (font->user_data);
     915                 : 
     916               0 :   if (!klass)
     917               0 :     klass = &_hb_font_funcs_nil;
     918                 : 
     919               0 :   hb_font_funcs_reference (klass);
     920               0 :   hb_font_funcs_destroy (font->klass);
     921               0 :   font->klass = klass;
     922               0 :   font->user_data = user_data;
     923               0 :   font->destroy = destroy;
     924                 : }
     925                 : 
     926                 : void
     927               0 : hb_font_set_funcs_data (hb_font_t         *font,
     928                 :                         void              *user_data,
     929                 :                         hb_destroy_func_t  destroy)
     930                 : {
     931                 :   /* Destroy user_data? */
     932               0 :   if (font->immutable) {
     933               0 :     if (destroy)
     934               0 :       destroy (user_data);
     935               0 :     return;
     936                 :   }
     937                 : 
     938               0 :   if (font->destroy)
     939               0 :     font->destroy (font->user_data);
     940                 : 
     941               0 :   font->user_data = user_data;
     942               0 :   font->destroy = destroy;
     943                 : }
     944                 : 
     945                 : 
     946                 : void
     947               0 : hb_font_set_scale (hb_font_t *font,
     948                 :                    int x_scale,
     949                 :                    int y_scale)
     950                 : {
     951               0 :   if (font->immutable)
     952               0 :     return;
     953                 : 
     954               0 :   font->x_scale = x_scale;
     955               0 :   font->y_scale = y_scale;
     956                 : }
     957                 : 
     958                 : void
     959               0 : hb_font_get_scale (hb_font_t *font,
     960                 :                    int *x_scale,
     961                 :                    int *y_scale)
     962                 : {
     963               0 :   if (x_scale) *x_scale = font->x_scale;
     964               0 :   if (y_scale) *y_scale = font->y_scale;
     965               0 : }
     966                 : 
     967                 : void
     968               0 : hb_font_set_ppem (hb_font_t *font,
     969                 :                   unsigned int x_ppem,
     970                 :                   unsigned int y_ppem)
     971                 : {
     972               0 :   if (font->immutable)
     973               0 :     return;
     974                 : 
     975               0 :   font->x_ppem = x_ppem;
     976               0 :   font->y_ppem = y_ppem;
     977                 : }
     978                 : 
     979                 : void
     980               0 : hb_font_get_ppem (hb_font_t *font,
     981                 :                   unsigned int *x_ppem,
     982                 :                   unsigned int *y_ppem)
     983                 : {
     984               0 :   if (x_ppem) *x_ppem = font->x_ppem;
     985               0 :   if (y_ppem) *y_ppem = font->y_ppem;
     986            4392 : }
     987                 : 
     988                 : 

Generated by: LCOV version 1.7