MATH Table: Add API to access glyph info.
diff --git a/src/hb-ot-layout-math-table.hh b/src/hb-ot-layout-math-table.hh
index e65680b..2eb0d92 100644
--- a/src/hb-ot-layout-math-table.hh
+++ b/src/hb-ot-layout-math-table.hh
@@ -159,6 +159,267 @@
DEFINE_SIZE_STATIC (214);
};
+struct MathItalicsCorrectionInfo
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ coverage.sanitize (c, this) &&
+ italicsCorrection.sanitize (c, this));
+ }
+
+ inline bool get_value (hb_font_t *font, hb_codepoint_t glyph,
+ hb_position_t &value) const
+ {
+ unsigned int index = (this+coverage).get_coverage (glyph);
+ if (likely (index == NOT_COVERED)) return false;
+ if (unlikely (index >= italicsCorrection.len)) return false;
+ value = italicsCorrection[index].get_x_value(font, this);
+ return true;
+ }
+
+protected:
+ OffsetTo<Coverage> coverage; /* Offset to Coverage table -
+ from the beginning of
+ MathItalicsCorrectionInfo
+ table. */
+ ArrayOf<MathValueRecord> italicsCorrection; /* Array of MathValueRecords
+ defining italics correction
+ values for each
+ covered glyph. */
+
+public:
+ DEFINE_SIZE_ARRAY (2 + 2, italicsCorrection);
+};
+
+struct MathTopAccentAttachment
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ topAccentCoverage.sanitize (c, this) &&
+ topAccentAttachment.sanitize (c, this));
+ }
+
+ inline bool get_value (hb_font_t *font, hb_codepoint_t glyph,
+ hb_position_t &value) const
+ {
+ unsigned int index = (this+topAccentCoverage).get_coverage (glyph);
+ if (likely (index == NOT_COVERED)) return false;
+ if (unlikely (index >= topAccentAttachment.len)) return false;
+ value = topAccentAttachment[index].get_x_value(font, this);
+ return true;
+ }
+
+protected:
+ OffsetTo<Coverage> topAccentCoverage; /* Offset to Coverage table -
+ from the beginning of
+ MathTopAccentAttachment
+ table. */
+ ArrayOf<MathValueRecord> topAccentAttachment; /* Array of MathValueRecords
+ defining top accent
+ attachment points for each
+ covered glyph. */
+
+public:
+ DEFINE_SIZE_ARRAY (2 + 2, topAccentAttachment);
+};
+
+struct MathKern
+{
+ inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ unsigned int count = 2 * heightCount + 1;
+ for (unsigned int i = 0; i < count; i++)
+ if (!mathValueRecords[i].sanitize (c, this)) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ c->check_array (mathValueRecords,
+ mathValueRecords[0].static_size,
+ 2 * heightCount + 1) &&
+ sanitize_math_value_records (c));
+ }
+
+ inline hb_position_t get_value (hb_font_t *font,
+ hb_position_t &correction_height) const
+ {
+ const MathValueRecord* correctionHeight = mathValueRecords;
+ const MathValueRecord* kernValue = mathValueRecords + heightCount;
+ // The description of the MathKern table is a ambiguous, but interpreting
+ // "between the two heights found at those indexes" for 0 < i < len as
+ //
+ // correctionHeight[i-1] < correction_height <= correctionHeight[i]
+ //
+ // makes the result consistent with the limit cases and we can just use the
+ // binary search algorithm of std::upper_bound:
+ unsigned int count = heightCount;
+ unsigned int i = 0;
+ while (count > 0) {
+ unsigned int half = count / 2;
+ hb_position_t height =
+ correctionHeight[i + half].get_y_value(font, this);
+ if (height < correction_height) {
+ i += half + 1;
+ count -= half + 1;
+ } else
+ count = half;
+ }
+ return kernValue[i].get_x_value(font, this);
+ }
+
+protected:
+ USHORT heightCount;
+ MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at
+ which the kern value changes.
+ Sorted by the height value in
+ design units. */
+ /* Array of kern values corresponding
+ to heights. */
+
+public:
+ DEFINE_SIZE_ARRAY (2, mathValueRecords);
+};
+
+struct MathKernInfoRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ mathKern[HB_OT_MATH_KERN_TOP_RIGHT].sanitize (c, base) &&
+ mathKern[HB_OT_MATH_KERN_TOP_LEFT].sanitize (c, base) &&
+ mathKern[HB_OT_MATH_KERN_BOTTOM_RIGHT].sanitize (c, base) &&
+ mathKern[HB_OT_MATH_KERN_BOTTOM_LEFT].sanitize (c, base));
+ }
+
+ inline bool has_math_kern (hb_ot_math_kern_t kern) const {
+ return mathKern[kern] != 0;
+ }
+ inline const MathKern &get_math_kern (hb_ot_math_kern_t kern,
+ const void *base) const {
+ return base+mathKern[kern];
+ }
+
+protected:
+ /* Offset to MathKern table for each corner -
+ from the beginning of MathKernInfo table. May be NULL. */
+ OffsetTo<MathKern> mathKern[HB_OT_MATH_KERN_BOTTOM_LEFT -
+ HB_OT_MATH_KERN_TOP_RIGHT + 1];
+
+public:
+ DEFINE_SIZE_STATIC (2 * (HB_OT_MATH_KERN_BOTTOM_LEFT -
+ HB_OT_MATH_KERN_TOP_RIGHT + 1));
+};
+
+struct MathKernInfo
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ mathKernCoverage.sanitize (c, this) &&
+ mathKernInfoRecords.sanitize (c, this));
+ }
+
+ inline bool
+ get_math_kern_info_record (hb_codepoint_t glyph,
+ const MathKernInfoRecord *&record) const
+ {
+ unsigned int index = (this+mathKernCoverage).get_coverage (glyph);
+ if (likely (index == NOT_COVERED)) return false;
+ if (unlikely (index >= mathKernInfoRecords.len)) return false;
+ record = &mathKernInfoRecords[index];
+ return true;
+ }
+
+protected:
+ OffsetTo<Coverage> mathKernCoverage; /* Offset to Coverage table -
+ from the beginning of the
+ MathKernInfo table. */
+ ArrayOf<MathKernInfoRecord> mathKernInfoRecords; /* Array of
+ MathKernInfoRecords,
+ per-glyph information for
+ mathematical positioning
+ of subscripts and
+ superscripts. */
+
+public:
+ DEFINE_SIZE_ARRAY (2 + 2, mathKernInfoRecords);
+};
+
+struct MathGlyphInfo
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ mathItalicsCorrectionInfo.sanitize (c, this) &&
+ mathTopAccentAttachment.sanitize (c, this) &&
+ extendedShapeCoverage.sanitize (c, this) &&
+ mathKernInfo.sanitize(c, this));
+ }
+
+ inline bool has_math_italics_correction_info (void) const {
+ return mathItalicsCorrectionInfo != 0;
+ }
+ inline const MathItalicsCorrectionInfo&
+ get_math_italics_correction_info (void) const {
+ return this+mathItalicsCorrectionInfo;
+ }
+
+ inline bool has_math_top_accent_attachment (void) const {
+ return mathTopAccentAttachment != 0;
+ }
+ inline const MathTopAccentAttachment&
+ get_math_top_accent_attachment (void) const {
+ return this+mathTopAccentAttachment;
+ }
+
+ inline bool is_extended_shape (hb_codepoint_t glyph) const
+ {
+ if (likely (extendedShapeCoverage == 0)) return false;
+ unsigned int index = (this+extendedShapeCoverage).get_coverage (glyph);
+ if (likely (index == NOT_COVERED)) return false;
+ return true;
+ }
+
+ inline bool has_math_kern_info (void) const { return mathKernInfo != 0; }
+ inline const MathKernInfo &get_math_kern_info (void) const {
+ return this+mathKernInfo;
+ }
+
+protected:
+ /* Offset to MathItalicsCorrectionInfo table -
+ from the beginning of MathGlyphInfo table. */
+ OffsetTo<MathItalicsCorrectionInfo> mathItalicsCorrectionInfo;
+
+ /* Offset to MathTopAccentAttachment table -
+ from the beginning of MathGlyphInfo table. */
+ OffsetTo<MathTopAccentAttachment> mathTopAccentAttachment;
+
+ /* Offset to coverage table for Extended Shape glyphs -
+ from the beginning of MathGlyphInfo table. When the left or right glyph of
+ a box is an extended shape variant, the (ink) box (and not the default
+ position defined by values in MathConstants table) should be used for
+ vertical positioning purposes. May be NULL.. */
+ OffsetTo<Coverage> extendedShapeCoverage;
+
+ /* Offset to MathKernInfo table -
+ from the beginning of MathGlyphInfo table. */
+ OffsetTo<MathKernInfo> mathKernInfo;
+
+public:
+ DEFINE_SIZE_STATIC (4 * 2);
+};
+
/*
* MATH -- The MATH Table
*/
@@ -172,7 +433,8 @@
TRACE_SANITIZE (this);
return_trace (version.sanitize (c) &&
likely (version.major == 1) &&
- mathConstants.sanitize (c, this));
+ mathConstants.sanitize (c, this) &&
+ mathGlyphInfo.sanitize (c, this));
}
inline bool has_math_constants (void) const { return mathConstants != 0; }
@@ -180,13 +442,18 @@
return this+mathConstants;
}
+ inline bool has_math_glyph_info (void) const { return mathGlyphInfo != 0; }
+ inline const MathGlyphInfo &get_math_glyph_info (void) const {
+ return this+mathGlyphInfo;
+ }
protected:
FixedVersion<>version; /* Version of the MATH table
* initially set to 0x00010000u */
OffsetTo<MathConstants> mathConstants; /* MathConstants table */
+ OffsetTo<MathGlyphInfo> mathGlyphInfo; /* MathGlyphInfo table */
public:
- DEFINE_SIZE_STATIC (6);
+ DEFINE_SIZE_STATIC (8);
};
} /* mathspace OT */