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