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>
This commit is contained in:
parent
91e260f4db
commit
9d85d63468
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user