Use layers properly in Slug drawing

When drawing the Slug, aboutToDraw was never called resulting
in strange drawing matrices and broken image filters. Call
aboutToDraw in Slug drawing needs to use the initial paint from
the convert call. Store this in the Slug instead of the paint
resulting from aboutToDraw. Plumb the initialPaint and the
paint from aboutToDraw to where they need to go.

Bug: chromium:1302290
Change-Id: Id921aa37bf8ff2ecd21cdcdaad0012a7b90f5322
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/533759
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2022-04-25 15:19:41 -06:00 committed by SkCQ
parent fd9804f9a3
commit 74666f4b8c
21 changed files with 170 additions and 97 deletions

View File

@ -61,7 +61,11 @@ public:
void draw(SkCanvas* canvas) const;
virtual SkRect sourceBounds() const = 0;
virtual const SkPaint& paint() const = 0;
// The paint passed into ConvertBlob; this paint is used instead of the paint resulting from
// the call to aboutToDraw because when we call draw(), the initial paint is needed to call
// aboutToDraw again to get the layer right.
virtual const SkPaint& initialPaint() const = 0;
virtual void doFlatten(SkWriteBuffer&) const = 0;

View File

@ -523,9 +523,10 @@ void SkBitmapDevice::drawImageRect(const SkImage* image, const SkRect* src, cons
void SkBitmapDevice::onDrawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
SkASSERT(!glyphRunList.hasRSXForm());
LOOP_TILER( drawGlyphRunList(canvas, &fGlyphPainter, glyphRunList, paint), nullptr )
LOOP_TILER( drawGlyphRunList(canvas, &fGlyphPainter, glyphRunList, drawingPaint), nullptr )
}
void SkBitmapDevice::drawVertices(const SkVertices* vertices,

View File

@ -107,7 +107,10 @@ protected:
///////////////////////////////////////////////////////////////////////////
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
bool onReadPixels(const SkPixmap&, int x, int y) override;
bool onWritePixels(const SkPixmap&, int, int) override;
bool onPeekPixels(SkPixmap*) override;

View File

@ -2338,7 +2338,7 @@ void SkCanvas::onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPa
}
auto layer = this->aboutToDraw(this, paint, &bounds);
if (layer) {
this->topDevice()->drawGlyphRunList(this, glyphRunList, layer->paint());
this->topDevice()->drawGlyphRunList(this, glyphRunList, paint, layer->paint());
}
}
@ -2358,7 +2358,7 @@ SkCanvas::onConvertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList, const
}
auto layer = this->aboutToDraw(this, paint, &bounds);
if (layer) {
return this->topDevice()->convertGlyphRunListToSlug(glyphRunList, layer->paint());
return this->topDevice()->convertGlyphRunListToSlug(glyphRunList, paint, layer->paint());
}
return nullptr;
}
@ -2372,11 +2372,14 @@ void SkCanvas::drawSlug(const GrSlug* slug) {
void SkCanvas::onDrawSlug(const GrSlug* slug) {
SkRect bounds = slug->sourceBounds();
if (this->internalQuickReject(bounds, slug->paint())) {
if (this->internalQuickReject(bounds, slug->initialPaint())) {
return;
}
this->topDevice()->drawSlug(this, slug);
auto layer = this->aboutToDraw(this, slug->initialPaint(), &bounds);
if (layer) {
this->topDevice()->drawSlug(this, slug, layer->paint());
}
}
#endif

View File

@ -814,7 +814,8 @@ protected:
#if SK_SUPPORT_GPU
void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override {
GrContextOptions ctxOptions;
GrSDFTControl control =
GrSDFTControl{fDFTSupport,
@ -829,7 +830,7 @@ protected:
fPainter.processGlyphRun(nullptr,
glyphRun,
drawMatrix,
paint,
drawingPaint,
control,
"Cache Diff",
uniqueID);
@ -837,7 +838,8 @@ protected:
}
sk_sp<GrSlug> convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override {
GrContextOptions ctxOptions;
GrSDFTControl control =
GrSDFTControl{fDFTSupport,
@ -858,14 +860,18 @@ protected:
fPainter.processGlyphRun(nullptr,
glyphRun,
positionMatrix,
paint,
drawingPaint,
control,
"Convert Slug Analysis");
}
// Use the glyph strike cache to get actual glyph information.
return skgpu::v1::MakeSlug(
this->localToDevice(), glyphRunList, paint, control, &fConvertPainter);
return skgpu::v1::MakeSlug(this->localToDevice(),
glyphRunList,
initialPaint,
drawingPaint,
control,
&fConvertPainter);
}
#endif // SK_SUPPORT_GPU

View File

@ -428,25 +428,27 @@ static sk_sp<SkShader> make_post_inverse_lm(const SkShader* shader, const SkMatr
void SkBaseDevice::drawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
if (!this->localToDevice().isFinite()) {
return;
}
if (!glyphRunList.hasRSXForm()) {
this->onDrawGlyphRunList(canvas, glyphRunList, paint);
this->onDrawGlyphRunList(canvas, glyphRunList, initialPaint, drawingPaint);
} else {
this->simplifyGlyphRunRSXFormAndRedraw(canvas, glyphRunList, paint);
this->simplifyGlyphRunRSXFormAndRedraw(canvas, glyphRunList, initialPaint, drawingPaint);
}
}
void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
for (const SkGlyphRun& run : glyphRunList) {
if (run.scaledRotations().empty()) {
SkGlyphRunList subList{run, run.sourceBounds(paint), {0, 0}};
this->drawGlyphRunList(canvas, subList, paint);
SkGlyphRunList subList{run, run.sourceBounds(drawingPaint), {0, 0}};
this->drawGlyphRunList(canvas, subList, initialPaint, drawingPaint);
} else {
SkPoint origin = glyphRunList.origin();
SkPoint sharedPos{0, 0}; // we're at the origin
@ -471,12 +473,13 @@ void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
// (i.e. the shader that cares about the ctm) so we have to undo our little ctm
// trick with a localmatrixshader so that the shader draws as if there was no
// change to the ctm.
SkPaint invertingPaint{paint};
invertingPaint.setShader(make_post_inverse_lm(paint.getShader(), glyphToLocal));
SkPaint invertingPaint{drawingPaint};
invertingPaint.setShader(
make_post_inverse_lm(drawingPaint.getShader(), glyphToLocal));
SkAutoCanvasRestore acr(canvas, true);
canvas->concat(SkM44(glyphToLocal));
SkGlyphRunList subList{glyphRun, glyphRun.sourceBounds(paint), {0, 0}};
this->drawGlyphRunList(canvas, subList, invertingPaint);
SkGlyphRunList subList{glyphRun, glyphRun.sourceBounds(drawingPaint), {0, 0}};
this->drawGlyphRunList(canvas, subList, initialPaint, invertingPaint);
}
}
}
@ -485,11 +488,12 @@ void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
#if SK_SUPPORT_GPU
sk_sp<GrSlug> SkBaseDevice::convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
return nullptr;
}
void SkBaseDevice::drawSlug(SkCanvas*, const GrSlug*) {
void SkBaseDevice::drawSlug(SkCanvas*, const GrSlug*, const SkPaint&) {
SK_ABORT("GrSlug drawing not supported.");
}
#endif

View File

@ -199,7 +199,10 @@ public:
virtual skgpu::graphite::Device* asGraphiteDevice() { return nullptr; }
// Ensure that non-RSXForm runs are passed to onDrawGlyphRunList.
void drawGlyphRunList(SkCanvas*, const SkGlyphRunList& glyphRunList, const SkPaint& paint);
void drawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList,
const SkPaint& initialPaint,
const SkPaint& drawingPaint);
protected:
enum TileUsage {
@ -311,14 +314,18 @@ protected:
virtual void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*);
// Only called with glyphRunLists that do not contain RSXForm.
virtual void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) = 0;
virtual void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) = 0;
// GrSlug handling routines.
#if SK_SUPPORT_GPU
virtual sk_sp<GrSlug> convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList,
const SkPaint& paint);
virtual void drawSlug(SkCanvas*, const GrSlug* slug);
const SkPaint& initialPaint,
const SkPaint& drawingPaint);
virtual void drawSlug(SkCanvas*, const GrSlug* slug, const SkPaint& drawingPaint);
#endif
/**
@ -436,7 +443,10 @@ private:
friend class SkSurface_Raster;
friend class DeviceTestingAccess;
void simplifyGlyphRunRSXFormAndRedraw(SkCanvas*, const SkGlyphRunList&, const SkPaint&);
void simplifyGlyphRunRSXFormAndRedraw(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint);
// used to change the backend's pixels (and possibly config/rowbytes)
// but cannot change the width/height, so there should be no change to
@ -548,8 +558,8 @@ protected:
void drawFilteredImage(const skif::Mapping&, SkSpecialImage* src, const SkImageFilter*,
const SkSamplingOptions&, const SkPaint&) override {}
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override {}
void onDrawGlyphRunList(
SkCanvas*, const SkGlyphRunList&, const SkPaint&, const SkPaint&) override {}
bool isNoPixelsDevice() const override { return true; }

View File

@ -62,10 +62,12 @@ public:
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
const SkSamplingOptions&, const SkPaint&) const override {}
void onDrawGlyphRunList(SkCanvas* canvas, const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override {
void onDrawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override {
SkASSERT(!glyphRunList.hasRSXForm());
fPainter.drawForBitmapDevice(canvas, this, glyphRunList, paint,
fPainter.drawForBitmapDevice(canvas, this, glyphRunList, drawingPaint,
fOverdrawCanvas->getTotalMatrix());
}
@ -83,12 +85,13 @@ void SkOverdrawCanvas::onDrawTextBlob(
}
void SkOverdrawCanvas::onDrawGlyphRunList(
const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
SkSurfaceProps props{0, kUnknown_SkPixelGeometry};
this->getProps(&props);
TextDevice device{this, props};
device.drawGlyphRunList(this, glyphRunList, paint);
device.drawGlyphRunList(this, glyphRunList, paint, paint);
}
void SkOverdrawCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],

View File

@ -479,7 +479,7 @@ private:
#if SK_SUPPORT_GPU
Bounds bounds(const DrawSlug& op) const {
SkRect dst = op.slug->sourceBounds();
return this->adjustAndMap(dst, &op.slug->paint());
return this->adjustAndMap(dst, &op.slug->initialPaint());
}
#else
Bounds bounds(const DrawSlug& op) const {

View File

@ -2211,7 +2211,8 @@ public:
static sk_sp<Slug> Make(const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint,
const SkPaint& initialPaint,
const SkPaint& drawingPaint,
const GrSDFTControl& control,
SkGlyphRunListPainter* painter);
static sk_sp<GrSlug> MakeFromBuffer(SkReadBuffer& buffer,
@ -2220,11 +2221,12 @@ public:
void surfaceDraw(SkCanvas*,
const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkPaint& paint,
skgpu::v1::SurfaceDrawContext* sdc) const;
void doFlatten(SkWriteBuffer& buffer) const override;
SkRect sourceBounds() const override { return fSourceBounds; }
const SkPaint& paint() const override { return fPaint; }
const SkPaint& initialPaint() const override { return fInitialPaint; }
// SkGlyphRunPainterInterface
void processDeviceMasks(
@ -2268,33 +2270,33 @@ private:
// structure may have pointers into it.
GrSubRunAllocator fAlloc;
const SkRect fSourceBounds;
const SkPaint fPaint;
const SkPaint fInitialPaint;
const SkMatrix fInitialPositionMatrix;
const SkPoint fOrigin;
GrSubRunList fSubRuns;
};
Slug::Slug(SkRect sourceBounds,
const SkPaint& paint,
const SkPaint& initialPaint,
const SkMatrix& positionMatrix,
SkPoint origin,
int allocSize)
: fAlloc {SkTAddOffset<char>(this, sizeof(Slug)), allocSize, allocSize/2}
, fSourceBounds{sourceBounds}
, fPaint{paint}
, fInitialPaint{initialPaint}
, fInitialPositionMatrix{positionMatrix}
, fOrigin{origin} { }
void Slug::surfaceDraw(SkCanvas* canvas, const GrClip* clip, const SkMatrixProvider& viewMatrix,
skgpu::v1::SurfaceDrawContext* sdc) const {
const SkPaint& drawingPaint, skgpu::v1::SurfaceDrawContext* sdc) const {
for (const GrSubRun& subRun : fSubRuns) {
subRun.draw(canvas, clip, viewMatrix, fOrigin, fPaint, sdc);
subRun.draw(canvas, clip, viewMatrix, fOrigin, drawingPaint, sdc);
}
}
void Slug::doFlatten(SkWriteBuffer& buffer) const {
buffer.writeRect(fSourceBounds);
SkPaintPriv::Flatten(fPaint, buffer);
SkPaintPriv::Flatten(fInitialPaint, buffer);
buffer.writeMatrix(fInitialPositionMatrix);
buffer.writePoint(fOrigin);
auto [subRunCount, subRunsUnflattenSizeHint] = this->subRunCountAndUnflattenSizeHint();
@ -2772,7 +2774,8 @@ void Slug::processDeviceMasks(
sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint,
const SkPaint& initialPaint,
const SkPaint& drawingPaint,
const GrSDFTControl& control,
SkGlyphRunListPainter* painter) {
// The difference in alignment from the per-glyph data to the SubRun;
@ -2795,7 +2798,7 @@ sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
sk_sp<Slug> slug{new (::operator new (allocationSize))
Slug(glyphRunList.sourceBounds(),
paint,
initialPaint,
positionMatrix,
glyphRunList.origin(),
bytesNeededForSubRun)};
@ -2805,7 +2808,7 @@ sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
painter->processGlyphRun(slug.get(),
glyphRun,
positionMatrix,
paint,
drawingPaint,
control,
"Make Slug",
uniqueID);
@ -2867,19 +2870,22 @@ void Slug::processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& accepted,
namespace skgpu::v1 {
sk_sp<GrSlug>
Device::convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
Device::convertGlyphRunListToSlug(const SkGlyphRunList& glyphRunList,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
auto recordingContextPriv = this->recordingContext()->priv();
const GrSDFTControl control = recordingContextPriv.getSDFTControl(
this->surfaceProps().isUseDeviceIndependentFonts());
return Slug::Make(this->asMatrixProvider(),
glyphRunList,
paint,
initialPaint,
drawingPaint,
control,
fSurfaceDrawContext->glyphRunPainter());
}
void Device::drawSlug(SkCanvas* canvas, const GrSlug* grSlug) {
void Device::drawSlug(SkCanvas* canvas, const GrSlug* grSlug, const SkPaint& drawingPaint) {
const Slug* slug = static_cast<const Slug*>(grSlug);
auto matrixProvider = this->asMatrixProvider();
#if defined(SK_DEBUG)
@ -2893,15 +2899,17 @@ void Device::drawSlug(SkCanvas* canvas, const GrSlug* grSlug) {
SkASSERT(slugMatrix == positionMatrix);
}
#endif
slug->surfaceDraw(canvas, this->clip(), matrixProvider, fSurfaceDrawContext.get());
slug->surfaceDraw(
canvas, this->clip(), matrixProvider, drawingPaint, fSurfaceDrawContext.get());
}
sk_sp<GrSlug> MakeSlug(const SkMatrixProvider& drawMatrix,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint,
const SkPaint& initialPaint,
const SkPaint& drawingPaint,
const GrSDFTControl& control,
SkGlyphRunListPainter* painter) {
return Slug::Make(drawMatrix, glyphRunList, paint, control, painter);
return Slug::Make(drawMatrix, glyphRunList, initialPaint, drawingPaint, control, painter);
}
} // namespace skgpu::v1

View File

@ -298,7 +298,8 @@ private:
namespace skgpu::v1 {
sk_sp<GrSlug> MakeSlug(const SkMatrixProvider& drawMatrix,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint,
const SkPaint& initialPaint,
const SkPaint& drawingPaint,
const GrSDFTControl& control,
SkGlyphRunListPainter* painter);
} // namespace skgpu::v1

View File

@ -960,10 +960,11 @@ void Device::drawAtlas(const SkRSXform xform[],
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG)
void Device::testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
auto slug = this->convertGlyphRunListToSlug(glyphRunList, paint);
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
auto slug = this->convertGlyphRunListToSlug(glyphRunList, initialPaint, drawingPaint);
if (slug != nullptr) {
this->drawSlug(canvas, slug.get());
this->drawSlug(canvas, slug.get(), drawingPaint);
}
}
#endif
@ -971,16 +972,18 @@ void Device::testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas,
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE)
void Device::testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
// This is not a text blob draw. Handle using glyphRunList conversion.
if (glyphRunList.blob() == nullptr) {
auto slug = this->convertGlyphRunListToSlug(glyphRunList, paint);
auto slug = this->convertGlyphRunListToSlug(glyphRunList, initialPaint, drawingPaint);
if (slug != nullptr) {
this->drawSlug(canvas, slug.get());
this->drawSlug(canvas, slug.get(), drawingPaint);
}
return;
}
auto srcSlug = GrSlug::ConvertBlob(canvas, *glyphRunList.blob(), glyphRunList.origin(), paint);
auto srcSlug = GrSlug::ConvertBlob(
canvas, *glyphRunList.blob(), glyphRunList.origin(), initialPaint);
// There is nothing to draw.
if (srcSlug == nullptr) {
@ -992,7 +995,7 @@ void Device::testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas,
auto dstSlug = GrSlug::Deserialize(dstSlugData->data(), dstSlugData->size());
SkASSERT(dstSlug != nullptr);
if (dstSlug != nullptr) {
this->drawSlug(canvas, dstSlug.get());
this->drawSlug(canvas, dstSlug.get(), drawingPaint);
}
}
#endif
@ -1052,10 +1055,15 @@ private:
} // namespace
void Device::testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
SkCanvas* canvas, const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
if (glyphRunList.blob() == nullptr) {
fSurfaceDrawContext->drawGlyphRunList(
canvas, this->clip(), this->asMatrixProvider(), glyphRunList, paint);
auto slug = this->convertGlyphRunListToSlug(glyphRunList, initialPaint, drawingPaint);
if (slug != nullptr) {
this->drawSlug(canvas, slug.get(), drawingPaint);
}
return;
}
@ -1080,7 +1088,7 @@ void Device::testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
auto srcSlug = GrSlug::ConvertBlob(analysisCanvas.get(),
*glyphRunList.blob(),
glyphRunList.origin(),
paint);
initialPaint);
if (srcSlug == nullptr) {
return;
@ -1095,34 +1103,37 @@ void Device::testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
auto dstSlugData = srcSlug->serialize();
auto dstSlug = client.deserializeSlug(dstSlugData->data(), dstSlugData->size());
this->drawSlug(canvas, dstSlug.get());
this->drawSlug(canvas, dstSlug.get(), drawingPaint);
}
#endif
void Device::onDrawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v1::Device", "drawGlyphRunList", fContext.get());
SkASSERT(!glyphRunList.hasRSXForm());
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG)
this->testingOnly_drawGlyphRunListWithSlug(canvas, glyphRunList, paint);
this->testingOnly_drawGlyphRunListWithSlug(canvas, glyphRunList, initialPaint, drawingPaint);
#elif defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE)
this->testingOnly_drawGlyphRunListWithSerializedSlug(canvas, glyphRunList, paint);
this->testingOnly_drawGlyphRunListWithSerializedSlug(
canvas, glyphRunList, initialPaint, drawingPaint);
#elif defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_STRIKE_SERIALIZE)
this->testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(canvas, glyphRunList, paint);
this->testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
canvas, glyphRunList, initialPaint, drawingPaint);
#else
if (glyphRunList.blob() == nullptr) {
// If the glyphRunList does not have an associated text blob, then it was created by one of
// the direct draw APIs (drawGlyphs, etc.). Use a Slug to draw the glyphs.
auto slug = this->convertGlyphRunListToSlug(glyphRunList, paint);
auto slug = this->convertGlyphRunListToSlug(glyphRunList, initialPaint, drawingPaint);
if (slug != nullptr) {
this->drawSlug(canvas, slug.get());
this->drawSlug(canvas, slug.get(), drawingPaint);
}
} else {
fSurfaceDrawContext->drawGlyphRunList(
canvas, this->clip(), this->asMatrixProvider(), glyphRunList, paint);
canvas, this->clip(), this->asMatrixProvider(), glyphRunList, drawingPaint);
}
#endif
}

View File

@ -155,13 +155,17 @@ protected:
void onSave() override { fClip.save(); }
void onRestore() override { fClip.restore(); }
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
sk_sp<GrSlug> convertGlyphRunListToSlug(
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) override;
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
void drawSlug(SkCanvas*, const GrSlug* slug) override;
void drawSlug(SkCanvas*, const GrSlug* slug, const SkPaint& drawingPaint) override;
void onClipRect(const SkRect& rect, SkClipOp op, bool aa) override {
SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);
@ -213,19 +217,22 @@ private:
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG)
void testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint);
const SkPaint& initialPaint,
const SkPaint& drawingPaint);
#endif
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE)
void testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint);
const SkPaint& initialPaint,
const SkPaint& drawingPaint);
#endif
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_STRIKE_SERIALIZE)
void testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint);
const SkPaint& initialPaint,
const SkPaint& drawingPaint);
#endif
// If not null, dstClip must be contained inside dst and will also respect the edge AA flags.

View File

@ -129,7 +129,8 @@ private:
void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override {}
void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override {}
void drawShadow(const SkPath&, const SkDrawShadowRec&) override {}
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override {}
void onDrawGlyphRunList(
SkCanvas*, const SkGlyphRunList&, const SkPaint&, const SkPaint&) override {}
void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override {}
void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice,

View File

@ -958,10 +958,11 @@ void SkPDFDevice::internalDrawGlyphRun(
void SkPDFDevice::onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
SkASSERT(!glyphRunList.hasRSXForm());
for (const SkGlyphRun& glyphRun : glyphRunList) {
this->internalDrawGlyphRun(glyphRun, glyphRunList.origin(), paint);
this->internalDrawGlyphRun(glyphRun, glyphRunList.origin(), drawingPaint);
}
}

View File

@ -84,7 +84,10 @@ public:
const SkSamplingOptions&,
const SkPaint&,
SkCanvas::SrcRectConstraint) override;
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override;
void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;

View File

@ -1106,10 +1106,11 @@ private:
void SkSVGDevice::onDrawGlyphRunList(SkCanvas* canvas,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initialPaint,
const SkPaint& drawingPaint) {
SkASSERT(!glyphRunList.hasRSXForm());
const auto draw_as_path = (fFlags & SkSVGCanvas::kConvertTextToPaths_Flag) ||
paint.getPathEffect();
drawingPaint.getPathEffect();
if (draw_as_path) {
// Emit a single <path> element.
@ -1118,14 +1119,14 @@ void SkSVGDevice::onDrawGlyphRunList(SkCanvas* canvas,
AddPath(glyphRun, glyphRunList.origin(), &path);
}
this->drawPath(path, paint);
this->drawPath(path, drawingPaint);
return;
}
// Emit one <text> element for each run.
for (auto& glyphRun : glyphRunList) {
AutoElement elem("text", this, fResourceBucket.get(), MxCp(this), paint);
AutoElement elem("text", this, fResourceBucket.get(), MxCp(this), drawingPaint);
elem.addTextAttributes(glyphRun.font());
SVGTextBuilder builder(glyphRunList.origin(), glyphRun);

View File

@ -57,7 +57,10 @@ protected:
const SkPaint& paint,
bool pathIsMutable = false) override;
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
void onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList&,
const SkPaint& initialPaint,
const SkPaint& drawingPaint) override;
void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override;
#ifdef SK_ENABLE_SKSL
void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;

View File

@ -284,7 +284,8 @@ void SkNWayCanvas::onDrawAtlas2(const SkImage* image, const SkRSXform xform[], c
}
}
void SkNWayCanvas::onDrawGlyphRunList(const SkGlyphRunList& list, const SkPaint &paint) {
void SkNWayCanvas::onDrawGlyphRunList(const SkGlyphRunList& list,
const SkPaint &paint) {
Iter iter(fList);
while (iter.next()) {
iter->onDrawGlyphRunList(list, paint);

View File

@ -1898,7 +1898,8 @@ static bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) {
void SkXPSDevice::onDrawGlyphRunList(SkCanvas*,
const SkGlyphRunList& glyphRunList,
const SkPaint& paint) {
const SkPaint& initailPaint,
const SkPaint& drawingPaint) {
SkASSERT(!glyphRunList.hasRSXForm());
for (const auto& run : glyphRunList) {
@ -1912,7 +1913,7 @@ void SkXPSDevice::onDrawGlyphRunList(SkCanvas*,
TypefaceUse* typeface;
if (FAILED(CreateTypefaceUse(font, &typeface)) ||
text_must_be_pathed(paint, this->localToDevice())) {
text_must_be_pathed(drawingPaint, this->localToDevice())) {
SkPath path;
//TODO: make this work, Draw currently does not handle as well.
//paint.getTextPath(text, byteLength, x, y, &path);
@ -1961,7 +1962,7 @@ void SkXPSDevice::onDrawGlyphRunList(SkCanvas*,
SkScalarToFLOAT(font.getSize()),
XPS_STYLE_SIMULATION_NONE,
this->localToDevice(),
paint));
drawingPaint));
}
}

View File

@ -92,7 +92,8 @@ protected:
const SkRect* srcOrNull, const SkRect& dst,
const SkSamplingOptions&, const SkPaint& paint,
SkCanvas::SrcRectConstraint) override;
void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
void onDrawGlyphRunList(
SkCanvas*, const SkGlyphRunList&, const SkPaint&, const SkPaint&) override;
void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override;
void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;
void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override;