2 * Copyright © 2018-2019 Ebrahim Byagowi
4 * This is part of HarfBuzz, a text shaping library.
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.
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
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.
27 #include "hb-ot-var-mvar-table.hh"
28 #include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
29 #include "hb-ot-os2-table.hh"
30 #include "hb-ot-post-table.hh"
31 #include "hb-ot-hhea-table.hh"
32 #include "hb-ot-metrics.hh"
33 #include "hb-ot-face.hh"
37 _fix_ascender_descender (float value, hb_ot_metrics_t metrics_tag)
39 if (metrics_tag == HB_OT_METRICS_HORIZONTAL_ASCENDER ||
40 metrics_tag == HB_OT_METRICS_VERTICAL_ASCENDER)
41 return fabs ((double) value);
42 if (metrics_tag == HB_OT_METRICS_HORIZONTAL_DESCENDER ||
43 metrics_tag == HB_OT_METRICS_VERTICAL_DESCENDER)
44 return -fabs ((double) value);
48 /* The common part of _get_position logic needed on hb-ot-font and here
49 to be able to have slim builds without the not always needed parts */
51 hb_ot_metrics_get_position_common (hb_font_t *font,
52 hb_ot_metrics_t metrics_tag,
53 hb_position_t *position /* OUT. May be NULL. */)
55 hb_face_t *face = font->face;
56 switch ((unsigned int) metrics_tag)
59 #define GET_VAR hb_ot_metrics_get_variation (face, metrics_tag)
63 #define GET_METRIC_X(TABLE, ATTR) \
64 (face->table.TABLE->has_data () && \
65 (position && (*position = font->em_scalef_x (_fix_ascender_descender ( \
66 face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
67 #define GET_METRIC_Y(TABLE, ATTR) \
68 (face->table.TABLE->has_data () && \
69 (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \
70 face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
71 case HB_OT_METRICS_HORIZONTAL_ASCENDER:
72 return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) ||
73 GET_METRIC_Y (hhea, ascender);
74 case HB_OT_METRICS_HORIZONTAL_DESCENDER:
75 return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoDescender)) ||
76 GET_METRIC_Y (hhea, descender);
77 case HB_OT_METRICS_HORIZONTAL_LINE_GAP:
78 return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoLineGap)) ||
79 GET_METRIC_Y (hhea, lineGap);
80 case HB_OT_METRICS_VERTICAL_ASCENDER: return GET_METRIC_X (vhea, ascender);
81 case HB_OT_METRICS_VERTICAL_DESCENDER: return GET_METRIC_X (vhea, descender);
82 case HB_OT_METRICS_VERTICAL_LINE_GAP: return GET_METRIC_X (vhea, lineGap);
86 default: assert (0); return false;
94 _get_gasp (hb_face_t *face, float *result, hb_ot_metrics_t metrics_tag)
96 const OT::GaspRange& range = face->table.gasp->get_gasp_range (metrics_tag - HB_TAG ('g','s','p','0'));
97 if (&range == &Null (OT::GaspRange)) return false;
98 if (result) *result = range.rangeMaxPPEM + face->table.MVAR->get_var (metrics_tag, nullptr, 0);
104 * hb_ot_metrics_get_position:
105 * @font: a #hb_font_t object.
106 * @metrics_tag: tag of metrics value you like to fetch.
107 * @position: (out) (optional): result of metrics value from the font.
109 * It fetches metrics value corresponding to a given tag from a font.
111 * Returns: Whether found the requested metrics in the font.
115 hb_ot_metrics_get_position (hb_font_t *font,
116 hb_ot_metrics_t metrics_tag,
117 hb_position_t *position /* OUT. May be NULL. */)
119 hb_face_t *face = font->face;
122 case HB_OT_METRICS_HORIZONTAL_ASCENDER:
123 case HB_OT_METRICS_HORIZONTAL_DESCENDER:
124 case HB_OT_METRICS_HORIZONTAL_LINE_GAP:
125 case HB_OT_METRICS_VERTICAL_ASCENDER:
126 case HB_OT_METRICS_VERTICAL_DESCENDER:
127 case HB_OT_METRICS_VERTICAL_LINE_GAP: return hb_ot_metrics_get_position_common (font, metrics_tag, position);
129 #define GET_VAR hb_ot_metrics_get_variation (face, metrics_tag)
133 #define GET_METRIC_X(TABLE, ATTR) \
134 (face->table.TABLE->has_data () && \
135 (position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR)), true))
136 #define GET_METRIC_Y(TABLE, ATTR) \
137 (face->table.TABLE->has_data () && \
138 (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true))
139 case HB_OT_METRICS_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent);
140 case HB_OT_METRICS_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
141 case HB_OT_METRICS_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise);
142 case HB_OT_METRICS_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun);
143 case HB_OT_METRICS_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
144 case HB_OT_METRICS_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
145 case HB_OT_METRICS_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun);
146 case HB_OT_METRICS_VERTICAL_CARET_OFFSET: return GET_METRIC_Y (vhea, caretOffset);
147 case HB_OT_METRICS_X_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sxHeight);
148 case HB_OT_METRICS_CAP_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sCapHeight);
149 case HB_OT_METRICS_SUBSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySubscriptXSize);
150 case HB_OT_METRICS_SUBSCRIPT_EM_Y_SIZE: return GET_METRIC_Y (OS2, ySubscriptYSize);
151 case HB_OT_METRICS_SUBSCRIPT_EM_X_OFFSET: return GET_METRIC_X (OS2, ySubscriptXOffset);
152 case HB_OT_METRICS_SUBSCRIPT_EM_Y_OFFSET: return GET_METRIC_Y (OS2, ySubscriptYOffset);
153 case HB_OT_METRICS_SUPERSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySuperscriptXSize);
154 case HB_OT_METRICS_SUPERSCRIPT_EM_Y_SIZE: return GET_METRIC_Y (OS2, ySuperscriptYSize);
155 case HB_OT_METRICS_SUPERSCRIPT_EM_X_OFFSET: return GET_METRIC_X (OS2, ySuperscriptXOffset);
156 case HB_OT_METRICS_SUPERSCRIPT_EM_Y_OFFSET: return GET_METRIC_Y (OS2, ySuperscriptYOffset);
157 case HB_OT_METRICS_STRIKEOUT_SIZE: return GET_METRIC_Y (OS2, yStrikeoutSize);
158 case HB_OT_METRICS_STRIKEOUT_OFFSET: return GET_METRIC_Y (OS2, yStrikeoutPosition);
159 case HB_OT_METRICS_UNDERLINE_SIZE: return GET_METRIC_Y (post->table, underlineThickness);
160 case HB_OT_METRICS_UNDERLINE_OFFSET: return GET_METRIC_Y (post->table, underlinePosition);
164 default: return false;
170 * hb_ot_metrics_get_variation:
179 hb_ot_metrics_get_variation (hb_face_t *face, hb_ot_metrics_t metrics_tag)
181 return face->table.MVAR->get_var (metrics_tag, nullptr, 0);
185 * hb_ot_metrics_get_x_variation:
194 hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
196 return font->em_scalef_x (hb_ot_metrics_get_variation (font->face, metrics_tag));
200 * hb_ot_metrics_get_y_variation:
209 hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
211 return font->em_scalef_y (hb_ot_metrics_get_variation (font->face, metrics_tag));