MATH Table: Add API to access glyph info.
This commit is contained in:
parent
6fd2fe418d
commit
d7182d1296
|
@ -159,6 +159,267 @@ public:
|
||||||
DEFINE_SIZE_STATIC (214);
|
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
|
* MATH -- The MATH Table
|
||||||
*/
|
*/
|
||||||
|
@ -172,7 +433,8 @@ struct MATH
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (version.sanitize (c) &&
|
return_trace (version.sanitize (c) &&
|
||||||
likely (version.major == 1) &&
|
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; }
|
inline bool has_math_constants (void) const { return mathConstants != 0; }
|
||||||
|
@ -180,13 +442,18 @@ struct MATH
|
||||||
return this+mathConstants;
|
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:
|
protected:
|
||||||
FixedVersion<>version; /* Version of the MATH table
|
FixedVersion<>version; /* Version of the MATH table
|
||||||
* initially set to 0x00010000u */
|
* initially set to 0x00010000u */
|
||||||
OffsetTo<MathConstants> mathConstants; /* MathConstants table */
|
OffsetTo<MathConstants> mathConstants; /* MathConstants table */
|
||||||
|
OffsetTo<MathGlyphInfo> mathGlyphInfo; /* MathGlyphInfo table */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (8);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* mathspace OT */
|
} /* mathspace OT */
|
||||||
|
|
|
@ -1269,3 +1269,117 @@ hb_ot_layout_get_math_constant (hb_font_t *font,
|
||||||
return math.has_math_constants() ?
|
return math.has_math_constants() ?
|
||||||
math.get_math_constants().get_value(font, constant) : 0;
|
math.get_math_constants().get_value(font, constant) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ot_layout_get_math_italic_correction:
|
||||||
|
*
|
||||||
|
* @font: #hb_font_t from which to retrieve the value
|
||||||
|
* @glyph: glyph index from which to retrieve the value
|
||||||
|
*
|
||||||
|
* Return value: the italic correction of the glyph or 0
|
||||||
|
*
|
||||||
|
* Since: ????
|
||||||
|
**/
|
||||||
|
HB_EXTERN hb_position_t
|
||||||
|
hb_ot_layout_get_math_italic_correction (hb_font_t *font,
|
||||||
|
hb_codepoint_t glyph)
|
||||||
|
{
|
||||||
|
const OT::MATH &math = _get_math (font->face);
|
||||||
|
if (math.has_math_glyph_info()) {
|
||||||
|
const OT::MathGlyphInfo &glyphInfo = math.get_math_glyph_info();
|
||||||
|
if (glyphInfo.has_math_italics_correction_info()) {
|
||||||
|
hb_position_t value;
|
||||||
|
if (glyphInfo.get_math_italics_correction_info().get_value(font, glyph,
|
||||||
|
value))
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ot_layout_get_math_top_accent_attachment:
|
||||||
|
*
|
||||||
|
* @font: #hb_font_t from which to retrieve the value
|
||||||
|
* @glyph: glyph index from which to retrieve the value
|
||||||
|
*
|
||||||
|
* Return value: the top accent attachment of the glyph or 0
|
||||||
|
*
|
||||||
|
* Since: ????
|
||||||
|
**/
|
||||||
|
HB_EXTERN hb_position_t
|
||||||
|
hb_ot_layout_get_math_top_accent_attachment (hb_font_t *font,
|
||||||
|
hb_codepoint_t glyph)
|
||||||
|
{
|
||||||
|
const OT::MATH &math = _get_math (font->face);
|
||||||
|
if (math.has_math_glyph_info()) {
|
||||||
|
const OT::MathGlyphInfo &glyphInfo = math.get_math_glyph_info();
|
||||||
|
if (glyphInfo.has_math_top_accent_attachment()) {
|
||||||
|
hb_position_t value;
|
||||||
|
if (glyphInfo.get_math_top_accent_attachment().get_value(font, glyph,
|
||||||
|
value))
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ot_layout_is_math_extended_shape:
|
||||||
|
*
|
||||||
|
* @font: a #hb_font_t to test
|
||||||
|
* @glyph: a glyph index to test
|
||||||
|
*
|
||||||
|
* Return value: #TRUE if the glyph is an extended shape and #FALSE otherwise
|
||||||
|
*
|
||||||
|
* Since: ????
|
||||||
|
**/
|
||||||
|
HB_EXTERN hb_bool_t
|
||||||
|
hb_ot_layout_is_math_extended_shape (hb_face_t *face,
|
||||||
|
hb_codepoint_t glyph)
|
||||||
|
{
|
||||||
|
const OT::MATH &math = _get_math (face);
|
||||||
|
return math.has_math_glyph_info() &&
|
||||||
|
math.get_math_glyph_info().is_extended_shape(glyph);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ot_layout_get_math_kerning:
|
||||||
|
*
|
||||||
|
* @font: #hb_font_t from which to retrieve the value
|
||||||
|
* @glyph: glyph index from which to retrieve the value
|
||||||
|
* @kern: the #hb_ot_math_kern_t from which to retrieve the value
|
||||||
|
* @correction_height: the correction height to use to determine the kerning.
|
||||||
|
*
|
||||||
|
* This function tries to retrieve the MathKern table for the specified font,
|
||||||
|
* glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the
|
||||||
|
* MathKern table to find one value that is greater or equal to specified
|
||||||
|
* correction_height. If one is found the corresponding value from the list of
|
||||||
|
* kerns is returned and otherwise the last kern value is returned.
|
||||||
|
*
|
||||||
|
* Return value: requested kerning or 0
|
||||||
|
*
|
||||||
|
* Since: ????
|
||||||
|
**/
|
||||||
|
HB_EXTERN hb_position_t
|
||||||
|
hb_ot_layout_get_math_kerning (hb_font_t *font,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
hb_ot_math_kern_t kern,
|
||||||
|
hb_position_t correction_height)
|
||||||
|
{
|
||||||
|
const OT::MATH &math = _get_math (font->face);
|
||||||
|
if (math.has_math_glyph_info()) {
|
||||||
|
const OT::MathGlyphInfo &glyphInfo = math.get_math_glyph_info();
|
||||||
|
if (glyphInfo.has_math_kern_info()) {
|
||||||
|
const OT::MathKernInfo &kernInfo = glyphInfo.get_math_kern_info();
|
||||||
|
const OT::MathKernInfoRecord *kernInfoRecord;
|
||||||
|
if (kernInfo.get_math_kern_info_record(glyph, kernInfoRecord) &&
|
||||||
|
kernInfoRecord->has_math_kern(kern)) {
|
||||||
|
return kernInfoRecord->
|
||||||
|
get_math_kern(kern, &kernInfo).get_value(font, correction_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -310,6 +310,24 @@ HB_EXTERN hb_position_t
|
||||||
hb_ot_layout_get_math_constant (hb_font_t *font,
|
hb_ot_layout_get_math_constant (hb_font_t *font,
|
||||||
hb_ot_math_constant_t constant);
|
hb_ot_math_constant_t constant);
|
||||||
|
|
||||||
|
HB_EXTERN hb_position_t
|
||||||
|
hb_ot_layout_get_math_italic_correction (hb_font_t *font,
|
||||||
|
hb_codepoint_t glyph);
|
||||||
|
|
||||||
|
HB_EXTERN hb_position_t
|
||||||
|
hb_ot_layout_get_math_top_accent_attachment (hb_font_t *font,
|
||||||
|
hb_codepoint_t glyph);
|
||||||
|
|
||||||
|
HB_EXTERN hb_bool_t
|
||||||
|
hb_ot_layout_is_math_extended_shape (hb_face_t *face,
|
||||||
|
hb_codepoint_t glyph);
|
||||||
|
|
||||||
|
HB_EXTERN hb_position_t
|
||||||
|
hb_ot_layout_get_math_kerning (hb_font_t *font,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
hb_ot_math_kern_t kern,
|
||||||
|
hb_position_t correction_height);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,13 @@ typedef enum {
|
||||||
HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT = 55
|
HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT = 55
|
||||||
} hb_ot_math_constant_t;
|
} hb_ot_math_constant_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HB_OT_MATH_KERN_TOP_RIGHT = 0,
|
||||||
|
HB_OT_MATH_KERN_TOP_LEFT = 1,
|
||||||
|
HB_OT_MATH_KERN_BOTTOM_RIGHT = 2,
|
||||||
|
HB_OT_MATH_KERN_BOTTOM_LEFT = 3
|
||||||
|
} hb_ot_math_kern_t;
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
||||||
#endif /* HB_OT_MATH_H */
|
#endif /* HB_OT_MATH_H */
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -160,6 +160,157 @@ test_get_math_constant (void)
|
||||||
cleanupFreeType();
|
cleanupFreeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_get_math_italic_correction (void)
|
||||||
|
{
|
||||||
|
hb_codepoint_t glyph;
|
||||||
|
initFreeType();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontEmpty.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_italic_correction (hb_font, glyph), ==, 0); // MathGlyphInfo not available
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontPartial1.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_italic_correction (hb_font, glyph), ==, 0); // MathGlyphInfo empty
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontPartial2.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_italic_correction (hb_font, glyph), ==, 0); // MathItalicsCorrectionInfo empty
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontFull.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_italic_correction (hb_font, glyph), ==, 0); // Glyph without italic correction.
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "A", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_italic_correction (hb_font, glyph), ==, 197);
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "B", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_italic_correction (hb_font, glyph), ==, 150);
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "C", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_italic_correction (hb_font, glyph), ==, 452);
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
cleanupFreeType();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_get_math_top_accent_attachment (void)
|
||||||
|
{
|
||||||
|
hb_codepoint_t glyph;
|
||||||
|
initFreeType();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontEmpty.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_top_accent_attachment (hb_font, glyph), ==, 0); // MathGlyphInfo not available
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontPartial1.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_top_accent_attachment (hb_font, glyph), ==, 0); // MathGlyphInfo empty
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontPartial2.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_top_accent_attachment (hb_font, glyph), ==, 0); // MathTopAccentAttachment empty
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontFull.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_top_accent_attachment (hb_font, glyph), ==, 0); // Glyph without top accent attachment.
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "D", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_top_accent_attachment (hb_font, glyph), ==, 374);
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "E", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_top_accent_attachment (hb_font, glyph), ==, 346);
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "F", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_top_accent_attachment (hb_font, glyph), ==, 318);
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
cleanupFreeType();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_is_math_extended_shape (void)
|
||||||
|
{
|
||||||
|
hb_codepoint_t glyph;
|
||||||
|
initFreeType();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontEmpty.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert(!hb_ot_layout_is_math_extended_shape (hb_face, glyph)); // MathGlyphInfo not available
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontPartial1.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert(!hb_ot_layout_is_math_extended_shape (hb_face, glyph)); // MathGlyphInfo empty
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontFull.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "G", -1, &glyph));
|
||||||
|
g_assert(!hb_ot_layout_is_math_extended_shape (hb_face, glyph));
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "H", -1, &glyph));
|
||||||
|
g_assert(hb_ot_layout_is_math_extended_shape (hb_face, glyph));
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
cleanupFreeType();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_get_math_kerning (void)
|
||||||
|
{
|
||||||
|
hb_codepoint_t glyph;
|
||||||
|
initFreeType();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontEmpty.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathGlyphInfo not available
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathGlyphInfo not available
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathGlyphInfo not available
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathGlyphInfo not available
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontPartial2.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathKernInfo empty
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathKernInfo empty
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathKernInfo empty
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathKernInfo empty
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontPartial3.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0), ==, 0); // MathKernInfoRecords empty
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0), ==, 0); // MathKernInfoRecords empty
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0), ==, 0); // MathKernInfoRecords empty
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0), ==, 0); // MathKernInfoRecords empty
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontFull.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "I", -1, &glyph));
|
||||||
|
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 7), ==, 31); // lower than min heigth
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 14), ==, 31); // equal to min height
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 20), ==, 52);
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 23), ==, 52);
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 31), ==, 73);
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 32), ==, 73);
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 86), ==, 199); // equal to max height
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 91), ==, 220); // larger than max height
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 96), ==, 220); // larger than max height
|
||||||
|
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 39), ==, 94); // top right
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 39), ==, 55); // top left
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 39), ==, 22); // bottom right
|
||||||
|
g_assert_cmpint(hb_ot_layout_get_math_kerning (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 39), ==, 50); // bottom left
|
||||||
|
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
cleanupFreeType();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -167,6 +318,10 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
hb_test_add (test_has_math_data);
|
hb_test_add (test_has_math_data);
|
||||||
hb_test_add (test_get_math_constant);
|
hb_test_add (test_get_math_constant);
|
||||||
|
hb_test_add (test_get_math_italic_correction);
|
||||||
|
hb_test_add (test_get_math_top_accent_attachment);
|
||||||
|
hb_test_add (test_is_math_extended_shape);
|
||||||
|
hb_test_add (test_get_math_kerning);
|
||||||
|
|
||||||
return hb_test_run();
|
return hb_test_run();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue