move insertSubRunOpsIntoTarget into GrRenderTargetContext
Change-Id: I1ba96ac0951aa89a076b9ad1383b5ae172e4266f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/301382
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 1fbdcdc..3993733 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -555,8 +555,107 @@
}
for (GrTextBlob::SubRun* subRun : blob->subRunList()) {
- subRun->insertSubRunOpsIntoTarget(
- fTextTarget.get(), fSurfaceProps, blobPaint, clip, matrixProvider, drawOrigin);
+ if (subRun->drawAsPaths()) {
+ SkASSERT(!subRun->paths().empty());
+ SkPaint runPaint{blobPaint};
+ runPaint.setAntiAlias(subRun->isAntiAliased());
+ // If there are shaders, blurs or styles, the path must be scaled into source
+ // space independently of the CTM. This allows the CTM to be correct for the
+ // different effects.
+ GrStyle style(runPaint);
+
+ bool needsExactCTM = runPaint.getShader()
+ || style.applies()
+ || runPaint.getMaskFilter();
+
+ // Calculate the matrix that maps the path glyphs from their size in the strike to
+ // the graphics source space.
+ SkScalar scale = subRun->strikeSpec().strikeToSourceRatio();
+ SkMatrix strikeToSource = SkMatrix::Scale(scale, scale);
+ strikeToSource.postTranslate(drawOrigin.x(), drawOrigin.y());
+ if (!needsExactCTM) {
+ for (const auto& pathPos : subRun->paths()) {
+ const SkPath& path = pathPos.fPath;
+ const SkPoint pos = pathPos.fOrigin; // Transform the glyph to source space.
+ SkMatrix pathMatrix = strikeToSource;
+ pathMatrix.postTranslate(pos.x(), pos.y());
+ SkPreConcatMatrixProvider strikeToDevice(matrixProvider, pathMatrix);
+
+ GrStyledShape shape(path, blobPaint);
+ GrBlurUtils::drawShapeWithMaskFilter(
+ this->fContext, this, clip, runPaint, strikeToDevice, shape);
+ }
+ } else {
+ // Transform the path to device because the deviceMatrix must be unchanged to
+ // draw effect, filter or shader paths.
+ for (const auto& pathPos : subRun->paths()) {
+ const SkPath& path = pathPos.fPath;
+ const SkPoint pos = pathPos.fOrigin;
+ // Transform the glyph to source space.
+ SkMatrix pathMatrix = strikeToSource;
+ pathMatrix.postTranslate(pos.x(), pos.y());
+
+ SkPath deviceOutline;
+ path.transform(pathMatrix, &deviceOutline);
+ deviceOutline.setIsVolatile(true);
+ GrStyledShape shape(deviceOutline, blobPaint);
+ GrBlurUtils::drawShapeWithMaskFilter(
+ this->fContext, this, clip, runPaint, matrixProvider, shape);
+ }
+ }
+ } else {
+ // Handle the mask and distance field cases.
+ SkASSERT(subRun->glyphCount() != 0);
+
+ // We can clip geometrically using clipRect and ignore clip if we're not using SDFs or
+ // transformed glyphs, and we have an axis-aligned rectangular non-AA clip.
+ std::unique_ptr<GrAtlasTextOp> op;
+ const GrClip* subRunClip = clip;
+ if (!subRun->drawAsDistanceFields()) {
+ SkIRect clipRect = SkIRect::MakeEmpty();
+ if (!subRun->needsTransform()) {
+ // We only need to do clipping work if the SubRun isn't contained by the clip
+ SkRect subRunBounds = subRun->deviceRect(
+ matrixProvider.localToDevice(), drawOrigin);
+ SkRect renderTargetBounds = SkRect::MakeWH(this->width(), this->height());
+ if (subRunClip == nullptr && !renderTargetBounds.intersects(subRunBounds)) {
+ // If the SubRun is completely outside, don't add an op for it.
+ continue;
+ } else if (subRunClip != nullptr) {
+ GrClip::PreClipResult result = subRunClip->preApply(subRunBounds);
+ if (result.fEffect == GrClip::Effect::kClipped) {
+ if (result.fIsRRect && result.fRRect.isRect() &&
+ result.fAA == GrAA::kNo) {
+ // Clip geometrically during onPrepare using clipRect.
+ result.fRRect.getBounds().round(&clipRect);
+ subRunClip = nullptr;
+ }
+ } else if (result.fEffect == GrClip::Effect::kClippedOut) {
+ continue;
+ }
+ }
+ }
+
+ if (!clipRect.isEmpty()) { SkASSERT(subRunClip == nullptr); }
+
+ op = GrAtlasTextOp::MakeBitmap(this,
+ blobPaint,
+ subRun,
+ matrixProvider,
+ drawOrigin,
+ clipRect);
+ } else {
+ op = GrAtlasTextOp::MakeDistanceField(this,
+ blobPaint,
+ subRun,
+ matrixProvider,
+ drawOrigin);
+ }
+
+ if (op != nullptr) {
+ this->addDrawOp(subRunClip, std::move(op));
+ }
+ }
}
}