parent
1bc4bad7a5
commit
81754a5a96
|
@ -546,6 +546,7 @@ HB_OT_TAG_MATH
|
||||||
HB_OT_TAG_MATH_SCRIPT
|
HB_OT_TAG_MATH_SCRIPT
|
||||||
hb_ot_math_constant_t
|
hb_ot_math_constant_t
|
||||||
hb_ot_math_kern_t
|
hb_ot_math_kern_t
|
||||||
|
hb_ot_math_kern_entry_t
|
||||||
hb_ot_math_glyph_variant_t
|
hb_ot_math_glyph_variant_t
|
||||||
hb_ot_math_glyph_part_flags_t
|
hb_ot_math_glyph_part_flags_t
|
||||||
hb_ot_math_glyph_part_t
|
hb_ot_math_glyph_part_t
|
||||||
|
@ -554,6 +555,7 @@ hb_ot_math_get_constant
|
||||||
hb_ot_math_get_glyph_italics_correction
|
hb_ot_math_get_glyph_italics_correction
|
||||||
hb_ot_math_get_glyph_top_accent_attachment
|
hb_ot_math_get_glyph_top_accent_attachment
|
||||||
hb_ot_math_get_glyph_kerning
|
hb_ot_math_get_glyph_kerning
|
||||||
|
hb_ot_math_get_glyph_kernings
|
||||||
hb_ot_math_is_glyph_extended_shape
|
hb_ot_math_is_glyph_extended_shape
|
||||||
hb_ot_math_get_glyph_variants
|
hb_ot_math_get_glyph_variants
|
||||||
hb_ot_math_get_min_connector_overlap
|
hb_ot_math_get_min_connector_overlap
|
||||||
|
|
|
@ -369,6 +369,37 @@ struct MathKern
|
||||||
return kernValue[i].get_x_value (font, this);
|
return kernValue[i].get_x_value (font, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int get_entries (unsigned int start_offset,
|
||||||
|
unsigned int *entries_count, /* IN/OUT */
|
||||||
|
hb_ot_math_kern_entry_t *kern_entries, /* OUT */
|
||||||
|
hb_font_t *font) const
|
||||||
|
{
|
||||||
|
const MathValueRecord* correctionHeight = mathValueRecordsZ.arrayZ;
|
||||||
|
const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount;
|
||||||
|
const unsigned int entriesCount = heightCount + 1;
|
||||||
|
|
||||||
|
if (entries_count)
|
||||||
|
{
|
||||||
|
unsigned int start = hb_min (start_offset, entriesCount);
|
||||||
|
unsigned int end = hb_min (start + *entries_count, entriesCount);
|
||||||
|
*entries_count = end - start;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < *entries_count; i++) {
|
||||||
|
unsigned int j = start + i;
|
||||||
|
|
||||||
|
hb_position_t max_height;
|
||||||
|
if (j == heightCount) {
|
||||||
|
max_height = INT32_MAX;
|
||||||
|
} else {
|
||||||
|
max_height = correctionHeight[j].get_y_value (font, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_entries[i] = {max_height, kernValue[j].get_x_value (font, this)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entriesCount;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 heightCount;
|
HBUINT16 heightCount;
|
||||||
UnsizedArrayOf<MathValueRecord>
|
UnsizedArrayOf<MathValueRecord>
|
||||||
|
@ -423,6 +454,24 @@ struct MathKernInfoRecord
|
||||||
return (base+mathKern[idx]).get_value (correction_height, font);
|
return (base+mathKern[idx]).get_value (correction_height, font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int get_kernings (hb_ot_math_kern_t kern,
|
||||||
|
unsigned int start_offset,
|
||||||
|
unsigned int *entries_count, /* IN/OUT */
|
||||||
|
hb_ot_math_kern_entry_t *kern_entries, /* OUT */
|
||||||
|
hb_font_t *font,
|
||||||
|
const void *base) const
|
||||||
|
{
|
||||||
|
unsigned int idx = kern;
|
||||||
|
if (unlikely (idx >= ARRAY_LENGTH (mathKern)) || !mathKern[idx]) {
|
||||||
|
if (entries_count) *entries_count = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (base+mathKern[idx]).get_entries (start_offset,
|
||||||
|
entries_count,
|
||||||
|
kern_entries,
|
||||||
|
font);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Offset to MathKern table for each corner -
|
/* Offset to MathKern table for each corner -
|
||||||
* from the beginning of MathKernInfo table. May be NULL. */
|
* from the beginning of MathKernInfo table. May be NULL. */
|
||||||
|
@ -473,6 +522,22 @@ struct MathKernInfo
|
||||||
return mathKernInfoRecords[index].get_kerning (kern, correction_height, font, this);
|
return mathKernInfoRecords[index].get_kerning (kern, correction_height, font, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int get_kernings (hb_codepoint_t glyph,
|
||||||
|
hb_ot_math_kern_t kern,
|
||||||
|
unsigned int start_offset,
|
||||||
|
unsigned int *entries_count, /* IN/OUT */
|
||||||
|
hb_ot_math_kern_entry_t *kern_entries, /* OUT */
|
||||||
|
hb_font_t *font) const
|
||||||
|
{
|
||||||
|
unsigned int index = (this+mathKernCoverage).get_coverage (glyph);
|
||||||
|
return mathKernInfoRecords[index].get_kernings (kern,
|
||||||
|
start_offset,
|
||||||
|
entries_count,
|
||||||
|
kern_entries,
|
||||||
|
font,
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Offset16To<Coverage>
|
Offset16To<Coverage>
|
||||||
mathKernCoverage;
|
mathKernCoverage;
|
||||||
|
@ -545,6 +610,19 @@ struct MathGlyphInfo
|
||||||
hb_font_t *font) const
|
hb_font_t *font) const
|
||||||
{ return (this+mathKernInfo).get_kerning (glyph, kern, correction_height, font); }
|
{ return (this+mathKernInfo).get_kerning (glyph, kern, correction_height, font); }
|
||||||
|
|
||||||
|
hb_position_t get_kernings (hb_codepoint_t glyph,
|
||||||
|
hb_ot_math_kern_t kern,
|
||||||
|
unsigned int start_offset,
|
||||||
|
unsigned int *entries_count, /* IN/OUT */
|
||||||
|
hb_ot_math_kern_entry_t *kern_entries, /* OUT */
|
||||||
|
hb_font_t *font) const
|
||||||
|
{ return (this+mathKernInfo).get_kernings (glyph,
|
||||||
|
kern,
|
||||||
|
start_offset,
|
||||||
|
entries_count,
|
||||||
|
kern_entries,
|
||||||
|
font); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Offset to MathItalicsCorrectionInfo table -
|
/* Offset to MathItalicsCorrectionInfo table -
|
||||||
* from the beginning of MathGlyphInfo table. */
|
* from the beginning of MathGlyphInfo table. */
|
||||||
|
|
|
@ -184,6 +184,51 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
|
||||||
font);
|
font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ot_math_get_glyph_kernings:
|
||||||
|
* @font: #hb_font_t to work upon
|
||||||
|
* @glyph: The glyph index from which to retrieve the kernings
|
||||||
|
* @kern: The #hb_ot_math_kern_t from which to retrieve the kernings
|
||||||
|
* @start_offset: offset of the first kern entry to retrieve
|
||||||
|
* @entries_count: (inout) (optional): Input = the maximum number of kern entries to return;
|
||||||
|
* Output = the actual number of kern entries returned
|
||||||
|
* @kern_entries: (out caller-allocates) (array length=entries_count): array of kern entries returned
|
||||||
|
*
|
||||||
|
* Fetches the raw MathKern (cut-in) data for the specified font, glyph index,
|
||||||
|
* and @kern. The corresponding list of kern values and correction heights is
|
||||||
|
* returned as a list of #hb_ot_math_kern_entry_t structs.
|
||||||
|
*
|
||||||
|
* See also #hb_ot_math_get_glyph_kerning, which handles selecting the
|
||||||
|
* appropriate kern value for a given correction height.
|
||||||
|
*
|
||||||
|
* <note>For a glyph with @n defined kern values (where @n > 0), there are only
|
||||||
|
* @n−1 defined correction heights, as each correction height defines a boundary
|
||||||
|
* past which the next kern value should be selected. Therefore, only the
|
||||||
|
* #hb_ot_math_kern_entry_t.kern_value of the uppermost #hb_ot_math_kern_entry_t
|
||||||
|
* actually comes from the font; its corresponding
|
||||||
|
* #hb_ot_math_kern_entry_t.max_correction_height is always set to
|
||||||
|
* <code>INT32_MAX</code>.</note>
|
||||||
|
*
|
||||||
|
* Return value: the total number of kern values available or zero
|
||||||
|
*
|
||||||
|
* Since: REPLACEME
|
||||||
|
**/
|
||||||
|
unsigned int
|
||||||
|
hb_ot_math_get_glyph_kernings (hb_font_t *font,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
hb_ot_math_kern_t kern,
|
||||||
|
unsigned int start_offset,
|
||||||
|
unsigned int *entries_count, /* IN/OUT */
|
||||||
|
hb_ot_math_kern_entry_t *kern_entries /* OUT */)
|
||||||
|
{
|
||||||
|
return font->face->table.MATH->get_glyph_info().get_kernings (glyph,
|
||||||
|
kern,
|
||||||
|
start_offset,
|
||||||
|
entries_count,
|
||||||
|
kern_entries,
|
||||||
|
font);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_ot_math_get_glyph_variants:
|
* hb_ot_math_get_glyph_variants:
|
||||||
* @font: #hb_font_t to work upon
|
* @font: #hb_font_t to work upon
|
||||||
|
|
|
@ -208,6 +208,20 @@ typedef enum {
|
||||||
HB_OT_MATH_KERN_BOTTOM_LEFT = 3
|
HB_OT_MATH_KERN_BOTTOM_LEFT = 3
|
||||||
} hb_ot_math_kern_t;
|
} hb_ot_math_kern_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ot_math_kern_entry_t:
|
||||||
|
* @max_correction_height: The maximum height at which this entry should be used
|
||||||
|
* @kern_value: The kern value of the entry
|
||||||
|
*
|
||||||
|
* Data type to hold math kerning (cut-in) information for a glyph.
|
||||||
|
*
|
||||||
|
* Since: REPLACEME
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
hb_position_t max_correction_height;
|
||||||
|
hb_position_t kern_value;
|
||||||
|
} hb_ot_math_kern_entry_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_ot_math_glyph_variant_t:
|
* hb_ot_math_glyph_variant_t:
|
||||||
* @glyph: The glyph index of the variant
|
* @glyph: The glyph index of the variant
|
||||||
|
@ -284,6 +298,14 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
|
||||||
hb_ot_math_kern_t kern,
|
hb_ot_math_kern_t kern,
|
||||||
hb_position_t correction_height);
|
hb_position_t correction_height);
|
||||||
|
|
||||||
|
HB_EXTERN unsigned int
|
||||||
|
hb_ot_math_get_glyph_kernings (hb_font_t *font,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
hb_ot_math_kern_t kern,
|
||||||
|
unsigned int start_offset,
|
||||||
|
unsigned int *entries_count, /* IN/OUT */
|
||||||
|
hb_ot_math_kern_entry_t *kern_entries /* OUT */);
|
||||||
|
|
||||||
HB_EXTERN unsigned int
|
HB_EXTERN unsigned int
|
||||||
hb_ot_math_get_glyph_variants (hb_font_t *font,
|
hb_ot_math_get_glyph_variants (hb_font_t *font,
|
||||||
hb_codepoint_t glyph,
|
hb_codepoint_t glyph,
|
||||||
|
|
|
@ -131,6 +131,7 @@ test_font (hb_font_t *font, hb_codepoint_t cp)
|
||||||
hb_ot_math_get_glyph_top_accent_attachment (font, cp);
|
hb_ot_math_get_glyph_top_accent_attachment (font, cp);
|
||||||
hb_ot_math_is_glyph_extended_shape (face, cp);
|
hb_ot_math_is_glyph_extended_shape (face, cp);
|
||||||
hb_ot_math_get_glyph_kerning (font, cp, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0);
|
hb_ot_math_get_glyph_kerning (font, cp, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0);
|
||||||
|
hb_ot_math_get_glyph_kernings (font, cp, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL);
|
||||||
hb_ot_math_get_glyph_variants (font, cp, HB_DIRECTION_TTB, 0, NULL, NULL);
|
hb_ot_math_get_glyph_variants (font, cp, HB_DIRECTION_TTB, 0, NULL, NULL);
|
||||||
hb_ot_math_get_min_connector_overlap (font, HB_DIRECTION_RTL);
|
hb_ot_math_get_min_connector_overlap (font, HB_DIRECTION_RTL);
|
||||||
hb_ot_math_get_glyph_assembly (font, cp, HB_DIRECTION_BTT, 0, NULL, NULL, NULL);
|
hb_ot_math_get_glyph_assembly (font, cp, HB_DIRECTION_BTT, 0, NULL, NULL, NULL);
|
||||||
|
|
|
@ -332,6 +332,87 @@ test_get_glyph_kerning (void)
|
||||||
cleanupFreeType();
|
cleanupFreeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_get_glyph_kernings (void)
|
||||||
|
{
|
||||||
|
hb_codepoint_t glyph;
|
||||||
|
hb_ot_math_kern_entry_t entries[20];
|
||||||
|
const unsigned entries_size = sizeof (entries) / sizeof (entries[0]);
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
initFreeType();
|
||||||
|
|
||||||
|
openFont("fonts/MathTestFontEmpty.otf");
|
||||||
|
g_assert(hb_font_get_glyph_from_name (hb_font, "space", -1, &glyph));
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, NULL, NULL), ==, 0); // MathGlyphInfo not available
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, NULL, NULL), ==, 0); // MathGlyphInfo not available
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL), ==, 0); // MathGlyphInfo not available
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0, NULL, NULL), ==, 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_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, NULL, NULL), ==, 0); // MathKernInfo empty
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, NULL, NULL), ==, 0); // MathKernInfo empty
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL), ==, 0); // MathKernInfo empty
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0, NULL, NULL), ==, 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_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, NULL, NULL), ==, 0); // MathKernInfoRecords empty
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, NULL, NULL), ==, 0); // MathKernInfoRecords empty
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL), ==, 0); // MathKernInfoRecords empty
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0, NULL, NULL), ==, 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_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, NULL, NULL), ==, 10);
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, NULL, NULL), ==, 3);
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0, NULL, NULL), ==, 9);
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_BOTTOM_LEFT, 0, NULL, NULL), ==, 7);
|
||||||
|
|
||||||
|
count = entries_size;
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_RIGHT, 0, &count, entries), ==, 10);
|
||||||
|
g_assert_cmpint(count, ==, 10);
|
||||||
|
g_assert_cmpint(entries[0].max_correction_height, ==, 14);
|
||||||
|
g_assert_cmpint(entries[0].kern_value, ==, 62);
|
||||||
|
g_assert_cmpint(entries[1].max_correction_height, ==, 23);
|
||||||
|
g_assert_cmpint(entries[1].kern_value, ==, 104);
|
||||||
|
g_assert_cmpint(entries[2].max_correction_height, ==, 32);
|
||||||
|
g_assert_cmpint(entries[2].kern_value, ==, 146);
|
||||||
|
g_assert_cmpint(entries[3].max_correction_height, ==, 41);
|
||||||
|
g_assert_cmpint(entries[3].kern_value, ==, 188);
|
||||||
|
g_assert_cmpint(entries[4].max_correction_height, ==, 50);
|
||||||
|
g_assert_cmpint(entries[4].kern_value, ==, 230);
|
||||||
|
g_assert_cmpint(entries[5].max_correction_height, ==, 59);
|
||||||
|
g_assert_cmpint(entries[5].kern_value, ==, 272);
|
||||||
|
g_assert_cmpint(entries[6].max_correction_height, ==, 68);
|
||||||
|
g_assert_cmpint(entries[6].kern_value, ==, 314);
|
||||||
|
g_assert_cmpint(entries[7].max_correction_height, ==, 77);
|
||||||
|
g_assert_cmpint(entries[7].kern_value, ==, 356);
|
||||||
|
g_assert_cmpint(entries[8].max_correction_height, ==, 86);
|
||||||
|
g_assert_cmpint(entries[8].kern_value, ==, 398);
|
||||||
|
g_assert_cmpint(entries[9].max_correction_height, ==, INT32_MAX);
|
||||||
|
g_assert_cmpint(entries[9].kern_value, ==, 440);
|
||||||
|
|
||||||
|
count = entries_size;
|
||||||
|
g_assert_cmpint(hb_ot_math_get_glyph_kernings (hb_font, glyph, HB_OT_MATH_KERN_TOP_LEFT, 0, &count, entries), ==, 3);
|
||||||
|
g_assert_cmpint(count, ==, 3);
|
||||||
|
g_assert_cmpint(entries[0].max_correction_height, ==, 20);
|
||||||
|
g_assert_cmpint(entries[0].kern_value, ==, 50);
|
||||||
|
g_assert_cmpint(entries[1].max_correction_height, ==, 35);
|
||||||
|
g_assert_cmpint(entries[1].kern_value, ==, 80);
|
||||||
|
g_assert_cmpint(entries[2].max_correction_height, ==, INT32_MAX);
|
||||||
|
g_assert_cmpint(entries[2].kern_value, ==, 110);
|
||||||
|
|
||||||
|
closeFont();
|
||||||
|
|
||||||
|
cleanupFreeType();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static hb_position_t
|
static hb_position_t
|
||||||
get_glyph_assembly_italics_correction (hb_font_t *font,
|
get_glyph_assembly_italics_correction (hb_font_t *font,
|
||||||
|
@ -707,6 +788,7 @@ main (int argc, char **argv)
|
||||||
hb_test_add (test_get_glyph_top_accent_attachment);
|
hb_test_add (test_get_glyph_top_accent_attachment);
|
||||||
hb_test_add (test_is_glyph_extended_shape);
|
hb_test_add (test_is_glyph_extended_shape);
|
||||||
hb_test_add (test_get_glyph_kerning);
|
hb_test_add (test_get_glyph_kerning);
|
||||||
|
hb_test_add (test_get_glyph_kernings);
|
||||||
hb_test_add (test_get_glyph_assembly_italics_correction);
|
hb_test_add (test_get_glyph_assembly_italics_correction);
|
||||||
hb_test_add (test_get_min_connector_overlap);
|
hb_test_add (test_get_min_connector_overlap);
|
||||||
hb_test_add (test_get_glyph_variants);
|
hb_test_add (test_get_glyph_variants);
|
||||||
|
|
Loading…
Reference in New Issue