fix SkTextBlob::getIntercepts regression no longer considering glyph vertical offset

As of revision 7924d9a4ae (https://skia-review.googlesource.com/c/skia/+/222277), SkTextBlob::getIntercepts no longer considers each glyph's vertical offset. So getIntercepts will only work properly if each glyph has a vertical offset of 0. This patch restores the original behavior of offsetting the bounds from each glyph's position.

Without this fix, Firefox has no way to implement proper intercepts for underlining decorations when glyphs are offset...

Change-Id: I06fc4b63bd57c9d70e3b07a95ead69f3caa8b33a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/248724
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Herb Derby <herb@google.com>
Auto-Submit: Lee Salzman <lsalzman@mozilla.com>
This commit is contained in:
Lee Salzman 2019-10-15 13:53:09 -04:00 committed by Skia Commit-Bot
parent 20c626aa23
commit 634d15032d
2 changed files with 36 additions and 3 deletions

View File

@ -881,9 +881,6 @@ int get_glyph_run_intercepts(const SkGlyphRun& glyphRun,
SkScalar xPos = xOffset;
SkScalar prevAdvance = 0;
// The typeface is scaled, so un-scale the bounds to be in the space of the typeface.
SkScalar scaledBounds[2] = {bounds[0] / scale, bounds[1] / scale};
const SkPoint* posCursor = glyphRun.positions().begin();
for (auto glyphID : glyphRun.glyphsIDs()) {
SkPoint pos = *posCursor++;
@ -892,6 +889,12 @@ int get_glyph_run_intercepts(const SkGlyphRun& glyphRun,
xPos += prevAdvance * scale;
prevAdvance = glyph->advanceX();
if (cache->preparePath(glyph) != nullptr) {
// The typeface is scaled, so un-scale the bounds to be in the space of the typeface.
// Also ensure the bounds are properly offset by the vertical positioning of the glyph.
SkScalar scaledBounds[2] = {
(bounds[0] - pos.y()) / scale,
(bounds[1] - pos.y()) / scale
};
cache->findIntercepts(scaledBounds, scale, pos.x(), glyph, intervals, intervalCount);
}
}

View File

@ -480,3 +480,33 @@ DEF_TEST(TextBlob_iter, reporter) {
// Hello should have the same glyph repeated for the 'l'
REPORTER_ASSERT(reporter, run.fGlyphIndices[2] == run.fGlyphIndices[3]);
}
DEF_TEST(TextBlob_getIntercepts, reporter) {
SkFont font;
font.setSize(16);
SkPoint lowPos[1] = { SkPoint::Make(0, 5) };
SkPoint highPos[1] = { SkPoint::Make(0, -8) };
SkPoint zeroPos[1] = { SkPoint::Make(0, 0) };
// 'x' sitting on baseline
auto blobZeroX = SkTextBlob::MakeFromPosText("x", 1, zeroPos, font);
// 'x' lowered to intersect baseline
auto blobLowX = SkTextBlob::MakeFromPosText("x", 1, lowPos, font);
// 'y' sitting on baseline
auto blobZeroY = SkTextBlob::MakeFromPosText("y", 1, zeroPos, font);
// 'y' raised to not intersect baseline
auto blobHighY = SkTextBlob::MakeFromPosText("y", 1, highPos, font);
// bounds right below baseline
SkScalar bounds[2] = { 1, 2 };
// 'x' on baseline should not intersect
REPORTER_ASSERT(reporter, blobZeroX->getIntercepts(bounds, nullptr) == 0);
// lowered 'x' should intersect
REPORTER_ASSERT(reporter, blobLowX->getIntercepts(bounds, nullptr) == 2);
// 'y' on baseline should intersect
REPORTER_ASSERT(reporter, blobZeroY->getIntercepts(bounds, nullptr) == 2);
// raised 'y' should not intersect
REPORTER_ASSERT(reporter, blobHighY->getIntercepts(bounds, nullptr) == 0);
}