1 /*
   2  * Copyright © 2011  Google, 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  * Google Author(s): Behdad Esfahbod
  25  */
  26 
  27 #define HB_SHAPER fallback
  28 #include "hb-shaper-impl-private.hh"
  29 
  30 
  31 /*
  32  * shaper face data
  33  */
  34 
  35 struct hb_fallback_shaper_face_data_t {};
  36 
  37 hb_fallback_shaper_face_data_t *
  38 _hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
  39 {
  40   return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
  41 }
  42 
  43 void
  44 _hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
  45 {
  46 }
  47 
  48 
  49 /*
  50  * shaper font data
  51  */
  52 
  53 struct hb_fallback_shaper_font_data_t {};
  54 
  55 hb_fallback_shaper_font_data_t *
  56 _hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
  57 {
  58   return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
  59 }
  60 
  61 void
  62 _hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
  63 {
  64 }
  65 
  66 
  67 /*
  68  * shaper shape_plan data
  69  */
  70 
  71 struct hb_fallback_shaper_shape_plan_data_t {};
  72 
  73 hb_fallback_shaper_shape_plan_data_t *
  74 _hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
  75                                             const hb_feature_t *user_features HB_UNUSED,
  76                                             unsigned int        num_user_features HB_UNUSED,
  77                                             const int          *coords HB_UNUSED,
  78                                             unsigned int        num_coords HB_UNUSED)
  79 {
  80   return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
  81 }
  82 
  83 void
  84 _hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
  85 {
  86 }
  87 
  88 
  89 /*
  90  * shaper
  91  */
  92 
  93 hb_bool_t
  94 _hb_fallback_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
  95                     hb_font_t          *font,
  96                     hb_buffer_t        *buffer,
  97                     const hb_feature_t *features HB_UNUSED,
  98                     unsigned int        num_features HB_UNUSED)
  99 {
 100   /* TODO
 101    *
 102    * - Apply fallback kern.
 103    * - Handle Variation Selectors?
 104    * - Apply normalization?
 105    *
 106    * This will make the fallback shaper into a dumb "TrueType"
 107    * shaper which many people unfortunately still request.
 108    */
 109 
 110   hb_codepoint_t space;
 111   bool has_space = (bool) font->get_nominal_glyph (' ', &space);
 112 
 113   buffer->clear_positions ();
 114 
 115   hb_direction_t direction = buffer->props.direction;
 116   hb_unicode_funcs_t *unicode = buffer->unicode;
 117   unsigned int count = buffer->len;
 118   hb_glyph_info_t *info = buffer->info;
 119   hb_glyph_position_t *pos = buffer->pos;
 120   for (unsigned int i = 0; i < count; i++)
 121   {
 122     if (has_space && unicode->is_default_ignorable (info[i].codepoint)) {
 123       info[i].codepoint = space;
 124       pos[i].x_advance = 0;
 125       pos[i].y_advance = 0;
 126       continue;
 127     }
 128     font->get_nominal_glyph (info[i].codepoint, &info[i].codepoint);
 129     font->get_glyph_advance_for_direction (info[i].codepoint,
 130                                            direction,
 131                                            &pos[i].x_advance,
 132                                            &pos[i].y_advance);
 133     font->subtract_glyph_origin_for_direction (info[i].codepoint,
 134                                                direction,
 135                                                &pos[i].x_offset,
 136                                                &pos[i].y_offset);
 137   }
 138 
 139   if (HB_DIRECTION_IS_BACKWARD (direction))
 140     hb_buffer_reverse (buffer);
 141 
 142   return true;
 143 }