Have prepare mask drawing do position mapping
Split out prepare_for_direct_mask_drawing from
prepare_for_mask_drawing. Move the direct mask positioning
code into prepare_for_direct_mask_drawing.
Bug: skia:14065
Change-Id: Ief21c9e793fba4828bfdd317892310226d101771
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/635182
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/text/gpu/SubRunContainer.cpp b/src/text/gpu/SubRunContainer.cpp
index e78ab3d..6402185 100644
--- a/src/text/gpu/SubRunContainer.cpp
+++ b/src/text/gpu/SubRunContainer.cpp
@@ -2352,23 +2352,72 @@
}
#endif
+SkRect prepare_for_direct_mask_drawing(StrikeForGPU* strike,
+ const SkMatrix& positionMatrix,
+ SkDrawableGlyphBuffer* accepted,
+ SkSourceGlyphBuffer* rejected) {
+ const SkIPoint mask = strike->roundingSpec().ignorePositionFieldMask;
+ const SkPoint halfSampleFreq = strike->roundingSpec().halfAxisSampleFreq;
+
+ // Build up the mapping from source space to device space. Add the rounding constant
+ // halfSampleFreq, so we just need to floor to get the device result.
+ SkMatrix positionMatrixWithRounding = positionMatrix;
+ positionMatrixWithRounding.postTranslate(halfSampleFreq.x(), halfSampleFreq.y());
+
+ SkGlyphRect boundingRect = skglyph::empty_rect();
+ StrikeMutationMonitor m{strike};
+ for (auto [i, notSubPixelGlyphID, pos] : SkMakeEnumerate(accepted->input())) {
+ if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+ continue;
+ }
+
+ const SkPoint mappedPos = positionMatrixWithRounding.mapPoint(pos);
+ const SkGlyphID glyphID = notSubPixelGlyphID.packedID().glyphID();
+ const SkPackedGlyphID packedGlyphID = SkPackedGlyphID{glyphID, mappedPos, mask};
+ const SkGlyphDigest digest = strike->digest(packedGlyphID);
+
+ if (digest.isEmpty()) {
+ continue;
+ }
+
+ if (digest.canDrawAsMask()) {
+ const SkPoint roundedPos{SkScalarFloorToScalar(mappedPos.x()),
+ SkScalarFloorToScalar(mappedPos.y())};
+ const SkGlyphRect glyphBounds = digest.bounds().offset(roundedPos);
+ boundingRect = skglyph::rect_union(boundingRect, glyphBounds);
+ accepted->accept(packedGlyphID, glyphBounds.leftTop(), digest.maskFormat());
+ } else {
+ rejected->reject(i);
+ }
+ }
+
+ return boundingRect.rect();
+}
+
SkRect prepare_for_mask_drawing(StrikeForGPU* strike,
+ const SkMatrix& creationMatrix,
SkDrawableGlyphBuffer* accepted,
SkSourceGlyphBuffer* rejected) {
SkGlyphRect boundingRect = skglyph::empty_rect();
StrikeMutationMonitor m{strike};
for (auto [i, packedID, pos] : SkMakeEnumerate(accepted->input())) {
- if (SkScalarsAreFinite(pos.x(), pos.y())) {
- SkGlyphDigest digest = strike->digest(packedID);
- if (!digest.isEmpty()) {
- if (digest.canDrawAsMask()) {
- const SkGlyphRect glyphBounds = digest.bounds().offset(pos);
- boundingRect = skglyph::rect_union(boundingRect, glyphBounds);
- accepted->accept(packedID, glyphBounds.leftTop(), digest.maskFormat());
- } else {
- rejected->reject(i);
- }
- }
+ if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+ continue;
+ }
+
+ SkGlyphDigest digest = strike->digest(packedID);
+
+ if (digest.isEmpty()) {
+ continue;
+ }
+
+ if (digest.canDrawAsMask()) {
+ SkPoint mappedPos = creationMatrix.mapPoint(pos);
+ const SkGlyphRect glyphBounds = digest.bounds().offset(mappedPos);
+ boundingRect = skglyph::rect_union(boundingRect, glyphBounds);
+ accepted->accept(packedID, glyphBounds.leftTop(), digest.maskFormat());
+ } else {
+ rejected->reject(i);
}
}
@@ -2516,12 +2565,13 @@
ScopedStrikeForGPU strike = strikeSpec.findOrCreateScopedStrike(strikeCache);
- accepted->startDevicePositioning(
- rejected->source(), positionMatrix, strike->roundingSpec());
+ accepted->startSource(rejected->source());
if constexpr (kTrace) {
msg.appendf(" glyphs:(x,y):\n %s\n", accepted->dumpInput().c_str());
}
- SkRect bounds = prepare_for_mask_drawing(strike.get(), accepted, rejected);
+ SkRect bounds =
+ prepare_for_direct_mask_drawing(
+ strike.get(), positionMatrix, accepted, rejected);
rejected->flipRejectsToSource();
if (creationBehavior == kAddSubRuns && !accepted->empty()) {
@@ -2682,11 +2732,12 @@
}
ScopedStrikeForGPU strike = strikeSpec.findOrCreateScopedStrike(strikeCache);
- accepted->startSourceWithMatrixAdjustment(rejected->source(), creationMatrix);
+ accepted->startSource(rejected->source());
if constexpr (kTrace) {
msg.appendf("glyphs:(x,y):\n %s\n", accepted->dumpInput().c_str());
}
- SkRect creationBounds = prepare_for_mask_drawing(strike.get(), accepted, rejected);
+ SkRect creationBounds =
+ prepare_for_mask_drawing(strike.get(), creationMatrix, accepted, rejected);
rejected->flipRejectsToSource();
SkASSERT(rejected->source().empty());
diff --git a/tests/SkStrikeTest.cpp b/tests/SkStrikeTest.cpp
index 24354cd..7a6fc72 100644
--- a/tests/SkStrikeTest.cpp
+++ b/tests/SkStrikeTest.cpp
@@ -120,8 +120,7 @@
accepted.ensureSize(glyphCount);
rejected.setSource(local);
- accepted.startDevicePositioning(
- rejected.source(), SkMatrix::I(), strike.roundingSpec());
+ accepted.startSource(rejected.source());
prepare_for_mask_drawing(&strike, &accepted, &rejected);
rejected.flipRejectsToSource();
accepted.reset();