hb-ot-math.cc (12300B)
1 /* 2 * Copyright © 2016 Igalia S.L. 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 * Igalia Author(s): Frédéric Wang 25 */ 26 27 #include "hb.hh" 28 29 #ifndef HB_NO_MATH 30 31 #include "hb-ot-math-table.hh" 32 33 34 /** 35 * SECTION:hb-ot-math 36 * @title: hb-ot-math 37 * @short_description: OpenType Math information 38 * @include: hb-ot.h 39 * 40 * Functions for fetching mathematics layout data from OpenType fonts. 41 * 42 * HarfBuzz itself does not implement a math layout solution. The 43 * functions and types provided can be used by client programs to access 44 * the font data necessary for typesetting OpenType Math layout. 45 * 46 **/ 47 48 49 /* 50 * OT::MATH 51 */ 52 53 /** 54 * hb_ot_math_has_data: 55 * @face: #hb_face_t to test 56 * 57 * Tests whether a face has a `MATH` table. 58 * 59 * Return value: `true` if the table is found, `false` otherwise 60 * 61 * Since: 1.3.3 62 **/ 63 hb_bool_t 64 hb_ot_math_has_data (hb_face_t *face) 65 { 66 return face->table.MATH->has_data (); 67 } 68 69 /** 70 * hb_ot_math_get_constant: 71 * @font: #hb_font_t to work upon 72 * @constant: #hb_ot_math_constant_t the constant to retrieve 73 * 74 * Fetches the specified math constant. For most constants, the value returned 75 * is an #hb_position_t. 76 * 77 * However, if the requested constant is #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, 78 * #HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or 79 * #HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT, then the return value is 80 * an integer between 0 and 100 representing that percentage. 81 * 82 * Return value: the requested constant or zero 83 * 84 * Since: 1.3.3 85 **/ 86 hb_position_t 87 hb_ot_math_get_constant (hb_font_t *font, 88 hb_ot_math_constant_t constant) 89 { 90 /* https://github.com/harfbuzz/harfbuzz/issues/4653 91 * Cambria Math has incorrect value for displayOperatorMinHeight, and 92 * apparently Microsoft implementation swaps displayOperatorMinHeight and 93 * delimitedSubFormulaMinHeight, so we do the same if we detect Cambria Math 94 * with the swapped values. */ 95 if ((constant == HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT || 96 constant == HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT) && 97 font->face->table.MATH->is_bad_cambria (font)) 98 { 99 if (constant == HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT) 100 constant = HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT; 101 else 102 constant = HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT; 103 } 104 return font->face->table.MATH->get_constant(constant, font); 105 } 106 107 /** 108 * hb_ot_math_get_glyph_italics_correction: 109 * @font: #hb_font_t to work upon 110 * @glyph: The glyph index from which to retrieve the value 111 * 112 * Fetches an italics-correction value (if one exists) for the specified 113 * glyph index. 114 * 115 * Return value: the italics correction of the glyph or zero 116 * 117 * Since: 1.3.3 118 **/ 119 hb_position_t 120 hb_ot_math_get_glyph_italics_correction (hb_font_t *font, 121 hb_codepoint_t glyph) 122 { 123 return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font); 124 } 125 126 /** 127 * hb_ot_math_get_glyph_top_accent_attachment: 128 * @font: #hb_font_t to work upon 129 * @glyph: The glyph index from which to retrieve the value 130 * 131 * Fetches a top-accent-attachment value (if one exists) for the specified 132 * glyph index. 133 * 134 * For any glyph that does not have a top-accent-attachment value - that is, 135 * a glyph not covered by the `MathTopAccentAttachment` table (or, when 136 * @font has no `MathTopAccentAttachment` table or no `MATH` table, any 137 * glyph) - the function synthesizes a value, returning the position at 138 * one-half the glyph's advance width. 139 * 140 * Return value: the top accent attachment of the glyph or 0.5 * the advance 141 * width of @glyph 142 * 143 * Since: 1.3.3 144 **/ 145 hb_position_t 146 hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, 147 hb_codepoint_t glyph) 148 { 149 return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font); 150 } 151 152 /** 153 * hb_ot_math_is_glyph_extended_shape: 154 * @face: #hb_face_t to work upon 155 * @glyph: The glyph index to test 156 * 157 * Tests whether the given glyph index is an extended shape in the face. 158 * 159 * Return value: `true` if the glyph is an extended shape, `false` otherwise 160 * 161 * Since: 1.3.3 162 **/ 163 hb_bool_t 164 hb_ot_math_is_glyph_extended_shape (hb_face_t *face, 165 hb_codepoint_t glyph) 166 { 167 return face->table.MATH->get_glyph_info().is_extended_shape (glyph); 168 } 169 170 /** 171 * hb_ot_math_get_glyph_kerning: 172 * @font: #hb_font_t to work upon 173 * @glyph: The glyph index from which to retrieve the value 174 * @kern: The #hb_ot_math_kern_t from which to retrieve the value 175 * @correction_height: the correction height to use to determine the kerning. 176 * 177 * Fetches the math kerning (cut-ins) value for the specified font, glyph index, and 178 * @kern. 179 * 180 * If the MathKern table is found, the function examines it to find a height 181 * value that is greater or equal to @correction_height. If such a height 182 * value is found, corresponding kerning value from the table is returned. If 183 * no such height value is found, the last kerning value is returned. 184 * 185 * Return value: requested kerning value or zero 186 * 187 * Since: 1.3.3 188 **/ 189 hb_position_t 190 hb_ot_math_get_glyph_kerning (hb_font_t *font, 191 hb_codepoint_t glyph, 192 hb_ot_math_kern_t kern, 193 hb_position_t correction_height) 194 { 195 return font->face->table.MATH->get_glyph_info().get_kerning (glyph, 196 kern, 197 correction_height, 198 font); 199 } 200 201 /** 202 * hb_ot_math_get_glyph_kernings: 203 * @font: #hb_font_t to work upon 204 * @glyph: The glyph index from which to retrieve the kernings 205 * @kern: The #hb_ot_math_kern_t from which to retrieve the kernings 206 * @start_offset: offset of the first kern entry to retrieve 207 * @entries_count: (inout) (optional): Input = the maximum number of kern entries to return; 208 * Output = the actual number of kern entries returned 209 * @kern_entries: (out caller-allocates) (array length=entries_count): array of kern entries returned 210 * 211 * Fetches the raw MathKern (cut-in) data for the specified font, glyph index, 212 * and @kern. The corresponding list of kern values and correction heights is 213 * returned as a list of #hb_ot_math_kern_entry_t structs. 214 * 215 * See also #hb_ot_math_get_glyph_kerning, which handles selecting the 216 * appropriate kern value for a given correction height. 217 * 218 * <note>For a glyph with @n defined kern values (where @n > 0), there are only 219 * @n−1 defined correction heights, as each correction height defines a boundary 220 * past which the next kern value should be selected. Therefore, only the 221 * #hb_ot_math_kern_entry_t.kern_value of the uppermost #hb_ot_math_kern_entry_t 222 * actually comes from the font; its corresponding 223 * #hb_ot_math_kern_entry_t.max_correction_height is always set to 224 * <code>INT32_MAX</code>.</note> 225 * 226 * Return value: the total number of kern values available or zero 227 * 228 * Since: 3.4.0 229 **/ 230 unsigned int 231 hb_ot_math_get_glyph_kernings (hb_font_t *font, 232 hb_codepoint_t glyph, 233 hb_ot_math_kern_t kern, 234 unsigned int start_offset, 235 unsigned int *entries_count, /* IN/OUT */ 236 hb_ot_math_kern_entry_t *kern_entries /* OUT */) 237 { 238 return font->face->table.MATH->get_glyph_info().get_kernings (glyph, 239 kern, 240 start_offset, 241 entries_count, 242 kern_entries, 243 font); 244 } 245 246 /** 247 * hb_ot_math_get_glyph_variants: 248 * @font: #hb_font_t to work upon 249 * @glyph: The index of the glyph to stretch 250 * @direction: The direction of the stretching (horizontal or vertical) 251 * @start_offset: offset of the first variant to retrieve 252 * @variants_count: (inout): Input = the maximum number of variants to return; 253 * Output = the actual number of variants returned 254 * @variants: (out) (array length=variants_count): array of variants returned 255 * 256 * Fetches the MathGlyphConstruction for the specified font, glyph index, and 257 * direction. The corresponding list of size variants is returned as a list of 258 * #hb_ot_math_glyph_variant_t structs. 259 * 260 * <note>The @direction parameter is only used to select between horizontal 261 * or vertical directions for the construction. Even though all #hb_direction_t 262 * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is 263 * considered.</note> 264 * 265 * Return value: the total number of size variants available or zero 266 * 267 * Since: 1.3.3 268 **/ 269 unsigned int 270 hb_ot_math_get_glyph_variants (hb_font_t *font, 271 hb_codepoint_t glyph, 272 hb_direction_t direction, 273 unsigned int start_offset, 274 unsigned int *variants_count, /* IN/OUT */ 275 hb_ot_math_glyph_variant_t *variants /* OUT */) 276 { 277 return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font, 278 start_offset, 279 variants_count, 280 variants); 281 } 282 283 /** 284 * hb_ot_math_get_min_connector_overlap: 285 * @font: #hb_font_t to work upon 286 * @direction: direction of the stretching (horizontal or vertical) 287 * 288 * Fetches the MathVariants table for the specified font and returns the 289 * minimum overlap of connecting glyphs that are required to draw a glyph 290 * assembly in the specified direction. 291 * 292 * <note>The @direction parameter is only used to select between horizontal 293 * or vertical directions for the construction. Even though all #hb_direction_t 294 * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is 295 * considered.</note> 296 * 297 * Return value: requested minimum connector overlap or zero 298 * 299 * Since: 1.3.3 300 **/ 301 hb_position_t 302 hb_ot_math_get_min_connector_overlap (hb_font_t *font, 303 hb_direction_t direction) 304 { 305 return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font); 306 } 307 308 /** 309 * hb_ot_math_get_glyph_assembly: 310 * @font: #hb_font_t to work upon 311 * @glyph: The index of the glyph to stretch 312 * @direction: direction of the stretching (horizontal or vertical) 313 * @start_offset: offset of the first glyph part to retrieve 314 * @parts_count: (inout): Input = maximum number of glyph parts to return; 315 * Output = actual number of parts returned 316 * @parts: (out) (array length=parts_count): the glyph parts returned 317 * @italics_correction: (out): italics correction of the glyph assembly 318 * 319 * Fetches the GlyphAssembly for the specified font, glyph index, and direction. 320 * Returned are a list of #hb_ot_math_glyph_part_t glyph parts that can be 321 * used to draw the glyph and an italics-correction value (if one is defined 322 * in the font). 323 * 324 * <note>The @direction parameter is only used to select between horizontal 325 * or vertical directions for the construction. Even though all #hb_direction_t 326 * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is 327 * considered.</note> 328 * 329 * Return value: the total number of parts in the glyph assembly 330 * 331 * Since: 1.3.3 332 **/ 333 unsigned int 334 hb_ot_math_get_glyph_assembly (hb_font_t *font, 335 hb_codepoint_t glyph, 336 hb_direction_t direction, 337 unsigned int start_offset, 338 unsigned int *parts_count, /* IN/OUT */ 339 hb_ot_math_glyph_part_t *parts, /* OUT */ 340 hb_position_t *italics_correction /* OUT */) 341 { 342 return font->face->table.MATH->get_variants().get_glyph_parts (glyph, 343 direction, 344 font, 345 start_offset, 346 parts_count, 347 parts, 348 italics_correction); 349 } 350 351 352 #endif