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();