aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-01-13 12:02:17 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-13 17:38:10 +0000
commit6f1d36cc54dc635f5e4d0f925ef79c14914342bb (patch)
treeb133ea2048fe159d2fef718e828ede8965a031cb /src
parent0ed3b640c9da71fbbd73c65a4ec1992f85596271 (diff)
Delay SkPaint->GrPaint conversion in text rendering.
This fixes an issue where color filters aren't correctly applied to color glyphs. Instead we apply the filter to the SkPaint's color which is correct for mask glyphs only. Add color filter and alpha + various effects to coloremoji gm Change-Id: If77dece71d43468fec65499857eaaaedb56428e9 Reviewed-on: https://skia-review.googlesource.com/6891 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrPathRenderingRenderTargetContext.cpp19
-rw-r--r--src/gpu/GrPathRenderingRenderTargetContext.h12
-rw-r--r--src/gpu/GrRenderTargetContext.cpp27
-rw-r--r--src/gpu/SkGpuDevice.cpp18
-rw-r--r--src/gpu/SkGrPriv.h2
-rw-r--r--src/gpu/text/GrAtlasTextBlob.cpp113
-rw-r--r--src/gpu/text/GrAtlasTextBlob.h39
-rw-r--r--src/gpu/text/GrAtlasTextContext.cpp205
-rw-r--r--src/gpu/text/GrAtlasTextContext.h20
-rw-r--r--src/gpu/text/GrStencilAndCoverTextContext.cpp104
-rw-r--r--src/gpu/text/GrStencilAndCoverTextContext.h6
-rw-r--r--src/gpu/text/GrTextUtils.cpp146
-rw-r--r--src/gpu/text/GrTextUtils.h130
13 files changed, 408 insertions, 433 deletions
diff --git a/src/gpu/GrPathRenderingRenderTargetContext.cpp b/src/gpu/GrPathRenderingRenderTargetContext.cpp
index 3319a05743..90966a8e84 100644
--- a/src/gpu/GrPathRenderingRenderTargetContext.cpp
+++ b/src/gpu/GrPathRenderingRenderTargetContext.cpp
@@ -15,8 +15,7 @@
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
#define RETURN_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return; }
-void GrPathRenderingRenderTargetContext::drawText(const GrClip& clip, GrPaint&& grPaint,
- const SkPaint& skPaint,
+void GrPathRenderingRenderTargetContext::drawText(const GrClip& clip, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const char text[],
size_t byteLength, SkScalar x, SkScalar y,
const SkIRect& clipBounds) {
@@ -30,13 +29,12 @@ void GrPathRenderingRenderTargetContext::drawText(const GrClip& clip, GrPaint&&
fStencilAndCoverTextContext.reset(GrStencilAndCoverTextContext::Create(fallbackContext));
}
- fStencilAndCoverTextContext->drawText(this->drawingManager()->getContext(), this, clip,
- std::move(grPaint), skPaint, viewMatrix,
- this->surfaceProps(), text, byteLength, x, y, clipBounds);
+ fStencilAndCoverTextContext->drawText(this->drawingManager()->getContext(), this, clip, skPaint,
+ viewMatrix, this->surfaceProps(), text, byteLength, x, y,
+ clipBounds);
}
-void GrPathRenderingRenderTargetContext::drawPosText(const GrClip& clip, GrPaint&& grPaint,
- const SkPaint& skPaint,
+void GrPathRenderingRenderTargetContext::drawPosText(const GrClip& clip, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const char text[],
size_t byteLength, const SkScalar pos[],
int scalarsPerPosition, const SkPoint& offset,
@@ -52,10 +50,9 @@ void GrPathRenderingRenderTargetContext::drawPosText(const GrClip& clip, GrPaint
fStencilAndCoverTextContext.reset(GrStencilAndCoverTextContext::Create(fallbackContext));
}
- fStencilAndCoverTextContext->drawPosText(this->drawingManager()->getContext(), this, clip,
- std::move(grPaint), skPaint, viewMatrix,
- this->surfaceProps(), text, byteLength, pos,
- scalarsPerPosition, offset, clipBounds);
+ fStencilAndCoverTextContext->drawPosText(
+ this->drawingManager()->getContext(), this, clip, skPaint, viewMatrix,
+ this->surfaceProps(), text, byteLength, pos, scalarsPerPosition, offset, clipBounds);
}
void GrPathRenderingRenderTargetContext::drawTextBlob(const GrClip& clip, const SkPaint& skPaint,
diff --git a/src/gpu/GrPathRenderingRenderTargetContext.h b/src/gpu/GrPathRenderingRenderTargetContext.h
index 05975397cd..d26f08ecdb 100644
--- a/src/gpu/GrPathRenderingRenderTargetContext.h
+++ b/src/gpu/GrPathRenderingRenderTargetContext.h
@@ -14,13 +14,11 @@ class GrStencilAndCoverTextContext;
class GrPathRenderingRenderTargetContext : public GrRenderTargetContext {
public:
- void drawText(const GrClip&, GrPaint&&, const SkPaint&, const SkMatrix& viewMatrix,
- const char text[], size_t byteLength, SkScalar x, SkScalar y,
- const SkIRect& clipBounds) override;
- void drawPosText(const GrClip&, GrPaint&&, const SkPaint&, const SkMatrix& viewMatrix,
- const char text[], size_t byteLength, const SkScalar pos[],
- int scalarsPerPosition, const SkPoint& offset,
- const SkIRect& clipBounds) override;
+ void drawText(const GrClip&, const SkPaint&, const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, SkScalar x, SkScalar y, const SkIRect& clipBounds) override;
+ void drawPosText(const GrClip&, const SkPaint&, const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset, const SkIRect& clipBounds) override;
void drawTextBlob(const GrClip&, const SkPaint&,
const SkMatrix& viewMatrix, const SkTextBlob*,
SkScalar x, SkScalar y,
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 968663cd64..b0d941b273 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -158,7 +158,7 @@ bool GrRenderTargetContext::onCopy(GrSurfaceProxy* srcProxy,
return this->getOpList()->copySurface(rt.get(), src.get(), srcRect, dstPoint);
}
-void GrRenderTargetContext::drawText(const GrClip& clip, GrPaint&& grPaint, const SkPaint& skPaint,
+void GrRenderTargetContext::drawText(const GrClip& clip, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const char text[],
size_t byteLength, SkScalar x, SkScalar y,
const SkIRect& clipBounds) {
@@ -168,13 +168,13 @@ void GrRenderTargetContext::drawText(const GrClip& clip, GrPaint&& grPaint, cons
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawText");
GrAtlasTextContext* atlasTextContext = fDrawingManager->getAtlasTextContext();
- atlasTextContext->drawText(fContext, this, clip, std::move(grPaint), skPaint, viewMatrix,
- fSurfaceProps, text, byteLength, x, y, clipBounds);
+ atlasTextContext->drawText(fContext, this, clip, skPaint, viewMatrix, fSurfaceProps, text,
+ byteLength, x, y, clipBounds);
}
-void GrRenderTargetContext::drawPosText(const GrClip& clip, GrPaint&& grPaint,
- const SkPaint& skPaint, const SkMatrix& viewMatrix,
- const char text[], size_t byteLength, const SkScalar pos[],
+void GrRenderTargetContext::drawPosText(const GrClip& clip, const SkPaint& paint,
+ const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, const SkScalar pos[],
int scalarsPerPosition, const SkPoint& offset,
const SkIRect& clipBounds) {
ASSERT_SINGLE_OWNER
@@ -183,23 +183,22 @@ void GrRenderTargetContext::drawPosText(const GrClip& clip, GrPaint&& grPaint,
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawPosText");
GrAtlasTextContext* atlasTextContext = fDrawingManager->getAtlasTextContext();
- atlasTextContext->drawPosText(fContext, this, clip, std::move(grPaint), skPaint, viewMatrix,
- fSurfaceProps, text, byteLength, pos, scalarsPerPosition, offset,
- clipBounds);
+ atlasTextContext->drawPosText(fContext, this, clip, paint, viewMatrix, fSurfaceProps, text,
+ byteLength, pos, scalarsPerPosition, offset, clipBounds);
}
-void GrRenderTargetContext::drawTextBlob(const GrClip& clip, const SkPaint& skPaint,
+void GrRenderTargetContext::drawTextBlob(const GrClip& clip, const SkPaint& paint,
const SkMatrix& viewMatrix, const SkTextBlob* blob,
- SkScalar x, SkScalar y,
- SkDrawFilter* filter, const SkIRect& clipBounds) {
+ SkScalar x, SkScalar y, SkDrawFilter* filter,
+ const SkIRect& clipBounds) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawTextBlob");
GrAtlasTextContext* atlasTextContext = fDrawingManager->getAtlasTextContext();
- atlasTextContext->drawTextBlob(fContext, this, clip, skPaint, viewMatrix, fSurfaceProps, blob,
- x, y, filter, clipBounds);
+ atlasTextContext->drawTextBlob(fContext, this, clip, paint, viewMatrix, fSurfaceProps, blob, x,
+ y, filter, clipBounds);
}
void GrRenderTargetContext::discard() {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index bf9341f435..258713c537 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1727,16 +1727,9 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
ASSERT_SINGLE_OWNER
CHECK_SHOULD_DRAW(draw);
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext.get());
-
- GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
- &grPaint)) {
- return;
- }
-
SkDEBUGCODE(this->validate();)
- fRenderTargetContext->drawText(fClip, std::move(grPaint), paint, *draw.fMatrix,
+ fRenderTargetContext->drawText(fClip, paint, *draw.fMatrix,
(const char*)text, byteLength, x, y, draw.fRC->getBounds());
}
@@ -1746,16 +1739,9 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPosText", fContext.get());
CHECK_SHOULD_DRAW(draw);
-
- GrPaint grPaint;
- if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
- &grPaint)) {
- return;
- }
-
SkDEBUGCODE(this->validate();)
- fRenderTargetContext->drawPosText(fClip, std::move(grPaint), paint, *draw.fMatrix,
+ fRenderTargetContext->drawPosText(fClip, paint, *draw.fMatrix,
(const char*)text, byteLength, pos, scalarsPerPos, offset,
draw.fRC->getBounds());
}
diff --git a/src/gpu/SkGrPriv.h b/src/gpu/SkGrPriv.h
index c64646bf17..a4e3976126 100644
--- a/src/gpu/SkGrPriv.h
+++ b/src/gpu/SkGrPriv.h
@@ -21,9 +21,11 @@ class GrFragmentProcessor;
class GrPaint;
class GrTexture;
class GrUniqueKey;
+class SkBitmap;
class SkData;
class SkPaint;
class SkPixelRef;
+class SkPixmap;
struct SkIRect;
/**
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 5e3b4bf4ff..321c4a6750 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -6,7 +6,6 @@
*/
#include "GrAtlasTextBlob.h"
-
#include "GrBlurUtils.h"
#include "GrContext.h"
#include "GrPipelineBuilder.h"
@@ -169,14 +168,14 @@ void GrAtlasTextBlob::appendLargeGlyph(GrGlyph* glyph, SkGlyphCache* cache, cons
fBigGlyphs.push_back(GrAtlasTextBlob::BigGlyph(*glyph->fPath, x, y, scale, treatAsBMP));
}
-bool GrAtlasTextBlob::mustRegenerate(const SkPaint& paint,
- GrColor color, const SkMaskFilter::BlurRec& blurRec,
+bool GrAtlasTextBlob::mustRegenerate(const GrTextUtils::Paint& paint,
+ const SkMaskFilter::BlurRec& blurRec,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
// If we have LCD text then our canonical color will be set to transparent, in this case we have
// to regenerate the blob on any color change
// We use the grPaint to get any color filter effects
if (fKey.fCanonicalColor == SK_ColorTRANSPARENT &&
- fPaintColor != color) {
+ fFilteredPaintColor != paint.filteredSkColor()) {
return true;
}
@@ -198,9 +197,9 @@ bool GrAtlasTextBlob::mustRegenerate(const SkPaint& paint,
// Similarly, we only cache one version for each style
if (fKey.fStyle != SkPaint::kFill_Style &&
- (fStrokeInfo.fFrameWidth != paint.getStrokeWidth() ||
- fStrokeInfo.fMiterLimit != paint.getStrokeMiter() ||
- fStrokeInfo.fJoin != paint.getStrokeJoin())) {
+ (fStrokeInfo.fFrameWidth != paint.skPaint().getStrokeWidth() ||
+ fStrokeInfo.fMiterLimit != paint.skPaint().getStrokeMiter() ||
+ fStrokeInfo.fJoin != paint.skPaint().getStrokeJoin())) {
return true;
}
@@ -256,27 +255,14 @@ bool GrAtlasTextBlob::mustRegenerate(const SkPaint& paint,
inline std::unique_ptr<GrDrawOp> GrAtlasTextBlob::makeOp(
const Run::SubRunInfo& info, int glyphCount, int run, int subRun,
- const SkMatrix& viewMatrix, SkScalar x, SkScalar y, GrColor color, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const GrTextUtils::Paint& paint,
const SkSurfaceProps& props, const GrDistanceFieldAdjustTable* distanceAdjustTable,
bool useGammaCorrectDistanceTable, GrAtlasGlyphCache* cache) {
GrMaskFormat format = info.maskFormat();
- GrColor subRunColor;
- if (kARGB_GrMaskFormat == format) {
- uint8_t paintAlpha = skPaint.getAlpha();
- subRunColor = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha);
- } else {
- subRunColor = color;
- }
std::unique_ptr<GrAtlasTextOp> op;
if (info.drawAsDistanceFields()) {
- SkColor filteredColor;
- SkColorFilter* colorFilter = skPaint.getColorFilter();
- if (colorFilter) {
- filteredColor = colorFilter->filterColor(skPaint.getColor());
- } else {
- filteredColor = skPaint.getColor();
- }
+ SkColor filteredColor = paint.filteredSkColor();
bool useBGR = SkPixelGeometryIsBGR(props.pixelGeometry());
op = GrAtlasTextOp::MakeDistanceField(glyphCount, cache, distanceAdjustTable,
useGammaCorrectDistanceTable, filteredColor,
@@ -289,7 +275,8 @@ inline std::unique_ptr<GrDrawOp> GrAtlasTextBlob::makeOp(
geometry.fBlob = SkRef(this);
geometry.fRun = run;
geometry.fSubRun = subRun;
- geometry.fColor = subRunColor;
+ geometry.fColor =
+ info.maskFormat() == kARGB_GrMaskFormat ? GrColor_WHITE : paint.filteredPremulGrColor();
geometry.fX = x;
geometry.fY = y;
op->init();
@@ -297,27 +284,27 @@ inline std::unique_ptr<GrDrawOp> GrAtlasTextBlob::makeOp(
return std::move(op);
}
-inline void GrAtlasTextBlob::flushRun(GrRenderTargetContext* rtc, GrPaint&& grPaint,
- const GrClip& clip, int run, const SkMatrix& viewMatrix,
- SkScalar x, SkScalar y, const SkPaint& skPaint,
- const SkSurfaceProps& props,
+inline void GrAtlasTextBlob::flushRun(GrRenderTargetContext* rtc, const GrClip& clip, int run,
+ const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
+ const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
GrAtlasGlyphCache* cache) {
int lastRun = fRuns[run].fSubRunInfo.count() - 1;
for (int subRun = 0; subRun <= lastRun; subRun++) {
const Run::SubRunInfo& info = fRuns[run].fSubRunInfo[subRun];
+ GrPaint grPaint;
+ if (!paint.toGrPaint(info.maskFormat(), rtc, viewMatrix, &grPaint)) {
+ continue;
+ }
int glyphCount = info.glyphCount();
if (0 == glyphCount) {
continue;
}
- GrColor color = grPaint.getColor();
-
std::unique_ptr<GrDrawOp> op(this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y,
- color, skPaint, props, distanceAdjustTable,
+ paint, props, distanceAdjustTable,
rtc->isGammaCorrect(), cache));
- GrPipelineBuilder pipelineBuilder(GrPaint::MoveOrClone(grPaint, subRun < lastRun),
- GrAAType::kNone);
+ GrPipelineBuilder pipelineBuilder(std::move(grPaint), GrAAType::kNone);
rtc->addDrawOp(pipelineBuilder, clip, std::move(op));
}
@@ -343,9 +330,8 @@ static void calculate_translation(bool applyVM,
}
}
-
void GrAtlasTextBlob::flushBigGlyphs(GrContext* context, GrRenderTargetContext* rtc,
- const GrClip& clip, const SkPaint& skPaint,
+ const GrClip& clip, const SkPaint& paint,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
const SkIRect& clipBounds) {
SkScalar transX, transY;
@@ -360,46 +346,39 @@ void GrAtlasTextBlob::flushBigGlyphs(GrContext* context, GrRenderTargetContext*
ctm.postConcat(viewMatrix);
}
- GrBlurUtils::drawPathWithMaskFilter(context, rtc, clip, bigGlyph.fPath,
- skPaint, ctm, nullptr, clipBounds, false);
+ GrBlurUtils::drawPathWithMaskFilter(context, rtc, clip, bigGlyph.fPath, paint, ctm, nullptr,
+ clipBounds, false);
}
}
void GrAtlasTextBlob::flushRunAsPaths(GrContext* context, GrRenderTargetContext* rtc,
- const SkSurfaceProps& props,
- const SkTextBlobRunIterator& it,
- const GrClip& clip, const SkPaint& skPaint,
+ const SkSurfaceProps& props, const SkTextBlobRunIterator& it,
+ const GrClip& clip, const GrTextUtils::Paint& paint,
SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
const SkIRect& clipBounds, SkScalar x, SkScalar y) {
- SkPaint runPaint = skPaint;
-
size_t textLen = it.glyphCount() * sizeof(uint16_t);
const SkPoint& offset = it.offset();
- it.applyFontToPaint(&runPaint);
-
- if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) {
+ GrTextUtils::RunPaint runPaint(&paint, drawFilter, props);
+ if (!runPaint.modifyForRun(it)) {
return;
}
- runPaint.setFlags(GrTextUtils::FilterTextFlags(props, runPaint));
-
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning:
GrTextUtils::DrawTextAsPath(context, rtc, clip, runPaint, viewMatrix,
- (const char *)it.glyphs(),
- textLen, x + offset.x(), y + offset.y(), clipBounds);
+ (const char*)it.glyphs(), textLen, x + offset.x(),
+ y + offset.y(), clipBounds);
break;
case SkTextBlob::kHorizontal_Positioning:
GrTextUtils::DrawPosTextAsPath(context, rtc, props, clip, runPaint, viewMatrix,
- (const char*)it.glyphs(),
- textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()),
- clipBounds);
+ (const char*)it.glyphs(), textLen, it.pos(), 1,
+ SkPoint::Make(x, y + offset.y()), clipBounds);
break;
case SkTextBlob::kFull_Positioning:
GrTextUtils::DrawPosTextAsPath(context, rtc, props, clip, runPaint, viewMatrix,
- (const char*)it.glyphs(),
- textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds);
+ (const char*)it.glyphs(), textLen, it.pos(), 2,
+ SkPoint::Make(x, y), clipBounds);
break;
}
}
@@ -407,49 +386,47 @@ void GrAtlasTextBlob::flushRunAsPaths(GrContext* context, GrRenderTargetContext*
void GrAtlasTextBlob::flushCached(GrContext* context, GrRenderTargetContext* rtc,
const SkTextBlob* blob, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
- const SkPaint& skPaint, GrPaint&& grPaint,
- SkDrawFilter* drawFilter, const GrClip& clip,
- const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
- SkScalar y) {
+ const GrTextUtils::Paint& paint, SkDrawFilter* drawFilter,
+ const GrClip& clip, const SkMatrix& viewMatrix,
+ const SkIRect& clipBounds, SkScalar x, SkScalar y) {
// We loop through the runs of the blob, flushing each. If any run is too large, then we flush
// it as paths
SkTextBlobRunIterator it(blob);
for (int run = 0; !it.done(); it.next(), run++) {
if (fRuns[run].fDrawAsPaths) {
- this->flushRunAsPaths(context, rtc, props, it, clip, skPaint,
- drawFilter, viewMatrix, clipBounds, x, y);
+ this->flushRunAsPaths(context, rtc, props, it, clip, paint, drawFilter, viewMatrix,
+ clipBounds, x, y);
continue;
}
- this->flushRun(rtc, GrPaint::MoveOrClone(grPaint, !it.done()), clip, run, viewMatrix, x, y,
- skPaint, props, distanceAdjustTable, context->getAtlasGlyphCache());
+ this->flushRun(rtc, clip, run, viewMatrix, x, y, paint, props, distanceAdjustTable,
+ context->getAtlasGlyphCache());
}
// Now flush big glyphs
- this->flushBigGlyphs(context, rtc, clip, skPaint, viewMatrix, x, y, clipBounds);
+ this->flushBigGlyphs(context, rtc, clip, paint, viewMatrix, x, y, clipBounds);
}
void GrAtlasTextBlob::flushThrowaway(GrContext* context, GrRenderTargetContext* rtc,
const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
- const SkPaint& skPaint, GrPaint&& grPaint, const GrClip& clip,
+ const GrTextUtils::Paint& paint, const GrClip& clip,
const SkMatrix& viewMatrix, const SkIRect& clipBounds,
SkScalar x, SkScalar y) {
for (int run = 0; run < fRunCount; run++) {
- this->flushRun(rtc, GrPaint::MoveOrClone(grPaint, run + 1 != fRunCount), clip, run,
- viewMatrix, x, y, skPaint, props, distanceAdjustTable,
+ this->flushRun(rtc, clip, run, viewMatrix, x, y, paint, props, distanceAdjustTable,
context->getAtlasGlyphCache());
}
// Now flush big glyphs
- this->flushBigGlyphs(context, rtc, clip, skPaint, viewMatrix, x, y, clipBounds);
+ this->flushBigGlyphs(context, rtc, clip, paint, viewMatrix, x, y, clipBounds);
}
std::unique_ptr<GrDrawOp> GrAtlasTextBlob::test_makeOp(
int glyphCount, int run, int subRun, const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
- GrColor color, const SkPaint& skPaint, const SkSurfaceProps& props,
+ const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable, GrAtlasGlyphCache* cache) {
const GrAtlasTextBlob::Run::SubRunInfo& info = fRuns[run].fSubRunInfo[subRun];
- return this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, color, skPaint, props,
+ return this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, paint, props,
distanceAdjustTable, false, cache);
}
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index f4e149ff73..787518de69 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -12,6 +12,7 @@
#include "GrColor.h"
#include "GrDrawOpAtlas.h"
#include "GrMemoryPool.h"
+#include "GrTextUtils.h"
#include "SkDescriptor.h"
#include "SkMaskFilter.h"
#include "SkOpts.h"
@@ -177,20 +178,20 @@ public:
}
}
- bool mustRegenerate(const SkPaint& paint, GrColor color, const SkMaskFilter::BlurRec& blurRec,
+ bool mustRegenerate(const GrTextUtils::Paint&, const SkMaskFilter::BlurRec& blurRec,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
// flush a GrAtlasTextBlob associated with a SkTextBlob
void flushCached(GrContext* context, GrRenderTargetContext* rtc, const SkTextBlob* blob,
const SkSurfaceProps& props,
- const GrDistanceFieldAdjustTable* distanceAdjustTable, const SkPaint& skPaint,
- GrPaint&& grPaint, SkDrawFilter* drawFilter, const GrClip& clip,
+ const GrDistanceFieldAdjustTable* distanceAdjustTable,
+ const GrTextUtils::Paint&, SkDrawFilter* drawFilter, const GrClip& clip,
const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y);
// flush a throwaway GrAtlasTextBlob *not* associated with an SkTextBlob
void flushThrowaway(GrContext* context, GrRenderTargetContext* rtc, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
- const SkPaint& skPaint, GrPaint&& grPaint, const GrClip& clip,
+ const GrTextUtils::Paint& paint, const GrClip& clip,
const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
SkScalar y);
@@ -238,8 +239,9 @@ public:
// The color here is the GrPaint color, and it is used to determine whether we
// have to regenerate LCD text blobs.
// We use this color vs the SkPaint color because it has the colorfilter applied.
- void initReusableBlob(GrColor color, const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
- fPaintColor = color;
+ void initReusableBlob(SkColor filteredColor, const SkMatrix& viewMatrix, SkScalar x,
+ SkScalar y) {
+ fFilteredPaintColor = filteredColor;
this->setupViewMatrix(viewMatrix, x, y);
}
@@ -269,7 +271,7 @@ public:
// Internal test methods
std::unique_ptr<GrDrawOp> test_makeOp(int glyphCount, int run, int subRun,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
- GrColor color, const SkPaint& skPaint,
+ const GrTextUtils::Paint& paint,
const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
GrAtlasGlyphCache* cache);
@@ -283,22 +285,19 @@ private:
void appendLargeGlyph(GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph,
SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP);
- inline void flushRun(GrRenderTargetContext* rtc, GrPaint&&, const GrClip&, int run,
- const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const SkPaint& skPaint,
- const SkSurfaceProps& props,
+ inline void flushRun(GrRenderTargetContext* rtc, const GrClip&, int run,
+ const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
+ const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
GrAtlasGlyphCache* cache);
- void flushBigGlyphs(GrContext* context, GrRenderTargetContext* rtc,
- const GrClip& clip, const SkPaint& skPaint,
- const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
+ void flushBigGlyphs(GrContext* context, GrRenderTargetContext* rtc, const GrClip& clip,
+ const SkPaint& paint, const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
const SkIRect& clipBounds);
- void flushRunAsPaths(GrContext* context,
- GrRenderTargetContext* rtc,
- const SkSurfaceProps& props,
- const SkTextBlobRunIterator& it,
- const GrClip& clip, const SkPaint& skPaint,
+ void flushRunAsPaths(GrContext* context, GrRenderTargetContext* rtc,
+ const SkSurfaceProps& props, const SkTextBlobRunIterator& it,
+ const GrClip& clip, const GrTextUtils::Paint& paint,
SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
const SkIRect& clipBounds, SkScalar x, SkScalar y);
@@ -491,7 +490,7 @@ private:
inline std::unique_ptr<GrDrawOp> makeOp(const Run::SubRunInfo& info, int glyphCount, int run,
int subRun, const SkMatrix& viewMatrix, SkScalar x,
- SkScalar y, GrColor color, const SkPaint& skPaint,
+ SkScalar y, const GrTextUtils::Paint& paint,
const SkSurfaceProps& props,
const GrDistanceFieldAdjustTable* distanceAdjustTable,
bool useGammaCorrectDistanceTable,
@@ -534,7 +533,7 @@ private:
SkMatrix fInitialViewMatrix;
SkMatrix fInitialViewMatrixInverse;
size_t fSize;
- GrColor fPaintColor;
+ SkColor fFilteredPaintColor;
SkScalar fInitialX;
SkScalar fInitialY;
diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
index 1d8571cd5f..07a653cdae 100644
--- a/src/gpu/text/GrAtlasTextContext.cpp
+++ b/src/gpu/text/GrAtlasTextContext.cpp
@@ -9,8 +9,6 @@
#include "GrContext.h"
#include "GrRenderTargetContext.h"
#include "GrTextBlobCache.h"
-#include "GrTextUtils.h"
-
#include "SkDraw.h"
#include "SkDrawFilter.h"
#include "SkGrPriv.h"
@@ -19,7 +17,6 @@ GrAtlasTextContext::GrAtlasTextContext()
: fDistanceAdjustTable(new GrDistanceFieldAdjustTable) {
}
-
GrAtlasTextContext* GrAtlasTextContext::Create() {
return new GrAtlasTextContext();
}
@@ -32,8 +29,8 @@ bool GrAtlasTextContext::canDraw(const SkPaint& skPaint,
!SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix);
}
-GrColor GrAtlasTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd) {
- GrColor canonicalColor = paint.computeLuminanceColor();
+SkColor GrAtlasTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd) {
+ SkColor canonicalColor = paint.computeLuminanceColor();
if (lcd) {
// This is the correct computation, but there are tons of cases where LCD can be overridden.
// For now we just regenerate if any run in a textblob has LCD.
@@ -121,24 +118,17 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrRenderTargetContext*
cacheBlob.reset(SkSafeRef(cache->find(key)));
}
- // Though for the time being runs in the textblob can override the paint, they only touch font
- // info.
- GrPaint grPaint;
- if (!SkPaintToGrPaint(context, rtc, skPaint, viewMatrix, &grPaint)) {
- return;
- }
-
+ GrTextUtils::Paint paint(&skPaint);
if (cacheBlob) {
- if (cacheBlob->mustRegenerate(skPaint, grPaint.getColor(), blurRec, viewMatrix, x, y)) {
+ if (cacheBlob->mustRegenerate(paint, blurRec, viewMatrix, x, y)) {
// We have to remake the blob because changes may invalidate our masks.
// TODO we could probably get away reuse most of the time if the pointer is unique,
// but we'd have to clear the subrun information
cache->remove(cacheBlob.get());
cacheBlob.reset(SkRef(cache->createCachedBlob(blob, key, blurRec, skPaint)));
RegenerateTextBlob(cacheBlob.get(), context->getAtlasGlyphCache(),
- *context->caps()->shaderCaps(), skPaint, grPaint.getColor(),
- scalerContextFlags, viewMatrix, props,
- blob, x, y, drawFilter);
+ *context->caps()->shaderCaps(), paint, scalerContextFlags,
+ viewMatrix, props, blob, x, y, drawFilter);
} else {
cache->makeMRU(cacheBlob.get());
@@ -149,9 +139,8 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrRenderTargetContext*
sk_sp<GrAtlasTextBlob> sanityBlob(cache->createBlob(glyphCount, runCount));
sanityBlob->setupKey(key, blurRec, skPaint);
RegenerateTextBlob(sanityBlob.get(), context->getAtlasGlyphCache(),
- *context->caps()->shaderCaps(), skPaint,
- grPaint.getColor(), scalerContextFlags, viewMatrix, props,
- blob, x, y, drawFilter);
+ *context->caps()->shaderCaps(), paint, scalerContextFlags,
+ viewMatrix, props, blob, x, y, drawFilter);
GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob);
}
}
@@ -162,70 +151,55 @@ void GrAtlasTextContext::drawTextBlob(GrContext* context, GrRenderTargetContext*
cacheBlob.reset(cache->createBlob(blob));
}
RegenerateTextBlob(cacheBlob.get(), context->getAtlasGlyphCache(),
- *context->caps()->shaderCaps(), skPaint, grPaint.getColor(),
- scalerContextFlags, viewMatrix, props,
- blob, x, y, drawFilter);
+ *context->caps()->shaderCaps(), paint, scalerContextFlags, viewMatrix,
+ props, blob, x, y, drawFilter);
}
- cacheBlob->flushCached(context, rtc, blob, props, fDistanceAdjustTable.get(), skPaint,
- std::move(grPaint), drawFilter, clip, viewMatrix, clipBounds, x, y);
+ cacheBlob->flushCached(context, rtc, blob, props, fDistanceAdjustTable.get(), paint, drawFilter,
+ clip, viewMatrix, clipBounds, x, y);
}
void GrAtlasTextContext::RegenerateTextBlob(GrAtlasTextBlob* cacheBlob,
GrAtlasGlyphCache* fontCache,
const GrShaderCaps& shaderCaps,
- const SkPaint& skPaint, GrColor color,
- uint32_t scalerContextFlags,
- const SkMatrix& viewMatrix,
- const SkSurfaceProps& props,
- const SkTextBlob* blob, SkScalar x, SkScalar y,
- SkDrawFilter* drawFilter) {
- cacheBlob->initReusableBlob(color, viewMatrix, x, y);
+ const GrTextUtils::Paint& paint,
+ uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
+ const SkSurfaceProps& props, const SkTextBlob* blob,
+ SkScalar x, SkScalar y, SkDrawFilter* drawFilter) {
+ cacheBlob->initReusableBlob(paint.filteredSkColor(), viewMatrix, x, y);
// Regenerate textblob
- SkPaint runPaint = skPaint;
SkTextBlobRunIterator it(blob);
+ GrTextUtils::RunPaint runPaint(&paint, drawFilter, props);
for (int run = 0; !it.done(); it.next(), run++) {
int glyphCount = it.glyphCount();
size_t textLen = glyphCount * sizeof(uint16_t);
const SkPoint& offset = it.offset();
- // applyFontToPaint() always overwrites the exact same attributes,
- // so it is safe to not re-seed the paint for this reason.
- it.applyFontToPaint(&runPaint);
-
- if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) {
- // A false return from filter() means we should abort the current draw.
- runPaint = skPaint;
+ cacheBlob->push_back_run(run);
+ if (!runPaint.modifyForRun(it)) {
continue;
}
-
- runPaint.setFlags(GrTextUtils::FilterTextFlags(props, runPaint));
-
- cacheBlob->push_back_run(run);
-
if (GrTextUtils::CanDrawAsDistanceFields(runPaint, viewMatrix, props, shaderCaps)) {
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning: {
- GrTextUtils::DrawDFText(cacheBlob, run, fontCache,
- props, runPaint, color, scalerContextFlags,
- viewMatrix, (const char *)it.glyphs(), textLen,
- x + offset.x(), y + offset.y());
+ GrTextUtils::DrawDFText(cacheBlob, run, fontCache, props, runPaint,
+ scalerContextFlags, viewMatrix,
+ (const char*)it.glyphs(), textLen, x + offset.x(),
+ y + offset.y());
break;
}
case SkTextBlob::kHorizontal_Positioning: {
SkPoint dfOffset = SkPoint::Make(x, y + offset.y());
- GrTextUtils::DrawDFPosText(cacheBlob, run, fontCache,
- props, runPaint, color, scalerContextFlags,
- viewMatrix, (const char*)it.glyphs(), textLen,
- it.pos(), 1, dfOffset);
+ GrTextUtils::DrawDFPosText(
+ cacheBlob, run, fontCache, props, runPaint, scalerContextFlags,
+ viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 1, dfOffset);
break;
}
case SkTextBlob::kFull_Positioning: {
SkPoint dfOffset = SkPoint::Make(x, y);
- GrTextUtils::DrawDFPosText(cacheBlob, run, fontCache,
- props, runPaint, color, scalerContextFlags,
- viewMatrix, (const char*)it.glyphs(), textLen,
- it.pos(), 2, dfOffset);
+ GrTextUtils::DrawDFPosText(
+ cacheBlob, run, fontCache, props, runPaint, scalerContextFlags,
+ viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2, dfOffset);
break;
}
}
@@ -234,30 +208,25 @@ void GrAtlasTextContext::RegenerateTextBlob(GrAtlasTextBlob* cacheBlob,
} else {
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning:
- GrTextUtils::DrawBmpText(cacheBlob, run, fontCache,
- props, runPaint, color, scalerContextFlags,
- viewMatrix, (const char *)it.glyphs(), textLen,
- x + offset.x(), y + offset.y());
+ GrTextUtils::DrawBmpText(cacheBlob, run, fontCache, props, runPaint,
+ scalerContextFlags, viewMatrix,
+ (const char*)it.glyphs(), textLen, x + offset.x(),
+ y + offset.y());
break;
case SkTextBlob::kHorizontal_Positioning:
- GrTextUtils::DrawBmpPosText(cacheBlob, run, fontCache,
- props, runPaint, color, scalerContextFlags,
- viewMatrix, (const char*)it.glyphs(), textLen,
- it.pos(), 1, SkPoint::Make(x, y + offset.y()));
+ GrTextUtils::DrawBmpPosText(cacheBlob, run, fontCache, props, runPaint,
+ scalerContextFlags, viewMatrix,
+ (const char*)it.glyphs(), textLen, it.pos(), 1,
+ SkPoint::Make(x, y + offset.y()));
break;
case SkTextBlob::kFull_Positioning:
- GrTextUtils::DrawBmpPosText(cacheBlob, run, fontCache,
- props, runPaint, color, scalerContextFlags,
- viewMatrix, (const char*)it.glyphs(), textLen,
- it.pos(), 2, SkPoint::Make(x, y));
+ GrTextUtils::DrawBmpPosText(cacheBlob, run, fontCache, props, runPaint,
+ scalerContextFlags, viewMatrix,
+ (const char*)it.glyphs(), textLen, it.pos(), 2,
+ SkPoint::Make(x, y));
break;
}
}
-
- if (drawFilter) {
- // A draw filter may change the paint arbitrarily, so we must re-seed in this case.
- runPaint = skPaint;
- }
}
}
@@ -265,106 +234,105 @@ inline GrAtlasTextBlob*
GrAtlasTextContext::CreateDrawTextBlob(GrTextBlobCache* blobCache,
GrAtlasGlyphCache* fontCache,
const GrShaderCaps& shaderCaps,
- const GrPaint& paint,
- const SkPaint& skPaint,
+ const GrTextUtils::Paint& paint,
uint32_t scalerContextFlags,
const SkMatrix& viewMatrix,
const SkSurfaceProps& props,
const char text[], size_t byteLength,
SkScalar x, SkScalar y) {
- int glyphCount = skPaint.countText(text, byteLength);
+ int glyphCount = paint.skPaint().countText(text, byteLength);
GrAtlasTextBlob* blob = blobCache->createBlob(glyphCount, 1);
blob->initThrowawayBlob(viewMatrix, x, y);
- if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, props, shaderCaps)) {
- GrTextUtils::DrawDFText(blob, 0, fontCache, props, skPaint, paint.getColor(),
- scalerContextFlags, viewMatrix, text, byteLength, x, y);
+ if (GrTextUtils::CanDrawAsDistanceFields(paint, viewMatrix, props, shaderCaps)) {
+ GrTextUtils::DrawDFText(blob, 0, fontCache, props, paint, scalerContextFlags, viewMatrix,
+ text, byteLength, x, y);
} else {
- GrTextUtils::DrawBmpText(blob, 0, fontCache, props, skPaint, paint.getColor(),
- scalerContextFlags, viewMatrix, text, byteLength, x, y);
+ GrTextUtils::DrawBmpText(blob, 0, fontCache, props, paint, scalerContextFlags, viewMatrix,
+ text, byteLength, x, y);
}
return blob;
}
inline GrAtlasTextBlob*
-GrAtlasTextContext::CreateDrawPosTextBlob(GrTextBlobCache* blobCache, GrAtlasGlyphCache* fontCache,
- const GrShaderCaps& shaderCaps, const GrPaint& paint,
- const SkPaint& skPaint, uint32_t scalerContextFlags,
- const SkMatrix& viewMatrix, const SkSurfaceProps& props,
+GrAtlasTextContext::CreateDrawPosTextBlob(GrTextBlobCache* blobCache,
+ GrAtlasGlyphCache* fontCache,
+ const GrShaderCaps& shaderCaps,
+ const GrTextUtils::Paint& paint,
+ uint32_t scalerContextFlags,
+ const SkMatrix& viewMatrix,
+ const SkSurfaceProps& props,
const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) {
- int glyphCount = skPaint.countText(text, byteLength);
+ const SkScalar pos[], int scalarsPerPosition, const
+ SkPoint& offset) {
+ int glyphCount = paint.skPaint().countText(text, byteLength);
GrAtlasTextBlob* blob = blobCache->createBlob(glyphCount, 1);
blob->initThrowawayBlob(viewMatrix, offset.x(), offset.y());
- if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, props, shaderCaps)) {
- GrTextUtils::DrawDFPosText(blob, 0, fontCache, props,
- skPaint, paint.getColor(), scalerContextFlags, viewMatrix, text,
- byteLength, pos, scalarsPerPosition, offset);
+ if (GrTextUtils::CanDrawAsDistanceFields(paint, viewMatrix, props, shaderCaps)) {
+ GrTextUtils::DrawDFPosText(blob, 0, fontCache, props, paint, scalerContextFlags, viewMatrix,
+ text, byteLength, pos, scalarsPerPosition, offset);
} else {
- GrTextUtils::DrawBmpPosText(blob, 0, fontCache, props, skPaint,
- paint.getColor(), scalerContextFlags, viewMatrix, text,
- byteLength, pos, scalarsPerPosition, offset);
+ GrTextUtils::DrawBmpPosText(blob, 0, fontCache, props, paint, scalerContextFlags,
+ viewMatrix, text, byteLength, pos, scalarsPerPosition, offset);
}
return blob;
}
void GrAtlasTextContext::drawText(GrContext* context, GrRenderTargetContext* rtc,
- const GrClip& clip, GrPaint&& paint, const SkPaint& skPaint,
+ const GrClip& clip, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const SkSurfaceProps& props,
const char text[], size_t byteLength, SkScalar x, SkScalar y,
const SkIRect& regionClipBounds) {
if (context->abandoned()) {
return;
- } else if (this->canDraw(skPaint, viewMatrix, props, *context->caps()->shaderCaps())) {
+ }
+ GrTextUtils::Paint paint(&skPaint);
+ if (this->canDraw(skPaint, viewMatrix, props, *context->caps()->shaderCaps())) {
sk_sp<GrAtlasTextBlob> blob(
CreateDrawTextBlob(context->getTextBlobCache(), context->getAtlasGlyphCache(),
*context->caps()->shaderCaps(),
- paint, skPaint,
- ComputeScalerContextFlags(rtc),
+ paint, ComputeScalerContextFlags(rtc),
viewMatrix, props,
text, byteLength, x, y));
- blob->flushThrowaway(context, rtc, props, fDistanceAdjustTable.get(), skPaint,
- std::move(paint), clip, viewMatrix, regionClipBounds, x, y);
+ blob->flushThrowaway(context, rtc, props, fDistanceAdjustTable.get(), paint, clip,
+ viewMatrix, regionClipBounds, x, y);
return;
}
// fall back to drawing as a path
- GrTextUtils::DrawTextAsPath(context, rtc, clip, skPaint, viewMatrix, text, byteLength, x, y,
+ GrTextUtils::DrawTextAsPath(context, rtc, clip, paint, viewMatrix, text, byteLength, x, y,
regionClipBounds);
}
void GrAtlasTextContext::drawPosText(GrContext* context, GrRenderTargetContext* rtc,
- const GrClip& clip, GrPaint&& paint, const SkPaint& skPaint,
+ const GrClip& clip, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const SkSurfaceProps& props,
const char text[], size_t byteLength, const SkScalar pos[],
int scalarsPerPosition, const SkPoint& offset,
const SkIRect& regionClipBounds) {
+ GrTextUtils::Paint paint(&skPaint);
if (context->abandoned()) {
return;
} else if (this->canDraw(skPaint, viewMatrix, props, *context->caps()->shaderCaps())) {
sk_sp<GrAtlasTextBlob> blob(
- CreateDrawPosTextBlob(context->getTextBlobCache(),
- context->getAtlasGlyphCache(),
+ CreateDrawPosTextBlob(context->getTextBlobCache(), context->getAtlasGlyphCache(),
*context->caps()->shaderCaps(),
- paint, skPaint,
- ComputeScalerContextFlags(rtc),
+ paint, ComputeScalerContextFlags(rtc),
viewMatrix, props,
text, byteLength,
pos, scalarsPerPosition,
offset));
- blob->flushThrowaway(context, rtc, props, fDistanceAdjustTable.get(), skPaint,
- std::move(paint), clip, viewMatrix, regionClipBounds, offset.fX,
- offset.fY);
+ blob->flushThrowaway(context, rtc, props, fDistanceAdjustTable.get(), paint, clip,
+ viewMatrix, regionClipBounds, offset.fX, offset.fY);
return;
}
// fall back to drawing as a path
- GrTextUtils::DrawPosTextAsPath(context, rtc, props, clip, skPaint, viewMatrix, text,
- byteLength, pos, scalarsPerPosition, offset, regionClipBounds);
+ GrTextUtils::DrawPosTextAsPath(context, rtc, props, clip, paint, viewMatrix, text, byteLength,
+ pos, scalarsPerPosition, offset, regionClipBounds);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -387,19 +355,13 @@ DRAW_OP_TEST_DEFINE(TextBlobOp) {
sk_sp<GrRenderTargetContext> renderTargetContext(context->makeRenderTargetContext(
SkBackingFit::kApprox, 1024, 1024, kRGBA_8888_GrPixelConfig, nullptr));
- GrColor color = GrRandomColor(random);
SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
SkPaint skPaint;
- skPaint.setColor(color);
+ skPaint.setColor(random->nextU());
skPaint.setLCDRenderText(random->nextBool());
skPaint.setAntiAlias(skPaint.isLCDRenderText() ? true : random->nextBool());
skPaint.setSubpixelText(random->nextBool());
- GrPaint grPaint;
- if (!SkPaintToGrPaint(context, renderTargetContext.get(), skPaint, viewMatrix, &grPaint)) {
- SkFAIL("couldn't convert paint\n");
- }
-
const char* text = "The quick brown fox jumps over the lazy dog.";
int textLen = (int)strlen(text);
@@ -412,15 +374,16 @@ DRAW_OP_TEST_DEFINE(TextBlobOp) {
SkScalar x = SkIntToScalar(xInt);
SkScalar y = SkIntToScalar(yInt);
+ GrTextUtils::Paint paint(&skPaint);
// right now we don't handle textblobs, nor do we handle drawPosText. Since we only intend to
// test the text op with this unit test, that is okay.
sk_sp<GrAtlasTextBlob> blob(GrAtlasTextContext::CreateDrawTextBlob(
context->getTextBlobCache(), context->getAtlasGlyphCache(),
- *context->caps()->shaderCaps(), grPaint, skPaint,
+ *context->caps()->shaderCaps(), paint,
GrAtlasTextContext::kTextBlobOpScalerContextFlags, viewMatrix, gSurfaceProps, text,
static_cast<size_t>(textLen), x, y));
- return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, color, skPaint, gSurfaceProps,
+ return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, paint, gSurfaceProps,
gTextContext->dfAdjustTable(), context->getAtlasGlyphCache());
}
diff --git a/src/gpu/text/GrAtlasTextContext.h b/src/gpu/text/GrAtlasTextContext.h
index 27560d47ce..11e22d3b7a 100644
--- a/src/gpu/text/GrAtlasTextContext.h
+++ b/src/gpu/text/GrAtlasTextContext.h
@@ -11,6 +11,7 @@
#include "GrAtlasTextBlob.h"
#include "GrDistanceFieldAdjustTable.h"
#include "GrGeometryProcessor.h"
+#include "GrTextUtils.h"
#include "SkTextBlobRunIterator.h"
#ifdef GR_TEST_UTILS
@@ -32,10 +33,11 @@ public:
bool canDraw(const SkPaint&, const SkMatrix& viewMatrix, const SkSurfaceProps&,
const GrShaderCaps&);
- void drawText(GrContext*, GrRenderTargetContext*, const GrClip&, GrPaint&&, const SkPaint&,
+
+ void drawText(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&,
const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
size_t byteLength, SkScalar x, SkScalar y, const SkIRect& regionClipBounds);
- void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, GrPaint&&, const SkPaint&,
+ void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&,
const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& regionClipBounds);
@@ -48,13 +50,13 @@ private:
GrAtlasTextContext();
// sets up the descriptor on the blob and returns a detached cache. Client must attach
- inline static GrColor ComputeCanonicalColor(const SkPaint&, bool lcd);
+ inline static SkColor ComputeCanonicalColor(const SkPaint&, bool lcd);
// Determines if we need to use fake gamma (and contrast boost):
inline static uint32_t ComputeScalerContextFlags(GrRenderTargetContext*);
static void RegenerateTextBlob(GrAtlasTextBlob* bmp,
GrAtlasGlyphCache*,
const GrShaderCaps&,
- const SkPaint& skPaint, GrColor,
+ const GrTextUtils::Paint&,
uint32_t scalerContextFlags,
const SkMatrix& viewMatrix,
const SkSurfaceProps&,
@@ -62,10 +64,9 @@ private:
SkDrawFilter* drawFilter);
inline static bool HasLCD(const SkTextBlob*);
- static inline GrAtlasTextBlob* CreateDrawTextBlob(GrTextBlobCache*,
- GrAtlasGlyphCache*, const GrShaderCaps&,
- const GrPaint&,
- const SkPaint&,
+ static inline GrAtlasTextBlob* CreateDrawTextBlob(GrTextBlobCache*, GrAtlasGlyphCache*,
+ const GrShaderCaps&,
+ const GrTextUtils::Paint&,
uint32_t scalerContextFlags,
const SkMatrix& viewMatrix,
const SkSurfaceProps&,
@@ -73,8 +74,7 @@ private:
SkScalar x, SkScalar y);
static inline GrAtlasTextBlob* CreateDrawPosTextBlob(GrTextBlobCache*, GrAtlasGlyphCache*,
const GrShaderCaps&,
- const GrPaint&,
- const SkPaint&,
+ const GrTextUtils::Paint&,
uint32_t scalerContextFlags,
const SkMatrix& viewMatrix,
const SkSurfaceProps&,
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index e5ca7ca2fb..5c3b8b912e 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -8,22 +8,23 @@
#include "GrStencilAndCoverTextContext.h"
#include "GrAtlasTextContext.h"
#include "GrContext.h"
-#include "GrRenderTargetContext.h"
#include "GrPath.h"
#include "GrPathRange.h"
#include "GrPipelineBuilder.h"
+#include "GrRenderTargetContext.h"
#include "GrResourceProvider.h"
+#include "GrSurfaceContextPriv.h"
#include "GrTextUtils.h"
#include "SkAutoKern.h"
#include "SkDraw.h"
+#include "SkDrawFilter.h"
#include "SkDrawProcs.h"
#include "SkGlyphCache.h"
#include "SkGrPriv.h"
-#include "SkDrawFilter.h"
#include "SkPath.h"
#include "SkTextBlobRunIterator.h"
-#include "SkTextMapStateProc.h"
#include "SkTextFormatParams.h"
+#include "SkTextMapStateProc.h"
#include "ops/GrDrawPathOp.h"
@@ -69,25 +70,24 @@ bool GrStencilAndCoverTextContext::internalCanDraw(const SkPaint& skPaint) {
}
void GrStencilAndCoverTextContext::drawText(GrContext* context, GrRenderTargetContext* rtc,
- const GrClip& clip, GrPaint&& paint,
- const SkPaint& skPaint, const SkMatrix& viewMatrix,
- const SkSurfaceProps& props, const char text[],
- size_t byteLength, SkScalar x, SkScalar y,
- const SkIRect& clipBounds) {
+ const GrClip& clip, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix, const SkSurfaceProps& props,
+ const char text[], size_t byteLength, SkScalar x,
+ SkScalar y, const SkIRect& clipBounds) {
if (context->abandoned()) {
return;
} else if (this->canDraw(skPaint, viewMatrix)) {
if (skPaint.getTextSize() > 0) {
TextRun run(skPaint);
run.setText(text, byteLength, x, y);
- run.draw(context, rtc, std::move(paint), clip, viewMatrix, props, 0, 0, clipBounds,
- fFallbackTextContext, skPaint);
+ run.draw(context, rtc, clip, viewMatrix, props, 0, 0, clipBounds, fFallbackTextContext,
+ skPaint);
}
return;
} else if (fFallbackTextContext->canDraw(skPaint, viewMatrix, props,
*context->caps()->shaderCaps())) {
- fFallbackTextContext->drawText(context, rtc, clip, std::move(paint), skPaint, viewMatrix,
- props, text, byteLength, x, y, clipBounds);
+ fFallbackTextContext->drawText(context, rtc, clip, skPaint, viewMatrix, props, text,
+ byteLength, x, y, clipBounds);
return;
}
@@ -97,8 +97,8 @@ void GrStencilAndCoverTextContext::drawText(GrContext* context, GrRenderTargetCo
}
void GrStencilAndCoverTextContext::drawPosText(GrContext* context, GrRenderTargetContext* rtc,
- const GrClip& clip, GrPaint&& paint,
- const SkPaint& skPaint, const SkMatrix& viewMatrix,
+ const GrClip& clip, const SkPaint& skPaint,
+ const SkMatrix& viewMatrix,
const SkSurfaceProps& props, const char text[],
size_t byteLength, const SkScalar pos[],
int scalarsPerPosition, const SkPoint& offset,
@@ -109,15 +109,14 @@ void GrStencilAndCoverTextContext::drawPosText(GrContext* context, GrRenderTarge
if (skPaint.getTextSize() > 0) {
TextRun run(skPaint);
run.setPosText(text, byteLength, pos, scalarsPerPosition, offset);
- run.draw(context, rtc, std::move(paint), clip, viewMatrix, props, 0, 0, clipBounds,
- fFallbackTextContext, skPaint);
+ run.draw(context, rtc, clip, viewMatrix, props, 0, 0, clipBounds, fFallbackTextContext,
+ skPaint);
}
return;
} else if (fFallbackTextContext->canDraw(skPaint, viewMatrix, props,
*context->caps()->shaderCaps())) {
- fFallbackTextContext->drawPosText(context, rtc, clip, std::move(paint), skPaint, viewMatrix,
- props, text, byteLength, pos, scalarsPerPosition, offset,
- clipBounds);
+ fFallbackTextContext->drawPosText(context, rtc, clip, skPaint, viewMatrix, props, text,
+ byteLength, pos, scalarsPerPosition, offset, clipBounds);
return;
}
@@ -136,52 +135,33 @@ void GrStencilAndCoverTextContext::uncachedDrawTextBlob(GrContext* context,
SkScalar x, SkScalar y,
SkDrawFilter* drawFilter,
const SkIRect& clipBounds) {
- SkPaint runPaint = skPaint;
-
+ GrTextUtils::Paint paint(&skPaint);
+ GrTextUtils::RunPaint runPaint(&paint, drawFilter, props);
SkTextBlobRunIterator it(blob);
for (;!it.done(); it.next()) {
- size_t textLen = it.glyphCount() * sizeof(uint16_t);
- const SkPoint& offset = it.offset();
-
- // applyFontToPaint() always overwrites the exact same attributes,
- // so it is safe to not re-seed the paint for this reason.
- it.applyFontToPaint(&runPaint);
-
- if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) {
- // A false return from filter() means we should abort the current draw.
- runPaint = skPaint;
+ if (!runPaint.modifyForRun(it)) {
continue;
}
-
- runPaint.setFlags(GrTextUtils::FilterTextFlags(props, runPaint));
-
- GrPaint grPaint;
- if (!SkPaintToGrPaint(context, rtc, runPaint, viewMatrix, &grPaint)) {
- return;
- }
+ size_t textLen = it.glyphCount() * sizeof(uint16_t);
+ const SkPoint& offset = it.offset();
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning:
- this->drawText(context, rtc, clip, std::move(grPaint), runPaint, viewMatrix, props,
+ this->drawText(context, rtc, clip, runPaint, viewMatrix, props,
(const char*)it.glyphs(), textLen, x + offset.x(), y + offset.y(),
clipBounds);
break;
case SkTextBlob::kHorizontal_Positioning:
- this->drawPosText(context, rtc, clip, std::move(grPaint), runPaint, viewMatrix,
- props, (const char*)it.glyphs(), textLen, it.pos(), 1,
+ this->drawPosText(context, rtc, clip, runPaint, viewMatrix, props,
+ (const char*)it.glyphs(), textLen, it.pos(), 1,
SkPoint::Make(x, y + offset.y()), clipBounds);
break;
case SkTextBlob::kFull_Positioning:
- this->drawPosText(context, rtc, clip, std::move(grPaint), runPaint, viewMatrix,
- props, (const char*)it.glyphs(), textLen, it.pos(), 2,
+ this->drawPosText(context, rtc, clip, runPaint, viewMatrix, props,
+ (const char*)it.glyphs(), textLen, it.pos(), 2,
SkPoint::Make(x, y), clipBounds);
break;
}
-
- if (drawFilter) {
- // A draw filter may change the paint arbitrarily, so we must re-seed in this case.
- runPaint = skPaint;
- }
}
}
@@ -209,18 +189,13 @@ void GrStencilAndCoverTextContext::drawTextBlob(GrContext* context, GrRenderTarg
return;
}
- GrPaint paint;
- if (!SkPaintToGrPaint(context, rtc, skPaint, viewMatrix, &paint)) {
- return;
- }
-
const TextBlob& blob = this->findOrCreateTextBlob(skBlob, skPaint);
TextBlob::Iter iter(blob);
for (TextRun *run = iter.get(), *nextRun; run; run = nextRun) {
nextRun = iter.next();
- run->draw(context, rtc, GrPaint::MoveOrClone(paint, nextRun), clip, viewMatrix, props, x, y,
- clipBounds, fFallbackTextContext, skPaint);
+ run->draw(context, rtc, clip, viewMatrix, props, x, y, clipBounds, fFallbackTextContext,
+ skPaint);
run->releaseGlyphCache();
}
}
@@ -588,11 +563,13 @@ inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl
}
}
-void GrStencilAndCoverTextContext::TextRun::draw(
- GrContext* ctx, GrRenderTargetContext* renderTargetContext, GrPaint&& grPaint,
- const GrClip& clip, const SkMatrix& viewMatrix, const SkSurfaceProps& props, SkScalar x,
- SkScalar y, const SkIRect& clipBounds, GrAtlasTextContext* fallbackTextContext,
- const SkPaint& originalSkPaint) const {
+void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
+ GrRenderTargetContext* renderTargetContext,
+ const GrClip& clip, const SkMatrix& viewMatrix,
+ const SkSurfaceProps& props, SkScalar x,
+ SkScalar y, const SkIRect& clipBounds,
+ GrAtlasTextContext* fallbackTextContext,
+ const SkPaint& originalSkPaint) const {
GrAA runAA = this->isAntiAlias();
SkASSERT(fInstanceData);
SkASSERT(renderTargetContext->isStencilBufferMultisampled() || GrAA::kNo == runAA);
@@ -615,6 +592,13 @@ void GrStencilAndCoverTextContext::TextRun::draw(
fLastDrawnGlyphsID = glyphs->uniqueID();
}
+ GrPaint grPaint;
+ GrContext* context = renderTargetContext->surfPriv().getContext();
+ if (!SkPaintToGrPaint(context, renderTargetContext, originalSkPaint, viewMatrix,
+ &grPaint)) {
+ return;
+ }
+
// Don't compute a bounding box. For dst copy texture, we'll opt instead for it to just copy
// the entire dst. Realistically this is a moot point, because any context that supports
// NV_path_rendering will also support NV_blend_equation_advanced.
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.h b/src/gpu/text/GrStencilAndCoverTextContext.h
index 0597225b0d..a99c264fb7 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.h
+++ b/src/gpu/text/GrStencilAndCoverTextContext.h
@@ -31,10 +31,10 @@ class GrStencilAndCoverTextContext {
public:
static GrStencilAndCoverTextContext* Create(GrAtlasTextContext* fallbackTextContext);
- void drawText(GrContext*, GrRenderTargetContext* rtc, const GrClip&, GrPaint&&, const SkPaint&,
+ void drawText(GrContext*, GrRenderTargetContext* rtc, const GrClip&, const SkPaint&,
const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
size_t byteLength, SkScalar x, SkScalar y, const SkIRect& clipBounds);
- void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, GrPaint&&, const SkPaint&,
+ void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&,
const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& clipBounds);
@@ -75,7 +75,7 @@ private:
void setPosText(const char text[], size_t byteLength, const SkScalar pos[],
int scalarsPerPosition, const SkPoint& offset);
- void draw(GrContext*, GrRenderTargetContext*, GrPaint&&, const GrClip&, const SkMatrix&,
+ void draw(GrContext*, GrRenderTargetContext*, const GrClip&, const SkMatrix&,
const SkSurfaceProps&, SkScalar x, SkScalar y, const SkIRect& clipBounds,
GrAtlasTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const;
diff --git a/src/gpu/text/GrTextUtils.cpp b/src/gpu/text/GrTextUtils.cpp
index 548d4aa27e..a199d8c92d 100644
--- a/src/gpu/text/GrTextUtils.cpp
+++ b/src/gpu/text/GrTextUtils.cpp
@@ -6,20 +6,22 @@
*/
#include "GrTextUtils.h"
-
#include "GrAtlasGlyphCache.h"
#include "GrAtlasTextBlob.h"
#include "GrBlurUtils.h"
#include "GrCaps.h"
#include "GrContext.h"
#include "GrRenderTargetContext.h"
-
+#include "GrSurfaceContextPriv.h"
#include "SkDistanceFieldGen.h"
+#include "SkDrawFilter.h"
#include "SkDrawProcs.h"
#include "SkFindAndPlaceGlyph.h"
#include "SkGlyphCache.h"
+#include "SkGrPriv.h"
#include "SkPaint.h"
#include "SkRect.h"
+#include "SkTextBlobRunIterator.h"
#include "SkTextMapStateProc.h"
#include "SkTextToPathIter.h"
@@ -37,13 +39,43 @@ static const int kLargeDFFontLimit = 2 * kLargeDFFontSize;
#endif
};
-void GrTextUtils::DrawBmpText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache,
- const SkSurfaceProps& props, const SkPaint& skPaint,
- GrColor color, uint32_t scalerContextFlags,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- SkScalar x, SkScalar y) {
+bool GrTextUtils::Paint::toGrPaint(GrMaskFormat maskFormat, GrRenderTargetContext* rtc,
+ const SkMatrix& viewMatrix, GrPaint* grPaint) const {
+ GrContext* context = rtc->surfPriv().getContext();
+ if (kARGB_GrMaskFormat == maskFormat) {
+ return SkPaintToGrPaintWithPrimitiveColor(context, rtc, this->skPaint(), grPaint);
+ } else {
+ return SkPaintToGrPaint(context, rtc, this->skPaint(), viewMatrix, grPaint);
+ }
+}
+
+bool GrTextUtils::RunPaint::modifyForRun(const SkTextBlobRunIterator& run) {
+ if (!fModifiedPaint.isValid()) {
+ fModifiedPaint.init(fOriginalPaint->skPaint());
+ fPaint = fModifiedPaint.get();
+ } else if (fFilter) {
+ // We have to reset before applying the run because the filter could have arbitrary
+ // changed the paint.
+ *fModifiedPaint.get() = fOriginalPaint->skPaint();
+ }
+ run.applyFontToPaint(fModifiedPaint.get());
+
+ if (fFilter) {
+ if (!fFilter->filter(fModifiedPaint.get(), SkDrawFilter::kText_Type)) {
+ // A false return from filter() means we should abort the current draw.
+ return false;
+ }
+ // The draw filter could have changed either the paint color or color filter.
+ this->initFilteredColor();
+ }
+ fModifiedPaint.get()->setFlags(FilterTextFlags(fProps, *fModifiedPaint.get()));
+ return true;
+}
+
+void GrTextUtils::DrawBmpText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache* fontCache,
+ const SkSurfaceProps& props, const GrTextUtils::Paint& paint,
+ uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, SkScalar x, SkScalar y) {
SkASSERT(byteLength == 0 || text != nullptr);
// nothing to draw
@@ -56,32 +88,28 @@ void GrTextUtils::DrawBmpText(GrAtlasTextBlob* blob, int runIndex,
GrAtlasTextStrike* currStrike = nullptr;
- SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags, skPaint,
- &viewMatrix);
+ SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags, paint, &viewMatrix);
SkFindAndPlaceGlyph::ProcessText(
- skPaint.getTextEncoding(), text, byteLength,
- {x, y}, viewMatrix, skPaint.getTextAlign(),
+ paint.skPaint().getTextEncoding(), text, byteLength,
+ {x, y}, viewMatrix, paint.skPaint().getTextAlign(),
cache,
[&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
- position += rounding;
- BmpAppendGlyph(
- blob, runIndex, fontCache, &currStrike, glyph,
- SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY),
- color, cache);
+ position += rounding;
+ BmpAppendGlyph(
+ blob, runIndex, fontCache, &currStrike, glyph,
+ SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY),
+ paint.filteredPremulGrColor(), cache);
}
);
SkGlyphCache::AttachCache(cache);
}
-void GrTextUtils::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache,
- const SkSurfaceProps& props, const SkPaint& skPaint,
- GrColor color, uint32_t scalerContextFlags,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) {
+void GrTextUtils::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache* fontCache,
+ const SkSurfaceProps& props, const GrTextUtils::Paint& paint,
+ uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, const SkScalar pos[],
+ int scalarsPerPosition, const SkPoint& offset) {
SkASSERT(byteLength == 0 || text != nullptr);
SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
@@ -95,19 +123,18 @@ void GrTextUtils::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex,
GrAtlasTextStrike* currStrike = nullptr;
- SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags, skPaint,
- &viewMatrix);
+ SkGlyphCache* cache = blob->setupCache(runIndex, props, scalerContextFlags, paint, &viewMatrix);
SkFindAndPlaceGlyph::ProcessPosText(
- skPaint.getTextEncoding(), text, byteLength,
+ paint.skPaint().getTextEncoding(), text, byteLength,
offset, viewMatrix, pos, scalarsPerPosition,
- skPaint.getTextAlign(), cache,
+ paint.skPaint().getTextAlign(), cache,
[&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
position += rounding;
BmpAppendGlyph(
blob, runIndex, fontCache, &currStrike, glyph,
SkScalarFloorToInt(position.fX), SkScalarFloorToInt(position.fY),
- color, cache);
+ paint.filteredPremulGrColor(), cache);
}
);
@@ -156,7 +183,7 @@ bool GrTextUtils::CanDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix
}
SkScalar maxScale = viewMatrix.getMaxScale();
- SkScalar scaledTextSize = maxScale*skPaint.getTextSize();
+ SkScalar scaledTextSize = maxScale * skPaint.getTextSize();
// Hinted text looks far better at small resolutions
// Scaling up beyond 2x yields undesireable artifacts
if (scaledTextSize < kMinDFFontSize ||
@@ -242,7 +269,7 @@ void GrTextUtils::InitDistanceFieldPaint(GrAtlasTextBlob* blob,
void GrTextUtils::DrawDFText(GrAtlasTextBlob* blob, int runIndex,
GrAtlasGlyphCache* fontCache, const SkSurfaceProps& props,
- const SkPaint& skPaint, GrColor color, uint32_t scalerContextFlags,
+ const GrTextUtils::Paint& paint, uint32_t scalerContextFlags,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
SkScalar x, SkScalar y) {
@@ -253,6 +280,7 @@ void GrTextUtils::DrawDFText(GrAtlasTextBlob* blob, int runIndex,
return;
}
+ const SkPaint& skPaint = paint.skPaint();
SkPaint::GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(skPaint.getTextEncoding(),
skPaint.isDevKernText(),
true);
@@ -311,18 +339,15 @@ void GrTextUtils::DrawDFText(GrAtlasTextBlob* blob, int runIndex,
y -= alignY;
SkPoint offset = SkPoint::Make(x, y);
- DrawDFPosText(blob, runIndex, fontCache, props, skPaint, color, scalerContextFlags, viewMatrix,
- text, byteLength, positions.begin(), 2, offset);
+ DrawDFPosText(blob, runIndex, fontCache, props, paint, scalerContextFlags, viewMatrix, text,
+ byteLength, positions.begin(), 2, offset);
}
-void GrTextUtils::DrawDFPosText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache* fontCache, const SkSurfaceProps& props,
- const SkPaint& origPaint,
- GrColor color, uint32_t scalerContextFlags,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) {
+void GrTextUtils::DrawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache* fontCache,
+ const SkSurfaceProps& props, const GrTextUtils::Paint& paint,
+ uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, const SkScalar pos[],
+ int scalarsPerPosition, const SkPoint& offset) {
SkASSERT(byteLength == 0 || text != nullptr);
SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
@@ -336,10 +361,10 @@ void GrTextUtils::DrawDFPosText(GrAtlasTextBlob* blob, int runIndex,
// Setup distance field paint and text ratio
SkScalar textRatio;
- SkPaint dfPaint(origPaint);
+ SkPaint dfPaint(paint);
GrTextUtils::InitDistanceFieldPaint(blob, &dfPaint, &textRatio, viewMatrix);
blob->setHasDistanceField();
- blob->setSubRunHasDistanceFields(runIndex, origPaint.isLCDRenderText());
+ blob->setSubRunHasDistanceFields(runIndex, paint.skPaint().isLCDRenderText());
GrAtlasTextStrike* currStrike = nullptr;
@@ -363,13 +388,8 @@ void GrTextUtils::DrawDFPosText(GrAtlasTextBlob* blob, int runIndex,
SkScalar x = offset.x() + pos[0];
SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0);
- if (!DfAppendGlyph(blob,
- runIndex,
- fontCache,
- &currStrike,
- glyph,
- x, y, color, cache,
- textRatio, viewMatrix)) {
+ if (!DfAppendGlyph(blob, runIndex, fontCache, &currStrike, glyph, x, y,
+ paint.filteredPremulGrColor(), cache, textRatio, viewMatrix)) {
// couldn't append, send to fallback
fallbackTxt.append(SkToInt(text-lastText), lastText);
*fallbackPos.append() = pos[0];
@@ -395,14 +415,8 @@ void GrTextUtils::DrawDFPosText(GrAtlasTextBlob* blob, int runIndex,
SkScalar advanceX = SkFloatToScalar(glyph.fAdvanceX) * alignMul * textRatio;
SkScalar advanceY = SkFloatToScalar(glyph.fAdvanceY) * alignMul * textRatio;
- if (!DfAppendGlyph(blob,
- runIndex,
- fontCache,
- &currStrike,
- glyph,
- x - advanceX, y - advanceY, color,
- cache,
- textRatio,
+ if (!DfAppendGlyph(blob, runIndex, fontCache, &currStrike, glyph, x - advanceX,
+ y - advanceY, paint.filteredPremulGrColor(), cache, textRatio,
viewMatrix)) {
// couldn't append, send to fallback
fallbackTxt.append(SkToInt(text-lastText), lastText);
@@ -419,9 +433,8 @@ void GrTextUtils::DrawDFPosText(GrAtlasTextBlob* blob, int runIndex,
SkGlyphCache::AttachCache(cache);
if (fallbackTxt.count()) {
blob->initOverride(runIndex);
- GrTextUtils::DrawBmpPosText(blob, runIndex, fontCache, props,
- origPaint, origPaint.getColor(), scalerContextFlags, viewMatrix,
- fallbackTxt.begin(), fallbackTxt.count(),
+ GrTextUtils::DrawBmpPosText(blob, runIndex, fontCache, props, paint, scalerContextFlags,
+ viewMatrix, fallbackTxt.begin(), fallbackTxt.count(),
fallbackPos.begin(), scalarsPerPosition, offset);
}
}
@@ -468,12 +481,11 @@ bool GrTextUtils::DfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyp
return true;
}
-void GrTextUtils::DrawTextAsPath(GrContext* context, GrRenderTargetContext* rtc,
- const GrClip& clip,
- const SkPaint& skPaint, const SkMatrix& viewMatrix,
+void GrTextUtils::DrawTextAsPath(GrContext* context, GrRenderTargetContext* rtc, const GrClip& clip,
+ const SkPaint& paint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, SkScalar x, SkScalar y,
const SkIRect& clipBounds) {
- SkTextToPathIter iter(text, byteLength, skPaint, true);
+ SkTextToPathIter iter(text, byteLength, paint, true);
SkMatrix matrix;
matrix.setScale(iter.getPathScale(), iter.getPathScale());
diff --git a/src/gpu/text/GrTextUtils.h b/src/gpu/text/GrTextUtils.h
index 93a0c1f8f7..c5daa42a15 100644
--- a/src/gpu/text/GrTextUtils.h
+++ b/src/gpu/text/GrTextUtils.h
@@ -9,84 +9,142 @@
#define GrTextUtils_DEFINED
#include "GrColor.h"
+#include "SkColorFilter.h"
+#include "SkGr.h"
#include "SkPaint.h"
#include "SkScalar.h"
+#include "SkTLazy.h"
class GrAtlasGlyphCache;
class GrAtlasTextBlob;
class GrAtlasTextStrike;
class GrClip;
class GrContext;
+class GrPaint;
class GrRenderTargetContext;
class GrShaderCaps;
+class SkDrawFilter;
class SkGlyph;
class SkMatrix;
struct SkIRect;
struct SkPoint;
class SkGlyphCache;
+class SkTextBlobRunIterator;
class SkSurfaceProps;
-/*
+/**
* A class to house a bunch of common text utilities. This class should *ONLY* have static
* functions. It is not a namespace only because we wish to friend SkPaint
- *
*/
class GrTextUtils {
public:
+ /**
+ * This is used to wrap a SkPaint and its post-color filter color. It is also used by RunPaint
+ * (below). This keeps a pointer to the SkPaint it is initialized with and expects it to remain
+ * const. It is also used to transform to GrPaint.
+ */
+ class Paint {
+ public:
+ explicit Paint(const SkPaint* paint) : fPaint(paint) { this->initFilteredColor(); }
+
+ // These expose the paint's color run through its color filter (if any). This is only valid
+ // when drawing grayscale/lcd glyph masks and not when drawing color glyphs.
+ SkColor filteredSkColor() const { return fFilteredSkColor; }
+ GrColor filteredPremulGrColor() const { return fFilteredGrColor; }
+
+ const SkPaint& skPaint() const { return *fPaint; }
+ operator const SkPaint&() const { return this->skPaint(); }
+
+ bool toGrPaint(GrMaskFormat, GrRenderTargetContext*, const SkMatrix& viewMatrix,
+ GrPaint*) const;
+
+ protected:
+ void initFilteredColor() {
+ fFilteredSkColor = fPaint->getColor();
+ if (fPaint->getColorFilter()) {
+ fFilteredSkColor = fPaint->getColorFilter()->filterColor(fFilteredSkColor);
+ }
+ fFilteredGrColor = SkColorToPremulGrColor(fFilteredSkColor);
+ }
+ Paint() = default;
+ const SkPaint* fPaint;
+ // This is the paint's color run through its color filter, if present. This color should
+ // be used except when rendering bitmap text, in which case the bitmap must be filtered in
+ // the fragment shader.
+ SkColor fFilteredSkColor;
+ SkColor fFilteredGrColor;
+ };
+
+ /**
+ * An extension of Paint that incorporated per-run modifications to the paint text settings and
+ * application of a draw filter. It expects its constructor arguments to remain alive and const
+ * during its lifetime.
+ */
+ class RunPaint : public Paint {
+ public:
+ RunPaint(const Paint* paint, SkDrawFilter* filter, const SkSurfaceProps& props)
+ : fOriginalPaint(paint), fFilter(filter), fProps(props) {
+ // Initially we represent the original paint.
+ fPaint = &fOriginalPaint->skPaint();
+ fFilteredSkColor = fOriginalPaint->filteredSkColor();
+ fFilteredGrColor = fOriginalPaint->filteredPremulGrColor();
+ }
+
+ bool modifyForRun(const SkTextBlobRunIterator&);
+
+ private:
+ SkTLazy<SkPaint> fModifiedPaint;
+ const Paint* fOriginalPaint;
+ SkDrawFilter* fFilter;
+ const SkSurfaceProps& fProps;
+ };
+
// Functions for appending BMP text to GrAtlasTextBlob
- static void DrawBmpText(GrAtlasTextBlob*, int runIndex,
- GrAtlasGlyphCache*, const SkSurfaceProps&,
- const SkPaint&,
- GrColor, uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
+ static void DrawBmpText(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
+ const SkSurfaceProps&, const Paint& paint, uint32_t scalerContextFlags,
+ const SkMatrix& viewMatrix, const char text[], size_t byteLength,
SkScalar x, SkScalar y);
- static void DrawBmpPosText(GrAtlasTextBlob*, int runIndex,
- GrAtlasGlyphCache*, const SkSurfaceProps&, const SkPaint&,
- GrColor, uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset);
+ static void DrawBmpPosText(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
+ const SkSurfaceProps&, const Paint& paint,
+ uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, const SkScalar pos[],
+ int scalarsPerPosition, const SkPoint& offset);
// functions for appending distance field text
static bool CanDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix& viewMatrix,
const SkSurfaceProps& props, const GrShaderCaps& caps);
- static void DrawDFText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache*, const SkSurfaceProps&,
- const SkPaint& skPaint, GrColor color, uint32_t scalerContextFlags,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
+ static void DrawDFText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache*,
+ const SkSurfaceProps&, const Paint& paint, uint32_t scalerContextFlags,
+ const SkMatrix& viewMatrix, const char text[], size_t byteLength,
SkScalar x, SkScalar y);
- static void DrawDFPosText(GrAtlasTextBlob* blob, int runIndex,
- GrAtlasGlyphCache*, const SkSurfaceProps&, const SkPaint&,
- GrColor color, uint32_t scalerContextFlags,
- const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset);
+ static void DrawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache*,
+ const SkSurfaceProps&, const Paint& paint,
+ uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, const SkScalar pos[],
+ int scalarsPerPosition, const SkPoint& offset);
// Functions for drawing text as paths
static void DrawTextAsPath(GrContext*, GrRenderTargetContext*, const GrClip& clip,
- const SkPaint& origPaint, const SkMatrix& viewMatrix,
- const char text[], size_t byteLength, SkScalar x, SkScalar y,
+ const SkPaint& paint, const SkMatrix& viewMatrix, const char text[],
+ size_t byteLength, SkScalar x, SkScalar y,
const SkIRect& clipBounds);
- static void DrawPosTextAsPath(GrContext* context,
- GrRenderTargetContext* rtc,
- const SkSurfaceProps& props,
- const GrClip& clip,
- const SkPaint& origPaint, const SkMatrix& viewMatrix,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset, const SkIRect& clipBounds);
+ static void DrawPosTextAsPath(GrContext* context, GrRenderTargetContext* rtc,
+ const SkSurfaceProps& props, const GrClip& clip,
+ const SkPaint& paint, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, const SkScalar pos[],
+ int scalarsPerPosition, const SkPoint& offset,
+ const SkIRect& clipBounds);
static bool ShouldDisableLCD(const SkPaint& paint);
- static uint32_t FilterTextFlags(const SkSurfaceProps& surfaceProps, const SkPaint& paint);
private:
+ static uint32_t FilterTextFlags(const SkSurfaceProps& surfaceProps, const SkPaint& paint);
+
static void InitDistanceFieldPaint(GrAtlasTextBlob* blob,
SkPaint* skPaint,
SkScalar* textRatio,