Device interface uses glyph run list

Have devices just treat all runs as drawPosText except
for SkGPUDevice and SkRemoteGlyphCache. Those two
just pass the blob to the old code. This way the
change over from blobs to run lists can happen in smaller
steps.

Change-Id: I3407bffeafe7fbd1c369f6b3c3db8d64b4b6c3b1
Reviewed-on: https://skia-review.googlesource.com/141300
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2018-07-13 13:26:29 -04:00 committed by Skia Commit-Bot
parent b965fcb472
commit b983e6baa1
11 changed files with 74 additions and 22 deletions

View File

@ -2432,7 +2432,7 @@ void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkSca
fScratchGlyphRunBuilder->drawText(
looper.paint(), text, byteLength, SkPoint::Make(x, y));
auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList();
iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList);
iter.fDevice->drawGlyphRunList(glyphRunList);
}
LOOPER_END
@ -2446,7 +2446,7 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint
while (iter.next()) {
fScratchGlyphRunBuilder->drawPosText(looper.paint(), text, byteLength, pos);
auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList();
iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList);
iter.fDevice->drawGlyphRunList(glyphRunList);
}
LOOPER_END
@ -2461,7 +2461,7 @@ void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScala
fScratchGlyphRunBuilder->drawPosTextH(
looper.paint(), text, byteLength, xpos, constY);
auto glyphRunList = fScratchGlyphRunBuilder->useGlyphRunList();
iter.fDevice->drawGlyphRunList(looper.paint(), glyphRunList);
iter.fDevice->drawGlyphRunList(glyphRunList);
}
LOOPER_END
@ -2511,7 +2511,8 @@ void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
LOOPER_BEGIN(paint, bounds)
while (iter.next()) {
iter.fDevice->drawTextBlob(blob, x, y, looper.paint());
fScratchGlyphRunBuilder->drawTextBlob(looper.paint(), *blob, SkPoint::Make(x, y));
iter.fDevice->drawGlyphRunList(fScratchGlyphRunBuilder->useGlyphRunList());
}
LOOPER_END

View File

@ -158,7 +158,7 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
SkGlyphRunBuilder builder;
builder.drawText(runPaint, (const char*) it.glyphs(), textLen, origin);
auto glyphRunList = builder.useGlyphRunList();
glyphRunList->temporaryShuntToDrawPosText(this);
glyphRunList->temporaryShuntToDrawPosText(this, SkPoint::Make(0, 0));
}
break;
case SkTextBlob::kHorizontal_Positioning:
@ -239,8 +239,16 @@ void SkBaseDevice::drawImageLattice(const SkImage* image,
}
}
void SkBaseDevice::drawGlyphRunList(const SkPaint& paint, SkGlyphRunList* glyphRunList) {
glyphRunList->temporaryShuntToDrawPosText(this);
void SkBaseDevice::drawGlyphRunList(SkGlyphRunList* glyphRunList) {
auto blob = glyphRunList->blob();
if (blob == nullptr) {
glyphRunList->temporaryShuntToDrawPosText(this, SkPoint::Make(0, 0));
} else {
auto origin = glyphRunList->origin();
auto paint = glyphRunList->paint();
this->drawTextBlob(blob, origin.x(), origin.y(), paint);
}
}
void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,

View File

@ -218,17 +218,12 @@ protected:
virtual void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
const SkRect& dst, const SkPaint&);
/**
* Does not handle text decoration.
* Decorations (underline and stike-thru) will be handled by SkCanvas.
*/
virtual void drawGlyphRunList(const SkPaint& paint, SkGlyphRunList* glyphRunList);
virtual void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
const SkPaint&) = 0;
virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
// default implementation unrolls the blob runs.
virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint& paint);
virtual void drawGlyphRunList(SkGlyphRunList* glyphRunList);
// default implementation calls drawVertices
virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
@ -346,10 +341,16 @@ private:
// Temporarily friend the SkGlyphRunBuilder until drawPosText is gone.
friend class SkGlyphRun;
friend class SkGlyphRunList;
virtual void drawPosText(const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) = 0;
// Does not handle text decoration.
// Decorations (underline and stike-thru) will be handled by SkCanvas.
// default implementation unrolls the blob runs.
virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint& paint);
// used to change the backend's pixels (and possibly config/rowbytes)
// but cannot change the width/height, so there should be no change to
// any clip information.

View File

@ -51,10 +51,9 @@ SkGlyphRun::SkGlyphRun(SkPaint&& runPaint,
, fClusters{clusters}
, fRunPaint{std::move(runPaint)} {}
void SkGlyphRun::temporaryShuntToDrawPosText(SkBaseDevice* device) {
void SkGlyphRun::temporaryShuntToDrawPosText(SkBaseDevice* device, SkPoint origin) {
auto pos = (const SkScalar*) this->positions().data();
auto origin = SkPoint::Make(0, 0);
if (!fTemporaryShuntGlyphIDs.empty()) {
device->drawPosText(
@ -442,7 +441,7 @@ size_t SkGlyphRunBuilder::simplifyDrawPosText(
uniqueGlyphIDs,
text,
clusters);
return 0;
return uniqueGlyphIDs.size();
}

View File

@ -56,7 +56,7 @@ public:
// The temporaryShunt calls are to allow inter-operating with existing code while glyph runs
// are developed.
void temporaryShuntToDrawPosText(SkBaseDevice* device);
void temporaryShuntToDrawPosText(SkBaseDevice* device, SkPoint origin);
using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>;
void temporaryShuntToCallback(TemporaryShuntCallback callback);
@ -114,15 +114,16 @@ public:
SkPoint origin() const { return fOrigin; }
const SkPaint& paint() const { return *fOriginalPaint; }
const SkTextBlob* blob() const { return fOriginalTextBlob; }
auto begin() -> decltype(fGlyphRuns.begin()) { return fGlyphRuns.begin(); }
auto end() -> decltype(fGlyphRuns.end()) { return fGlyphRuns.end(); }
auto size() -> decltype(fGlyphRuns.size()) { return fGlyphRuns.size(); }
auto empty() -> decltype(fGlyphRuns.empty()) { return fGlyphRuns.empty(); }
auto operator [] (size_t i) -> decltype(fGlyphRuns[i]) { return fGlyphRuns[i]; }
void temporaryShuntToDrawPosText(SkBaseDevice* device) {
void temporaryShuntToDrawPosText(SkBaseDevice* device, SkPoint origin) {
for (auto& run : fGlyphRuns) {
run.temporaryShuntToDrawPosText(device);
run.temporaryShuntToDrawPosText(device, origin);
}
}

View File

@ -256,6 +256,19 @@ protected:
}
}
void drawGlyphRunList(SkGlyphRunList* glyphRunList) override {
auto blob = glyphRunList->blob();
SkASSERT(blob != nullptr);
if (blob != nullptr) {
auto origin = glyphRunList->origin();
auto paint = glyphRunList->paint();
this->drawTextBlob(blob, origin.x(), origin.y(), paint);
}
}
private:
void processGlyphRun(const SkPoint& position,
const SkTextBlobRunIterator& it,

View File

@ -129,8 +129,7 @@ protected:
return 0;
}
int onCountGlyphs() const override {
SK_ABORT("Should never be called.");
return 0;
return this->glyphCount();
}
void* onGetCTFontRef() const override {

View File

@ -1647,6 +1647,22 @@ void SkGpuDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
this->devClipBounds());
}
void SkGpuDevice::drawGlyphRunList(SkGlyphRunList* glyphRunList) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawGlyphRunList", fContext.get());
SkDEBUGCODE(this->validate();)
auto blob = glyphRunList->blob();
if (blob == nullptr) {
glyphRunList->temporaryShuntToDrawPosText(this, SkPoint::Make(0, 0));
} else {
auto origin = glyphRunList->origin();
auto paint = glyphRunList->paint();
this->drawTextBlob(blob, origin.x(), origin.y(), paint);
}
}
///////////////////////////////////////////////////////////////////////////////
void SkGpuDevice::flush() {

View File

@ -90,6 +90,7 @@ public:
void drawPosText(const void* text, size_t len, const SkScalar pos[],
int scalarsPerPos, const SkPoint& offset, const SkPaint&) override;
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint& paint) override;
void drawGlyphRunList(SkGlyphRunList* glyphRunList) override;
void drawVertices(const SkVertices*, const SkMatrix bones[], int boneCount, SkBlendMode,
const SkPaint&) override;
void drawShadow(const SkPath&, const SkDrawShadowRec&) override;

View File

@ -1457,6 +1457,18 @@ void SkPDFDevice::drawPosText(const void* text, size_t len,
offset, paint, nullptr, 0, nullptr);
}
void SkPDFDevice::drawGlyphRunList(SkGlyphRunList* glyphRunList) {
auto blob = glyphRunList->blob();
if (blob == nullptr) {
glyphRunList->temporaryShuntToDrawPosText(this, SkPoint::Make(0, 0));
} else {
auto origin = glyphRunList->origin();
auto paint = glyphRunList->paint();
this->drawTextBlob(blob, origin.x(), origin.y(), paint);
}
}
void SkPDFDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint &paint) {
for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {

View File

@ -98,6 +98,7 @@ public:
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint&) override;
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y, const SkPaint &) override;
void drawGlyphRunList(SkGlyphRunList* glyphRunList) override;
void drawVertices(const SkVertices*, const SkMatrix* bones, int boneCount, SkBlendMode,
const SkPaint&) override;
void drawDevice(SkBaseDevice*, int x, int y,