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-open-type.hh"
  28 
  29 #include "hb-ot-face.hh"
  30 #include "hb-ot-math-table.hh"
  31 
  32 
  33 /**
  34  * SECTION:hb-ot-math
  35  * @title: hb-ot-math
  36  * @short_description: OpenType Math information
  37  * @include: hb-ot.h
  38  *
  39  * Functions for fetching mathematics layout data from OpenType fonts.
  40  **/
  41 
  42 
  43 /*
  44  * OT::MATH
  45  */
  46 
  47 /**
  48  * hb_ot_math_has_data:
  49  * @face: #hb_face_t to test
  50  *
  51  * This function allows to verify the presence of an OpenType MATH table on the
  52  * face.
  53  *
  54  * Return value: true if face has a MATH table, false otherwise
  55  *
  56  * Since: 1.3.3
  57  **/
  58 hb_bool_t
  59 hb_ot_math_has_data (hb_face_t *face)
  60 {
  61   return face->table.MATH->has_data ();
  62 }
  63 
  64 /**
  65  * hb_ot_math_get_constant:
  66  * @font: #hb_font_t from which to retrieve the value
  67  * @constant: #hb_ot_math_constant_t the constant to retrieve
  68  *
  69  * This function returns the requested math constants as a #hb_position_t.
  70  * If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
  71  * HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
  72  * HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is
  73  * actually an integer between 0 and 100 representing that percentage.
  74  *
  75  * Return value: the requested constant or 0
  76  *
  77  * Since: 1.3.3
  78  **/
  79 hb_position_t
  80 hb_ot_math_get_constant (hb_font_t *font,
  81                          hb_ot_math_constant_t constant)
  82 {
  83   return font->face->table.MATH->get_constant(constant, font);
  84 }
  85 
  86 /**
  87  * hb_ot_math_get_glyph_italics_correction:
  88  * @font: #hb_font_t from which to retrieve the value
  89  * @glyph: glyph index from which to retrieve the value
  90  *
  91  * Return value: the italics correction of the glyph or 0
  92  *
  93  * Since: 1.3.3
  94  **/
  95 hb_position_t
  96 hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
  97                                          hb_codepoint_t glyph)
  98 {
  99   return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font);
 100 }
 101 
 102 /**
 103  * hb_ot_math_get_glyph_top_accent_attachment:
 104  * @font: #hb_font_t from which to retrieve the value
 105  * @glyph: glyph index from which to retrieve the value
 106  *
 107  * Return value: the top accent attachment of the glyph or 0
 108  *
 109  * Since: 1.3.3
 110  **/
 111 hb_position_t
 112 hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
 113                                             hb_codepoint_t glyph)
 114 {
 115   return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font);
 116 }
 117 
 118 /**
 119  * hb_ot_math_is_glyph_extended_shape:
 120  * @face: a #hb_face_t to test
 121  * @glyph: a glyph index to test
 122  *
 123  * Return value: true if the glyph is an extended shape, false otherwise
 124  *
 125  * Since: 1.3.3
 126  **/
 127 hb_bool_t
 128 hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
 129                                     hb_codepoint_t glyph)
 130 {
 131   return face->table.MATH->get_glyph_info().is_extended_shape (glyph);
 132 }
 133 
 134 /**
 135  * hb_ot_math_get_glyph_kerning:
 136  * @font: #hb_font_t from which to retrieve the value
 137  * @glyph: glyph index from which to retrieve the value
 138  * @kern: the #hb_ot_math_kern_t from which to retrieve the value
 139  * @correction_height: the correction height to use to determine the kerning.
 140  *
 141  * This function tries to retrieve the MathKern table for the specified font,
 142  * glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the
 143  * MathKern table to find one value that is greater or equal to specified
 144  * correction_height. If one is found the corresponding value from the list of
 145  * kerns is returned and otherwise the last kern value is returned.
 146  *
 147  * Return value: requested kerning or 0
 148  *
 149  * Since: 1.3.3
 150  **/
 151 hb_position_t
 152 hb_ot_math_get_glyph_kerning (hb_font_t *font,
 153                               hb_codepoint_t glyph,
 154                               hb_ot_math_kern_t kern,
 155                               hb_position_t correction_height)
 156 {
 157   return font->face->table.MATH->get_glyph_info().get_kerning (glyph,
 158                                                                kern,
 159                                                                correction_height,
 160                                                                font);
 161 }
 162 
 163 /**
 164  * hb_ot_math_get_glyph_variants:
 165  * @font: #hb_font_t from which to retrieve the values
 166  * @glyph: index of the glyph to stretch
 167  * @direction: direction of the stretching
 168  * @start_offset: offset of the first variant to retrieve
 169  * @variants_count: maximum number of variants to retrieve after start_offset
 170  * (IN) and actual number of variants retrieved (OUT)
 171  * @variants: array of size at least @variants_count to store the result
 172  *
 173  * This function tries to retrieve the MathGlyphConstruction for the specified
 174  * font, glyph and direction. Note that only the value of
 175  * #HB_DIRECTION_IS_HORIZONTAL is considered. It provides the corresponding list
 176  * of size variants as an array of hb_ot_math_glyph_variant_t structs.
 177  *
 178  * Return value: the total number of size variants available or 0
 179  *
 180  * Since: 1.3.3
 181  **/
 182 unsigned int
 183 hb_ot_math_get_glyph_variants (hb_font_t *font,
 184                                hb_codepoint_t glyph,
 185                                hb_direction_t direction,
 186                                unsigned int start_offset,
 187                                unsigned int *variants_count, /* IN/OUT */
 188                                hb_ot_math_glyph_variant_t *variants /* OUT */)
 189 {
 190   return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font,
 191                                                                     start_offset,
 192                                                                     variants_count,
 193                                                                     variants);
 194 }
 195 
 196 /**
 197  * hb_ot_math_get_min_connector_overlap:
 198  * @font: #hb_font_t from which to retrieve the value
 199  * @direction: direction of the stretching
 200  *
 201  * This function tries to retrieve the MathVariants table for the specified
 202  * font and returns the minimum overlap of connecting glyphs to draw a glyph
 203  * assembly in the specified direction. Note that only the value of
 204  * #HB_DIRECTION_IS_HORIZONTAL is considered.
 205  *
 206  * Return value: requested min connector overlap or 0
 207  *
 208  * Since: 1.3.3
 209  **/
 210 hb_position_t
 211 hb_ot_math_get_min_connector_overlap (hb_font_t *font,
 212                                       hb_direction_t direction)
 213 {
 214   return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font);
 215 }
 216 
 217 /**
 218  * hb_ot_math_get_glyph_assembly:
 219  * @font: #hb_font_t from which to retrieve the values
 220  * @glyph: index of the glyph to stretch
 221  * @direction: direction of the stretching
 222  * @start_offset: offset of the first glyph part to retrieve
 223  * @parts_count: maximum number of glyph parts to retrieve after start_offset
 224  * (IN) and actual number of parts retrieved (OUT)
 225  * @parts: array of size at least @parts_count to store the result
 226  * @italics_correction: italic correction of the glyph assembly
 227  *
 228  * This function tries to retrieve the GlyphAssembly for the specified font,
 229  * glyph and direction. Note that only the value of #HB_DIRECTION_IS_HORIZONTAL
 230  * is considered. It provides the information necessary to draw the glyph
 231  * assembly as an array of #hb_ot_math_glyph_part_t.
 232  *
 233  * Return value: the total number of parts in the glyph assembly
 234  *
 235  * Since: 1.3.3
 236  **/
 237 unsigned int
 238 hb_ot_math_get_glyph_assembly (hb_font_t *font,
 239                                hb_codepoint_t glyph,
 240                                hb_direction_t direction,
 241                                unsigned int start_offset,
 242                                unsigned int *parts_count, /* IN/OUT */
 243                                hb_ot_math_glyph_part_t *parts, /* OUT */
 244                                hb_position_t *italics_correction /* OUT */)
 245 {
 246   return font->face->table.MATH->get_variants().get_glyph_parts (glyph,
 247                                                                  direction,
 248                                                                  font,
 249                                                                  start_offset,
 250                                                                  parts_count,
 251                                                                  parts,
 252                                                                  italics_correction);
 253 }