1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 /*
  31  * Copyright © 2011  Google, Inc.
  32  *
  33  *  This is part of HarfBuzz, a text shaping library.
  34  *
  35  * Permission is hereby granted, without written agreement and without
  36  * license or royalty fees, to use, copy, modify, and distribute this
  37  * software and its documentation for any purpose, provided that the
  38  * above copyright notice and the following two paragraphs appear in
  39  * all copies of this software.
  40  *
  41  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  42  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  43  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  44  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  45  * DAMAGE.
  46  *
  47  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  48  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  49  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  50  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  51  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  52  *
  53  * Google Author(s): Behdad Esfahbod
  54  */
  55 
  56 #define HB_SHAPER fallback
  57 #include "hb-shaper-impl-private.hh"
  58 
  59 
  60 /*
  61  * shaper face data
  62  */
  63 
  64 struct hb_fallback_shaper_face_data_t {};
  65 
  66 hb_fallback_shaper_face_data_t *
  67 _hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
  68 {
  69   return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
  70 }
  71 
  72 void
  73 _hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
  74 {
  75 }
  76 
  77 
  78 /*
  79  * shaper font data
  80  */
  81 
  82 struct hb_fallback_shaper_font_data_t {};
  83 
  84 hb_fallback_shaper_font_data_t *
  85 _hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
  86 {
  87   return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
  88 }
  89 
  90 void
  91 _hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
  92 {
  93 }
  94 
  95 
  96 /*
  97  * shaper shape_plan data
  98  */
  99 
 100 struct hb_fallback_shaper_shape_plan_data_t {};
 101 
 102 hb_fallback_shaper_shape_plan_data_t *
 103 _hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
 104                                             const hb_feature_t *user_features HB_UNUSED,
 105                                             unsigned int        num_user_features HB_UNUSED)
 106 {
 107   return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 108 }
 109 
 110 void
 111 _hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
 112 {
 113 }
 114 
 115 
 116 /*
 117  * shaper
 118  */
 119 
 120 hb_bool_t
 121 _hb_fallback_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
 122                     hb_font_t          *font,
 123                     hb_buffer_t        *buffer,
 124                     const hb_feature_t *features HB_UNUSED,
 125                     unsigned int        num_features HB_UNUSED)
 126 {
 127   /* TODO
 128    *
 129    * - Apply fallback kern.
 130    * - Handle Variation Selectors?
 131    * - Apply normalization?
 132    *
 133    * This will make the fallback shaper into a dumb "TrueType"
 134    * shaper which many people unfortunately still request.
 135    */
 136 
 137   hb_codepoint_t space;
 138   bool has_space = font->get_glyph (' ', 0, &space);
 139 
 140   buffer->clear_positions ();
 141 
 142   hb_direction_t direction = buffer->props.direction;
 143   hb_unicode_funcs_t *unicode = buffer->unicode;
 144   unsigned int count = buffer->len;
 145   hb_glyph_info_t *info = buffer->info;
 146   hb_glyph_position_t *pos = buffer->pos;
 147   for (unsigned int i = 0; i < count; i++)
 148   {
 149     if (has_space && unicode->is_default_ignorable (info[i].codepoint)) {
 150       info[i].codepoint = space;
 151       pos[i].x_advance = 0;
 152       pos[i].y_advance = 0;
 153       continue;
 154     }
 155     font->get_glyph (info[i].codepoint, 0, &info[i].codepoint);
 156     font->get_glyph_advance_for_direction (info[i].codepoint,
 157                                            direction,
 158                                            &pos[i].x_advance,
 159                                            &pos[i].y_advance);
 160     font->subtract_glyph_origin_for_direction (info[i].codepoint,
 161                                                direction,
 162                                                &pos[i].x_offset,
 163                                                &pos[i].y_offset);
 164   }
 165 
 166   if (HB_DIRECTION_IS_BACKWARD (direction))
 167     hb_buffer_reverse (buffer);
 168 
 169   return true;
 170 }