[MATH] Fix get_kerning() with negative y-scale

This commit is contained in:
Behdad Esfahbod 2016-09-26 13:39:58 +01:00
parent 94f5df5626
commit 8d58e3433e
1 changed files with 21 additions and 15 deletions

View File

@ -252,20 +252,24 @@ struct MathKern
{ {
const MathValueRecord* correctionHeight = mathValueRecords; const MathValueRecord* correctionHeight = mathValueRecords;
const MathValueRecord* kernValue = mathValueRecords + heightCount; const MathValueRecord* kernValue = mathValueRecords + heightCount;
// The description of the MathKern table is a ambiguous, but interpreting int sign = font->y_scale < 0 ? -1 : +1;
// "between the two heights found at those indexes" for 0 < i < len as
// /* The description of the MathKern table is a ambiguous, but interpreting
// correctionHeight[i-1] < correction_height <= correctionHeight[i] * "between the two heights found at those indexes" for 0 < i < len as
// *
// makes the result consistent with the limit cases and we can just use the * correctionHeight[i-1] < correction_height <= correctionHeight[i]
// binary search algorithm of std::upper_bound: *
unsigned int count = heightCount; * makes the result consistent with the limit cases and we can just use the
* binary search algorithm of std::upper_bound:
*/
unsigned int i = 0; unsigned int i = 0;
while (count > 0) { unsigned int count = heightCount;
while (count > 0)
{
unsigned int half = count / 2; unsigned int half = count / 2;
hb_position_t height = hb_position_t height = correctionHeight[i + half].get_y_value(font, this);
correctionHeight[i + half].get_y_value(font, this); if (sign * height < sign * correction_height)
if (height < correction_height) { {
i += half + 1; i += half + 1;
count -= half + 1; count -= half + 1;
} else } else
@ -279,9 +283,11 @@ protected:
MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at
* which the kern value changes. * which the kern value changes.
* Sorted by the height value in * Sorted by the height value in
* design units. */ * design units (heightCount entries),
/* Array of kern values corresponding * Followed by:
* to heights. */ * Array of kern values corresponding
* to heights. (heightCount+1 entries).
*/
public: public:
DEFINE_SIZE_ARRAY (2, mathValueRecords); DEFINE_SIZE_ARRAY (2, mathValueRecords);