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