1 /* 2 * Copyright © 2011,2014 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, Roozbeh Pournader 25 */ 26 27 #include "hb.hh" 28 29 #include "hb-ot.h" 30 31 #include "hb-font.hh" 32 #include "hb-machinery.hh" 33 #include "hb-ot-face.hh" 34 35 #include "hb-ot-cmap-table.hh" 36 #include "hb-ot-glyf-table.hh" 37 #include "hb-ot-cff1-table.hh" 38 #include "hb-ot-cff2-table.hh" 39 #include "hb-ot-hmtx-table.hh" 40 #include "hb-ot-kern-table.hh" 41 #include "hb-ot-os2-table.hh" 42 #include "hb-ot-post-table.hh" 43 #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. 44 #include "hb-ot-vorg-table.hh" 45 #include "hb-ot-color-cbdt-table.hh" 46 #include "hb-ot-color-sbix-table.hh" 47 48 49 /** 50 * SECTION:hb-ot-font 51 * @title: hb-ot-font 52 * @short_description: OpenType font implementation 53 * @include: hb-ot.h 54 * 55 * Functions for using OpenType fonts with hb_shape(). Not that fonts returned 56 * by hb_font_create() default to using these functions, so most clients would 57 * never need to call these functions directly. 58 **/ 59 60 61 static hb_bool_t 62 hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, 63 void *font_data, 64 hb_codepoint_t unicode, 65 hb_codepoint_t *glyph, 66 void *user_data HB_UNUSED) 67 { 68 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 69 return ot_face->cmap->get_nominal_glyph (unicode, glyph); 70 } 71 72 static unsigned int 73 hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, 74 void *font_data, 75 unsigned int count, 76 const hb_codepoint_t *first_unicode, 77 unsigned int unicode_stride, 78 hb_codepoint_t *first_glyph, 79 unsigned int glyph_stride, 80 void *user_data HB_UNUSED) 81 { 82 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 83 return ot_face->cmap->get_nominal_glyphs (count, 84 first_unicode, unicode_stride, 85 first_glyph, glyph_stride); 86 } 87 88 static hb_bool_t 89 hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, 90 void *font_data, 91 hb_codepoint_t unicode, 92 hb_codepoint_t variation_selector, 93 hb_codepoint_t *glyph, 94 void *user_data HB_UNUSED) 95 { 96 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 97 return ot_face->cmap->get_variation_glyph (unicode, variation_selector, glyph); 98 } 99 100 static void 101 hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, 102 unsigned count, 103 const hb_codepoint_t *first_glyph, 104 unsigned glyph_stride, 105 hb_position_t *first_advance, 106 unsigned advance_stride, 107 void *user_data HB_UNUSED) 108 { 109 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 110 const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; 111 112 for (unsigned int i = 0; i < count; i++) 113 { 114 *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font)); 115 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); 116 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); 117 } 118 } 119 120 static void 121 hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, 122 unsigned count, 123 const hb_codepoint_t *first_glyph, 124 unsigned glyph_stride, 125 hb_position_t *first_advance, 126 unsigned advance_stride, 127 void *user_data HB_UNUSED) 128 { 129 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 130 const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; 131 132 for (unsigned int i = 0; i < count; i++) 133 { 134 *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font)); 135 first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); 136 first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); 137 } 138 } 139 140 static hb_bool_t 141 hb_ot_get_glyph_v_origin (hb_font_t *font, 142 void *font_data, 143 hb_codepoint_t glyph, 144 hb_position_t *x, 145 hb_position_t *y, 146 void *user_data HB_UNUSED) 147 { 148 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 149 150 *x = font->get_glyph_h_advance (glyph) / 2; 151 152 const OT::VORG &VORG = *ot_face->VORG; 153 if (VORG.has_data ()) 154 { 155 *y = font->em_scale_y (VORG.get_y_origin (glyph)); 156 return true; 157 } 158 159 hb_glyph_extents_t extents = {0}; 160 if (ot_face->glyf->get_extents (glyph, &extents)) 161 { 162 const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; 163 hb_position_t tsb = vmtx.get_side_bearing (glyph); 164 *y = font->em_scale_y (extents.y_bearing + tsb); 165 return true; 166 } 167 168 hb_font_extents_t font_extents; 169 font->get_h_extents_with_fallback (&font_extents); 170 *y = font_extents.ascender; 171 172 return true; 173 } 174 175 static hb_bool_t 176 hb_ot_get_glyph_extents (hb_font_t *font, 177 void *font_data, 178 hb_codepoint_t glyph, 179 hb_glyph_extents_t *extents, 180 void *user_data HB_UNUSED) 181 { 182 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 183 bool ret = ot_face->sbix->get_extents (font, glyph, extents); 184 if (!ret) 185 ret = ot_face->glyf->get_extents (glyph, extents); 186 if (!ret) 187 ret = ot_face->cff1->get_extents (glyph, extents); 188 if (!ret) 189 ret = ot_face->cff2->get_extents (font, glyph, extents); 190 if (!ret) 191 ret = ot_face->CBDT->get_extents (font, glyph, extents); 192 // TODO Hook up side-bearings variations. 193 extents->x_bearing = font->em_scale_x (extents->x_bearing); 194 extents->y_bearing = font->em_scale_y (extents->y_bearing); 195 extents->width = font->em_scale_x (extents->width); 196 extents->height = font->em_scale_y (extents->height); 197 return ret; 198 } 199 200 static hb_bool_t 201 hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, 202 void *font_data, 203 hb_codepoint_t glyph, 204 char *name, unsigned int size, 205 void *user_data HB_UNUSED) 206 { 207 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 208 return ot_face->post->get_glyph_name (glyph, name, size); 209 } 210 211 static hb_bool_t 212 hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, 213 void *font_data, 214 const char *name, int len, 215 hb_codepoint_t *glyph, 216 void *user_data HB_UNUSED) 217 { 218 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 219 return ot_face->post->get_glyph_from_name (name, len, glyph); 220 } 221 222 static hb_bool_t 223 hb_ot_get_font_h_extents (hb_font_t *font, 224 void *font_data, 225 hb_font_extents_t *metrics, 226 void *user_data HB_UNUSED) 227 { 228 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 229 const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; 230 metrics->ascender = font->em_scale_y (hmtx.ascender); 231 metrics->descender = font->em_scale_y (hmtx.descender); 232 metrics->line_gap = font->em_scale_y (hmtx.line_gap); 233 // TODO Hook up variations. 234 return hmtx.has_font_extents; 235 } 236 237 static hb_bool_t 238 hb_ot_get_font_v_extents (hb_font_t *font, 239 void *font_data, 240 hb_font_extents_t *metrics, 241 void *user_data HB_UNUSED) 242 { 243 const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; 244 const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; 245 metrics->ascender = font->em_scale_x (vmtx.ascender); 246 metrics->descender = font->em_scale_x (vmtx.descender); 247 metrics->line_gap = font->em_scale_x (vmtx.line_gap); 248 // TODO Hook up variations. 249 return vmtx.has_font_extents; 250 } 251 252 #if HB_USE_ATEXIT 253 static void free_static_ot_funcs (); 254 #endif 255 256 static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t> 257 { 258 static hb_font_funcs_t *create () 259 { 260 hb_font_funcs_t *funcs = hb_font_funcs_create (); 261 262 hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); 263 hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); 264 hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr); 265 hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr); 266 hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr); 267 hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr); 268 hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); 269 //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); 270 hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); 271 hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); 272 //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); 273 hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); 274 hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr); 275 276 hb_font_funcs_make_immutable (funcs); 277 278 #if HB_USE_ATEXIT 279 atexit (free_static_ot_funcs); 280 #endif 281 282 return funcs; 283 } 284 } static_ot_funcs; 285 286 #if HB_USE_ATEXIT 287 static 288 void free_static_ot_funcs () 289 { 290 static_ot_funcs.free_instance (); 291 } 292 #endif 293 294 static hb_font_funcs_t * 295 _hb_ot_get_font_funcs () 296 { 297 return static_ot_funcs.get_unconst (); 298 } 299 300 301 /** 302 * hb_ot_font_set_funcs: 303 * 304 * Since: 0.9.28 305 **/ 306 void 307 hb_ot_font_set_funcs (hb_font_t *font) 308 { 309 hb_font_set_funcs (font, 310 _hb_ot_get_font_funcs (), 311 &font->face->table, 312 nullptr); 313 }