зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1790450 - Avoid using SkTextBlob bounds. r=aosmond
The conservative bounds returned when using SkTextBlob::bounds() can sometimes be erroneous. Skia currently does not have a way to force tight bounds computation with that particular interface, so we work around this by querying the bounds from SkFont explicitly like Skia's internal tight bounds computation would do anyway. Differential Revision: https://phabricator.services.mozilla.com/D157547
This commit is contained in:
Родитель
9281cd6961
Коммит
8986d2d483
|
@ -1344,23 +1344,33 @@ Maybe<Rect> DrawTargetSkia::GetGlyphLocalBounds(
|
|||
// Limit the amount of internal batch allocations Skia does.
|
||||
const uint32_t kMaxGlyphBatchSize = 8192;
|
||||
|
||||
// Avoid using TextBlobBuilder for bounds computations as the conservative
|
||||
// bounds can be wrong due to buggy font metrics. Instead, explicitly compute
|
||||
// tight bounds directly with the SkFont.
|
||||
Vector<SkGlyphID, 32> glyphs;
|
||||
Vector<SkRect, 32> rects;
|
||||
Rect bounds;
|
||||
for (uint32_t offset = 0; offset < aBuffer.mNumGlyphs;) {
|
||||
uint32_t batchSize =
|
||||
std::min(aBuffer.mNumGlyphs - offset, kMaxGlyphBatchSize);
|
||||
SkTextBlobBuilder builder;
|
||||
auto runBuffer = builder.allocRunPos(font, batchSize);
|
||||
for (uint32_t i = 0; i < batchSize; i++, offset++) {
|
||||
runBuffer.glyphs[i] = aBuffer.mGlyphs[offset].mIndex;
|
||||
runBuffer.points()[i] = PointToSkPoint(aBuffer.mGlyphs[offset].mPosition);
|
||||
if (glyphs.resizeUninitialized(batchSize) &&
|
||||
rects.resizeUninitialized(batchSize)) {
|
||||
for (uint32_t i = 0; i < batchSize; i++) {
|
||||
glyphs[i] = aBuffer.mGlyphs[offset + i].mIndex;
|
||||
}
|
||||
font.getBounds(glyphs.begin(), batchSize, rects.begin(), nullptr);
|
||||
for (uint32_t i = 0; i < batchSize; i++) {
|
||||
bounds = bounds.Union(SkRectToRect(rects[i]) +
|
||||
aBuffer.mGlyphs[offset + i].mPosition);
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<SkTextBlob> text = builder.make();
|
||||
SkRect storage;
|
||||
bounds = bounds.Union(
|
||||
SkRectToRect(paint.mPaint.computeFastBounds(text->bounds(), &storage)));
|
||||
offset += batchSize;
|
||||
}
|
||||
|
||||
SkRect storage;
|
||||
bounds = SkRectToRect(
|
||||
paint.mPaint.computeFastBounds(RectToSkRect(bounds), &storage));
|
||||
|
||||
if (bounds.IsEmpty()) {
|
||||
return Nothing();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче