Filter TextBlob paints in Viewer.

In particular this allows subpixel positioning to be forced for
drawing.

Change-Id: I2c88311f075944fef66fe5ba0237804aa5755800
Reviewed-on: https://skia-review.googlesource.com/156370
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
Ben Wagner 2018-09-24 13:01:54 -04:00 committed by Skia Commit-Bot
parent 9461dcf130
commit 41e404746d
3 changed files with 73 additions and 0 deletions

View File

@ -309,6 +309,7 @@ skia_core_sources = [
"$_src/core/SkTDPQueue.h",
"$_src/core/SkTDynamicHash.h",
"$_src/core/SkTextBlob.cpp",
"$_src/core/SkTextBlobPriv.h",
"$_src/core/SkTextFormatParams.h",
"$_src/core/SkTextToPathIter.h",
"$_src/core/SkTime.cpp",

View File

@ -37,6 +37,11 @@ public:
SkString lang, const SkRect* bounds = nullptr) {
return builder->allocRunText(font, count, x, y, textByteCount, lang, bounds);
}
static const SkTextBlobBuilder::RunBuffer& AllocRunTextPosH(SkTextBlobBuilder* builder,
const SkPaint& font, int count, SkScalar y, int textByteCount, SkString lang,
const SkRect* bounds = nullptr) {
return builder->allocRunTextPosH(font, count, y, textByteCount, lang, bounds);
}
static const SkTextBlobBuilder::RunBuffer& AllocRunTextPos(SkTextBlobBuilder* builder,
const SkPaint& font, int count, int textByteCount, SkString lang,
const SkRect* bounds = nullptr) {

View File

@ -985,6 +985,73 @@ public:
OveridePaintFilterCanvas(SkCanvas* canvas, SkPaint* paint, Viewer::SkPaintFields* fields)
: SkPaintFilterCanvas(canvas), fPaint(paint), fPaintOverrides(fields)
{ }
const SkTextBlob* filterTextBlob(const SkPaint& paint, const SkTextBlob* blob,
sk_sp<SkTextBlob>* cache) {
bool blobWillChange = false;
for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
SkPaint blobPaint = paint;
it.applyFontToPaint(&blobPaint);
SkTCopyOnFirstWrite<SkPaint> filteredPaint(blobPaint);
bool shouldDraw = this->onFilter(&filteredPaint, kTextBlob_Type);
if (blobPaint != *filteredPaint || !shouldDraw) {
blobWillChange = true;
break;
}
}
if (!blobWillChange) {
return blob;
}
SkTextBlobBuilder builder;
for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
SkPaint blobPaint = paint;
it.applyFontToPaint(&blobPaint);
SkTCopyOnFirstWrite<SkPaint> filteredPaint(blobPaint);
bool shouldDraw = this->onFilter(&filteredPaint, kTextBlob_Type);
if (!shouldDraw) {
continue;
}
const SkTextBlobBuilder::RunBuffer& runBuffer
= it.positioning() == SkTextBlobRunIterator::kDefault_Positioning
? SkTextBlobBuilderPriv::AllocRunText(&builder, *filteredPaint,
it.offset().x(),it.offset().y(), it.glyphCount(), it.textSize(), SkString())
: it.positioning() == SkTextBlobRunIterator::kHorizontal_Positioning
? SkTextBlobBuilderPriv::AllocRunTextPosH(&builder, *filteredPaint,
it.offset().y(), it.glyphCount(), it.textSize(), SkString())
: it.positioning() == SkTextBlobRunIterator::kFull_Positioning
? SkTextBlobBuilderPriv::AllocRunTextPos(&builder, *filteredPaint,
it.glyphCount(), it.textSize(), SkString())
: (SkASSERT_RELEASE(false), SkTextBlobBuilder::RunBuffer());
uint32_t glyphCount = it.glyphCount();
if (it.glyphs()) {
size_t glyphSize = sizeof(decltype(*it.glyphs()));
memcpy(runBuffer.glyphs, it.glyphs(), glyphCount * glyphSize);
}
if (it.pos()) {
size_t posSize = sizeof(decltype(*it.pos()));
uint8_t positioning = it.positioning();
memcpy(runBuffer.pos, it.pos(), glyphCount * positioning * posSize);
}
if (it.text()) {
size_t textSize = sizeof(decltype(*it.text()));
uint32_t textCount = it.textSize();
memcpy(runBuffer.utf8text, it.text(), textCount * textSize);
}
if (it.clusters()) {
size_t clusterSize = sizeof(decltype(*it.clusters()));
memcpy(runBuffer.clusters, it.clusters(), glyphCount * clusterSize);
}
}
*cache = builder.make();
return cache->get();
}
void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint& paint) override {
sk_sp<SkTextBlob> cache;
this->SkPaintFilterCanvas::onDrawTextBlob(
this->filterTextBlob(paint, blob, &cache), x, y, paint);
}
bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type) const override {
if (*paint == nullptr) {
return true;