aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-06-18 16:25:52 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-19 19:56:25 +0000
commit9d85d63468eede1324c88b6e174834eb096113fe (patch)
treeb08d9d455cb2323aadea851abc10cf6d40d2a458
parent91e260f4dbcb4006c3b177c2eba7ed0dc1af3e3d (diff)
Use SkGlyphRun instead of builder
Move from passing builder down the stack to passing the object we really want to be the interface down the stack. Move code that shunts from glyph run style to drawTextPos to the SkGlyphRun from the builder. Change-Id: Iefaca69104737ce46c06fbb26dc99996784b2bdb Reviewed-on: https://skia-review.googlesource.com/135620 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Ben Wagner <bungeman@google.com>
-rw-r--r--src/core/SkCanvas.cpp9
-rw-r--r--src/core/SkDevice.cpp7
-rw-r--r--src/core/SkDevice.h4
-rw-r--r--src/core/SkGlyphRun.cpp46
-rw-r--r--src/core/SkGlyphRun.h47
-rw-r--r--src/gpu/text/GrTextContext.cpp11
6 files changed, 78 insertions, 46 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 494bd3b837..be55947efd 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2452,7 +2452,8 @@ void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkSca
while (iter.next()) {
fScratchGlyphRunBuilder->prepareDrawText(paint, text, byteLength, SkPoint::Make(x, y));
- iter.fDevice->drawGlyphRun(looper.paint(), fScratchGlyphRunBuilder.get());
+ auto glyphRun = fScratchGlyphRunBuilder->useGlyphRun();
+ iter.fDevice->drawGlyphRun(looper.paint(), glyphRun);
}
LOOPER_END
@@ -2465,7 +2466,8 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint
while (iter.next()) {
fScratchGlyphRunBuilder->prepareDrawPosText(paint, text, byteLength, pos);
- iter.fDevice->drawGlyphRun(looper.paint(), fScratchGlyphRunBuilder.get());
+ auto glyphRun = fScratchGlyphRunBuilder->useGlyphRun();
+ iter.fDevice->drawGlyphRun(looper.paint(), glyphRun);
}
LOOPER_END
@@ -2478,7 +2480,8 @@ void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScala
while (iter.next()) {
fScratchGlyphRunBuilder->prepareDrawPosTextH(paint, text, byteLength, xpos, constY);
- iter.fDevice->drawGlyphRun(looper.paint(), fScratchGlyphRunBuilder.get());
+ const auto& glyphRun = fScratchGlyphRunBuilder->useGlyphRun();
+ iter.fDevice->drawGlyphRun(looper.paint(), glyphRun);
}
LOOPER_END
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index aea08c55ab..23560986bc 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -165,7 +165,8 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
auto origin = SkPoint::Make(x + offset.x(), y + offset.y());
SkGlyphRunBuilder builder;
builder.prepareDrawText(runPaint, (const char*) it.glyphs(), textLen, origin);
- builder.temporaryShuntToDrawPosText(runPaint, this);
+ auto glyphRun = builder.useGlyphRun();
+ glyphRun->temporaryShuntToDrawPosText(runPaint, this);
}
break;
case SkTextBlob::kHorizontal_Positioning:
@@ -251,11 +252,11 @@ void SkBaseDevice::drawImageLattice(const SkImage* image,
}
}
-void SkBaseDevice::drawGlyphRun(const SkPaint& paint, SkGlyphRunBuilder* runBuilder) {
+void SkBaseDevice::drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun) {
SkPaint glyphPaint(paint);
glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- runBuilder->temporaryShuntToDrawPosText(glyphPaint, this);
+ glyphRun->temporaryShuntToDrawPosText(glyphPaint, this);
}
void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index 25008336c6..f840cf6218 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -224,7 +224,7 @@ protected:
* Does not handle text decoration.
* Decorations (underline and stike-thru) will be handled by SkCanvas.
*/
- virtual void drawGlyphRun(const SkPaint& paint, SkGlyphRunBuilder* info);
+ virtual void drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun);
virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) = 0;
virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
@@ -348,7 +348,7 @@ private:
friend class DeviceTestingAccess;
// Temporarily friend the SkGlyphRunBuilder until drawPosText is gone.
- friend class SkGlyphRunBuilder;
+ friend class SkGlyphRun;
virtual void drawPosText(const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) = 0;
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index caea07a076..29c1dfdb78 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -76,6 +76,24 @@ void SkGlyphSet::reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqu
// correctly even when the fIndexes buffer is uninitialized!
}
+// -- SkGlyphRun -----------------------------------------------------------------------------------
+
+void SkGlyphRun::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) {
+
+ auto pos = (const SkScalar*) fPositions.data();
+
+ device->drawPosText(
+ fTemporaryShuntGlyphIDs.data(), fDenseIndex.size() * sizeof(SkGlyphID),
+ pos, 2, SkPoint::Make(0, 0), paint);
+}
+
+void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) {
+ auto bytes = (const char *)fTemporaryShuntGlyphIDs.data();
+ auto pos = (const SkScalar*)fPositions.data();
+ callback(this->runSize(), bytes, pos);
+}
+
+
// -- SkGlyphRunBuilder ----------------------------------------------------------------------------
void SkGlyphRunBuilder::prepareDrawText(
const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin) {
@@ -127,26 +145,14 @@ void SkGlyphRunBuilder::prepareDrawPosText(const SkPaint& paint, const void* byt
}
}
-const SkGlyphRun& SkGlyphRunBuilder::useGlyphRun() const {
+SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() {
+ fScratchGlyphRun.~SkGlyphRun();
new ((void*)&fScratchGlyphRun) SkGlyphRun{SkSpan<uint16_t>(fDenseIndex),
- SkSpan<SkPoint>(fPositions),
- SkSpan<SkGlyphID>(fUniqueGlyphs)};
- return fScratchGlyphRun;
-}
-
-void SkGlyphRunBuilder::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) {
-
- auto pos = (const SkScalar*) fPositions.data();
-
- device->drawPosText(
- fTemporaryShuntGlyphIDs, fDenseIndex.size() * 2,
- pos, 2, SkPoint::Make(0, 0), paint);
-}
-
-void SkGlyphRunBuilder::temporaryShuntToCallback(TemporaryShuntCallback callback) {
- auto bytes = (const char *)fTemporaryShuntGlyphIDs;
- auto pos = (const SkScalar*)fPositions.data();
- callback(this->runSize(), bytes, pos);
+ SkSpan<SkPoint>(fPositions),
+ SkSpan<SkGlyphID>(
+ fTemporaryShuntGlyphIDs, fDenseIndex.size()),
+ SkSpan<SkGlyphID>(fUniqueGlyphs)};
+ return &fScratchGlyphRun;
}
void SkGlyphRunBuilder::initializeDenseAndUnique(
@@ -175,6 +181,8 @@ void SkGlyphRunBuilder::initializeDenseAndUnique(
glyphIDs = (const SkGlyphID*)bytes;
}
+ SkASSERT(glyphIDs != nullptr);
+
if (runSize == 0) { return; }
fTemporaryShuntGlyphIDs = glyphIDs;
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h
index eeb9c2924e..243d5d121c 100644
--- a/src/core/SkGlyphRun.h
+++ b/src/core/SkGlyphRun.h
@@ -23,13 +23,17 @@ class SkBaseDevice;
template <typename T>
class SkSpan {
public:
- SkSpan() = default;
+ SkSpan() : fPtr{nullptr}, fSize{0} {}
SkSpan(const T* ptr, size_t size) : fPtr{ptr}, fSize{size} {}
explicit SkSpan(const std::vector<T>& v) : fPtr{v.data()}, fSize{v.size()} {}
const T& operator [] (ptrdiff_t i) const { return fPtr[i]; }
- const T* begin() const { return fPtr; }
- const T* end() const { return fPtr + fSize; }
+ T* begin() const { return fPtr; }
+ T* end() const { return fPtr + fSize; }
+ const T* cbegin() const { return fPtr; }
+ const T* cend() const { return fPtr + fSize; }
+ const T* data() const { return fPtr; }
ptrdiff_t size() const { return fSize; }
+ bool empty() const { return fSize == 0; }
private:
const T* fPtr;
@@ -39,20 +43,37 @@ private:
class SkGlyphRun {
public:
SkGlyphRun() = default;
- SkGlyphRun(SkSpan<uint16_t> denseIndex, SkSpan<SkPoint> positions,
+ SkGlyphRun(SkSpan<uint16_t> denseIndex,
+ SkSpan<SkPoint> positions,
+ SkSpan<SkGlyphID> scratchGlyphs,
SkSpan<SkGlyphID> uniqueGlyphIDs)
: fDenseIndex{denseIndex}
, fPositions{positions}
- , fUniqueGlyphIDs{uniqueGlyphIDs} {}
+ , fTemporaryShuntGlyphIDs{scratchGlyphs}
+ , fUniqueGlyphIDs{uniqueGlyphIDs} {
+ SkASSERT(denseIndex.size() == positions.size());
+ SkASSERT(denseIndex.size() == scratchGlyphs.size());
+ }
+
+ // The temporaryShunt calls are to allow inter-operating with existing code while glyph runs
+ // are developed.
+ void temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device);
+ using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>;
+ void temporaryShuntToCallback(TemporaryShuntCallback callback);
size_t runSize() const { return fDenseIndex.size(); }
uint16_t uniqueSize() const { return fUniqueGlyphIDs.size(); }
SkSpan<SkPoint> positions() const { return SkSpan<SkPoint>(fPositions); }
private:
- SkSpan<uint16_t> fDenseIndex;
- SkSpan<SkPoint> fPositions;
- SkSpan<SkGlyphID> fUniqueGlyphIDs;
+ // Indices into the unique glyph IDs. On for each original glyph.
+ const SkSpan<uint16_t> fDenseIndex;
+ // The base line position of all the glyphs in source space.
+ const SkSpan<SkPoint> fPositions;
+ // This is temporary while converting from the old per glyph code to the bulk code.
+ const SkSpan<SkGlyphID> fTemporaryShuntGlyphIDs;
+ // The set of unique glyphs in the run.
+ const SkSpan<SkGlyphID> fUniqueGlyphIDs;
};
// A faster set implementation that does not need any initialization, and reading the set items
@@ -89,13 +110,7 @@ public:
size_t runSize() const {return fDenseIndex.size();}
size_t uniqueSize() const {return fUniqueGlyphs.size();}
- const SkGlyphRun& useGlyphRun() const;
-
- // The temporaryShunt calls are to allow inter-operating with existing code while glyph runs
- // are developed.
- void temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device);
- using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>;
- void temporaryShuntToCallback(TemporaryShuntCallback callback);
+ SkGlyphRun* useGlyphRun();
private:
void initializeDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength);
@@ -119,7 +134,7 @@ private:
const SkGlyphID* fTemporaryShuntGlyphIDs{nullptr};
// Used for collecting the set of unique glyphs.
- SkGlyphSet fGlyphSet;
+ SkGlyphSet fGlyphSet;
};
#endif // SkGlyphRunInfo_DEFINED
diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp
index b63b726079..6da4c0d014 100644
--- a/src/gpu/text/GrTextContext.cpp
+++ b/src/gpu/text/GrTextContext.cpp
@@ -217,7 +217,9 @@ void GrTextContext::regenerateTextBlob(GrTextBlob* cacheBlob,
builder.prepareDrawText(runPaint.skPaint(),
(const char*)it.glyphs(), textLen, origin);
- builder.temporaryShuntToCallback(
+ auto glyphRun = builder.useGlyphRun();
+
+ glyphRun->temporaryShuntToCallback(
[&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
this->drawDFPosText(
cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
@@ -250,7 +252,9 @@ void GrTextContext::regenerateTextBlob(GrTextBlob* cacheBlob,
builder.prepareDrawText(runPaint.skPaint(),
(const char*)it.glyphs(), textLen, origin);
- builder.temporaryShuntToCallback(
+ auto glyphRun = builder.useGlyphRun();
+
+ glyphRun->temporaryShuntToCallback(
[&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
this->DrawBmpPosText(
cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
@@ -782,8 +786,9 @@ std::unique_ptr<GrDrawOp> GrTextContext::createOp_TestingOnly(GrContext* context
builder.prepareDrawText(skPaint, text, textLen, origin);
sk_sp<GrTextBlob> blob;
+ auto glyphRun = builder.useGlyphRun();
// Use the text and textLen below, because we don't want to mess with the paint.
- builder.temporaryShuntToCallback(
+ glyphRun->temporaryShuntToCallback(
[&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
blob = textContext->makeDrawPosTextBlob(
context->contextPriv().getTextBlobCache(), glyphCache,