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);
|
||||
};
|
||||
|
||||
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 @@ struct MATH
|
|||
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 @@ struct MATH
|
|||
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 */
|
||||
|
|
|
@ -1269,3 +1269,117 @@ hb_ot_layout_get_math_constant (hb_font_t *font,
|
|||
return math.has_math_constants() ?
|
||||
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_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
|
||||
|
||||
|
|
|
@ -95,6 +95,13 @@ typedef enum {
|
|||
HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT = 55
|
||||
} 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
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
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
|
||||
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_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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue