aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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,