move drawTextPaths from RTC to SubRun

Move drawing text as paths to the SubRun in anticipation of producing
a virtual draw() interface.

Change-Id: Iba9f948a8036a955a0205a098279825a72dc95c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302261
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Herb Derby 2020-07-13 10:42:18 -04:00 committed by Skia Commit-Bot
parent 85894305bf
commit c1583cba22
4 changed files with 62 additions and 63 deletions

View File

@ -424,61 +424,6 @@ static SkColor compute_canonical_color(const SkPaint& paint, bool lcd) {
return canonicalColor;
}
void GrRenderTargetContext::drawTextPaths(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrTextBlob::SubRun* subRun) {
SkASSERT(!subRun->paths().empty());
SkPoint drawOrigin = glyphRunList.origin();
const SkPaint& drawPaint = glyphRunList.paint();
SkPaint runPaint{drawPaint};
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(viewMatrix, pathMatrix);
GrStyledShape shape(path, drawPaint);
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, drawPaint);
GrBlurUtils::drawShapeWithMaskFilter(
this->fContext, this, clip, runPaint, viewMatrix, shape);
}
}
}
void GrRenderTargetContext::drawGlyphRunList(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList) {
@ -560,7 +505,7 @@ void GrRenderTargetContext::drawGlyphRunList(const GrClip* clip,
for (GrTextBlob::SubRun* subRun : blob->subRunList()) {
if (subRun->drawAsPaths()) {
this->drawTextPaths(clip, viewMatrix, glyphRunList, subRun);
subRun->drawPaths(clip, viewMatrix, glyphRunList, this);
} else {
auto [drawingClip, op] = subRun->makeAtlasTextOp(clip, viewMatrix, glyphRunList, this);
if (op != nullptr) {

View File

@ -473,6 +473,7 @@ public:
const SkMatrix& viewMatrix,
const SkRect& oval,
const GrStyle& style);
/**
* Draws a partial arc of an oval.
*
@ -510,13 +511,6 @@ public:
GrSamplerState::Filter,
std::unique_ptr<SkLatticeIter>,
const SkRect& dst);
/**
* Draw the paths for text.
*/
void drawTextPaths(const GrClip*,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrTextBlob::SubRun* subRun);
/**
* Draw the text specified by the SkGlyphRunList.

View File

@ -189,6 +189,61 @@ GrTextBlob::SubRun::makeAtlasTextOp(const GrClip* clip,
return {clip, std::move(op)};
}
void GrTextBlob::SubRun::drawPaths(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc) {
SkASSERT(!this->paths().empty());
SkPoint drawOrigin = glyphRunList.origin();
const SkPaint& drawPaint = glyphRunList.paint();
SkPaint runPaint{drawPaint};
runPaint.setAntiAlias(this->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 = this->strikeSpec().strikeToSourceRatio();
SkMatrix strikeToSource = SkMatrix::Scale(scale, scale);
strikeToSource.postTranslate(drawOrigin.x(), drawOrigin.y());
if (!needsExactCTM) {
for (const auto& pathPos : this->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(viewMatrix, pathMatrix);
GrStyledShape shape(path, drawPaint);
GrBlurUtils::drawShapeWithMaskFilter(
rtc->priv().getContext(), rtc, 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 : this->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, drawPaint);
GrBlurUtils::drawShapeWithMaskFilter(
rtc->priv().getContext(), rtc, clip, runPaint, viewMatrix, shape);
}
}
}
void GrTextBlob::SubRun::resetBulkUseToken() { fBulkUseToken.reset(); }
GrDrawOpAtlas::BulkUseTokenUpdater* GrTextBlob::SubRun::bulkUseToken() { return &fBulkUseToken; }

View File

@ -269,6 +269,11 @@ public:
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc);
void drawPaths(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc);
// TODO when this object is more internal, drop the privacy
void resetBulkUseToken();
GrDrawOpAtlas::BulkUseTokenUpdater* bulkUseToken();