aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-07-09 15:53:57 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-10 16:57:25 +0000
commitb77822b4442d57d69835355c6c9e9a1354d65fce (patch)
tree40cc30bb3c4c5efcd2f8fa8b0c938eddb86533af
parent1d784ceafa9e0f3e32ef341900bc349f90abb81d (diff)
Remove the SkGlyphRunInfo code
The SkGlyphRunInfo code caused most of the complication. Maintaining the various different indices became unwieldy. Change-Id: Ia0a1259338c8572c57bb11d2407f5709459e0c72 Reviewed-on: https://skia-review.googlesource.com/140001 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
-rw-r--r--src/core/SkDevice.cpp4
-rw-r--r--src/core/SkGlyphRun.cpp153
-rw-r--r--src/core/SkGlyphRun.h98
3 files changed, 90 insertions, 165 deletions
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index c1359e7075..2b7fef62fb 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -165,7 +165,7 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
SkGlyphRunBuilder builder;
builder.prepareDrawText(runPaint, (const char*) it.glyphs(), textLen, origin);
auto glyphRun = builder.useGlyphRun();
- glyphRun->temporaryShuntToDrawPosText(runPaint, this);
+ glyphRun->temporaryShuntToDrawPosText(this);
}
break;
case SkTextBlob::kHorizontal_Positioning:
@@ -255,7 +255,7 @@ void SkBaseDevice::drawGlyphRun(const SkPaint& paint, SkGlyphRun* glyphRun) {
SkPaint glyphPaint(paint);
glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- glyphRun->temporaryShuntToDrawPosText(glyphPaint, this);
+ glyphRun->temporaryShuntToDrawPosText(this);
}
void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index fa070da3a7..426b8fbbcb 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -85,33 +85,37 @@ void SkGlyphSet::reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqu
}
// -- SkGlyphRun -----------------------------------------------------------------------------------
-SkGlyphRun::SkGlyphRun(const SkIndexedRunInfo* runInfo,
- size_t denseOffset, size_t denseSize,
- size_t uniqueOffset, uint16_t uniqueSize,
- SkSpan<SkGlyphID> scratchGlyphs,
+SkGlyphRun::SkGlyphRun(SkPaint&& runPaint,
+ SkSpan<const uint16_t> denseIndices,
+ SkSpan<const SkPoint> positions,
+ SkSpan<const SkGlyphID> glyphIDs,
+ SkSpan<const SkGlyphID> uniqueGlyphIDs,
SkSpan<const char> text,
- SkSpan<uint32_t> clusters)
- : fRunInfo{runInfo}
- , fDenseOffset{denseOffset}, fDenseSize{denseSize}
- , fUniqueOffset{uniqueOffset}, fUniqueSize{uniqueSize}
- , fTemporaryShuntGlyphIDs{scratchGlyphs}
+ SkSpan<const uint32_t> clusters)
+ : fUniqueGlyphIDIndices{denseIndices}
+ , fPositions{positions}
+ , fTemporaryShuntGlyphIDs{glyphIDs}
+ , fUniqueGlyphIDs{uniqueGlyphIDs}
, fText{text}
- , fClusters{clusters} { }
+ , fClusters{clusters}
+ , fRunPaint{std::move(runPaint)} {}
-
-void SkGlyphRun::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) {
+void SkGlyphRun::temporaryShuntToDrawPosText(SkBaseDevice* device) {
auto pos = (const SkScalar*) this->positions().data();
+ auto origin = SkPoint::Make(0, 0);
- device->drawPosText(
- fTemporaryShuntGlyphIDs.data(), fDenseSize * sizeof(SkGlyphID),
- pos, 2, SkPoint::Make(0, 0), paint);
+ if (!fTemporaryShuntGlyphIDs.empty()) {
+ device->drawPosText(
+ fTemporaryShuntGlyphIDs.data(), fTemporaryShuntGlyphIDs.size() * sizeof(SkGlyphID),
+ pos, 2, origin, fRunPaint);
+ }
}
void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) {
auto bytes = (const char *)fTemporaryShuntGlyphIDs.data();
auto pos = (const SkScalar*) this->positions().data();
- callback(this->runSize(), bytes, pos);
+ callback(fTemporaryShuntGlyphIDs.size(), bytes, pos);
}
// -- SkGlyphRunBuilder ----------------------------------------------------------------------------
@@ -122,7 +126,7 @@ void SkGlyphRunBuilder::prepareDrawText(
if (paint.getTextEncoding() != SkPaint::kUTF8_TextEncoding) {
originalText = SkSpan<const char>();
}
- this->drawText(paint, bytes, byteLength, origin, originalText, SkSpan<uint32_t>());
+ this->drawText(paint, bytes, byteLength, origin, originalText, SkSpan<const uint32_t>());
}
void SkGlyphRunBuilder::prepareDrawPosTextH(const SkPaint& paint, const void* bytes,
@@ -130,75 +134,31 @@ void SkGlyphRunBuilder::prepareDrawPosTextH(const SkPaint& paint, const void* by
SkScalar constY) {
this->initialize();
this->drawPosTextH(
- paint, bytes, byteLength, xpos, constY, SkSpan<const char>(), SkSpan<uint32_t>());
+ paint, bytes, byteLength, xpos, constY, SkSpan<const char>(), SkSpan<const uint32_t>());
}
void SkGlyphRunBuilder::prepareDrawPosText(const SkPaint& paint, const void* bytes,
size_t byteLength, const SkPoint* pos) {
this->initialize();
- this->drawPosText(paint, bytes, byteLength, pos, SkSpan<const char>(), SkSpan<uint32_t>());
-}
-
-void SkGlyphRunBuilder::prepareTextBlob(
- const SkPaint& paint, const SkTextBlob& blob, SkPoint origin) {
- this->initialize();
- fUniqueID = blob.uniqueID();
-
- SkPaint runPaint = paint;
-
- for (SkTextBlobRunIterator it(&blob); !it.done(); it.next()) {
- // applyFontToPaint() always overwrites the exact same attributes,
- // so it is safe to not re-seed the paint for this reason.
- it.applyFontToPaint(&runPaint);
-
- // These better be glyphs
- SkASSERT(runPaint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
-
- auto text = SkSpan<const char>(it.text(), it.textSize());
- auto clusters = SkSpan<uint32_t>(it.clusters(), it.glyphCount());
- size_t glyphLen = it.glyphCount() * sizeof(SkGlyphID);
- const SkPoint& offset = it.offset();
-
- switch (it.positioning()) {
- case SkTextBlob::kDefault_Positioning: {
- auto dtOrigin = origin + offset;
- this->drawText(runPaint, it.glyphs(), glyphLen, dtOrigin, text, clusters);
- }
- break;
- case SkTextBlob::kHorizontal_Positioning: {
- auto constY = origin.y() + offset.y();
- this->drawPosTextH(
- runPaint, it.glyphs(), glyphLen, it.pos(), constY, text, clusters);
- }
- break;
- case SkTextBlob::kFull_Positioning:
- this->drawPosText(
- runPaint, it.glyphs(), glyphLen, (const SkPoint*)it.pos(), text, clusters);
- break;
- default:
- SK_ABORT("unhandled positioning mode");
- }
- }
+ this->drawPosText(paint, bytes, byteLength, pos,
+ SkSpan<const char>(), SkSpan<const uint32_t>());
}
SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() {
return &fScratchGlyphRun;
}
-size_t SkGlyphRunBuilder::runSize() const { return fDenseIndex.size() - fLastDenseIndex; }
-
-size_t SkGlyphRunBuilder::uniqueSize() const { return fUniqueGlyphIDs.size() - fLastUniqueIndex; }
-
void SkGlyphRunBuilder::initialize() {
fUniqueID = 0;
fDenseIndex.clear();
fPositions.clear();
fUniqueGlyphIDs.clear();
- fLastDenseIndex = 0;
- fLastUniqueIndex = 0;
+
+ // Be sure to clean up the last run before we reuse it.
+ fScratchGlyphRun.~SkGlyphRun();
}
-SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique(
+void SkGlyphRunBuilder::addDenseAndUnique(
const SkPaint& paint, const void* bytes, size_t byteLength) {
size_t runSize = 0;
@@ -227,50 +187,47 @@ SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique(
fDenseIndex.push_back(fGlyphSet.add(glyphIDs[i]));
}
}
-
- return glyphIDs;
}
void SkGlyphRunBuilder::makeGlyphRun(
- SkGlyphID* temporaryShuntGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters) {
+ const SkPaint& runPaint,
+ SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
// Ignore empty runs.
- if (fDenseIndex.size() != fLastDenseIndex) {
- auto runSize = this->runSize();
- auto uniqueSize = this->uniqueSize();
+ if (!fDenseIndex.empty()) {
+ SkPaint glyphRunPaint{runPaint};
+ glyphRunPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ glyphRunPaint.setTextAlign(SkPaint::kLeft_Align);
new ((void*)&fScratchGlyphRun) SkGlyphRun{
- &fIndexed,
- fLastDenseIndex, runSize,
- fLastUniqueIndex, SkTo<uint16_t>(uniqueSize),
- SkSpan<SkGlyphID>(temporaryShuntGlyphIDs, runSize),
+ std::move(glyphRunPaint),
+ SkSpan<const uint16_t>{fDenseIndex},
+ SkSpan<const SkPoint>{fPositions},
+ SkSpan<const SkGlyphID>{fScratchGlyphIDs},
+ SkSpan<const SkGlyphID>{fUniqueGlyphIDs},
text,
clusters
};
-
- fLastDenseIndex = fDenseIndex.size();
- fLastUniqueIndex = fUniqueGlyphIDs.size();
}
}
void SkGlyphRunBuilder::drawText(
const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin,
- SkSpan<const char> text, SkSpan<uint32_t> clusters) {
+ SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
- SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength);
+ this->addDenseAndUnique(paint, bytes, byteLength);
- fScratchAdvances.resize(this->uniqueSize());
+ fScratchAdvances.resize(fUniqueGlyphIDs.size());
{
auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
- cache->getAdvances(
- fIndexed.uniqueGlyphIDs(fLastUniqueIndex, uniqueSize()), fScratchAdvances.data());
+ cache->getAdvances(SkSpan<const SkGlyphID>{fUniqueGlyphIDs}, fScratchAdvances.data());
}
SkPoint endOfLastGlyph = origin;
- for (size_t i = 0; i < this->runSize(); i++) {
+ for (size_t i = 0; i < fDenseIndex.size(); i++) {
fPositions.push_back(endOfLastGlyph);
- endOfLastGlyph += fScratchAdvances[fDenseIndex[fLastDenseIndex + i]];
+ endOfLastGlyph += fScratchAdvances[fDenseIndex[i]];
}
if (paint.getTextAlign() != SkPaint::kLeft_Align) {
@@ -278,38 +235,38 @@ void SkGlyphRunBuilder::drawText(
if (paint.getTextAlign() == SkPaint::kCenter_Align) {
len.scale(SK_ScalarHalf);
}
- for (size_t i = fLastDenseIndex; i < this->runSize(); i++) {
+ for (size_t i = 0; i < fDenseIndex.size(); i++) {
fPositions[i] -= len;
}
}
- this->makeGlyphRun(temporaryShuntGlyphIDs, text, clusters);
+ this->makeGlyphRun(paint, text, clusters);
}
void SkGlyphRunBuilder::drawPosTextH(const SkPaint& paint, const void* bytes,
size_t byteLength, const SkScalar* xpos,
SkScalar constY,
- SkSpan<const char> text, SkSpan<uint32_t> clusters) {
+ SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
- SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength);
+ this->addDenseAndUnique(paint, bytes, byteLength);
- for (size_t i = 0; i < runSize(); i++) {
+ for (size_t i = 0; i < fDenseIndex.size(); i++) {
fPositions.push_back(SkPoint::Make(xpos[i], constY));
}
- this->makeGlyphRun(temporaryShuntGlyphIDs, text, clusters);
+ this->makeGlyphRun(paint, text, clusters);
}
void SkGlyphRunBuilder::drawPosText(const SkPaint& paint, const void* bytes,
size_t byteLength, const SkPoint* pos,
- SkSpan<const char> text, SkSpan<uint32_t> clusters) {
- SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength);
+ SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
+ this->addDenseAndUnique(paint, bytes, byteLength);
- for (size_t i = 0; i < runSize(); i++) {
+ for (size_t i = 0; i < fDenseIndex.size(); i++) {
fPositions.push_back(pos[i]);
}
- this->makeGlyphRun(temporaryShuntGlyphIDs, text, clusters);
+ this->makeGlyphRun(paint, text, clusters);
}
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h
index 653b1f9ae1..d3f8c07cab 100644
--- a/src/core/SkGlyphRun.h
+++ b/src/core/SkGlyphRun.h
@@ -25,7 +25,8 @@ class SkSpan {
public:
SkSpan() : fPtr{nullptr}, fSize{0} {}
SkSpan(T* ptr, ptrdiff_t size) : fPtr{ptr}, fSize{size} { SkASSERT(size >= 0); }
- explicit SkSpan(std::vector<T>& v) : fPtr{v.data()}, fSize{SkTo<ptrdiff_t>(v.size())} {}
+ template <typename U>
+ explicit SkSpan(std::vector<U>& v) : fPtr{v.data()}, fSize{SkTo<ptrdiff_t>(v.size())} {}
SkSpan(const SkSpan<T>& o) = default;
SkSpan& operator=( const SkSpan& other ) = default;
T& operator [] (ptrdiff_t i) const { return fPtr[i]; }
@@ -42,70 +43,44 @@ private:
ptrdiff_t fSize;
};
-struct SkIndexedRunInfo {
- SkIndexedRunInfo(const std::vector<uint16_t>* denseIndex,
- const std::vector<SkPoint>* positions,
- const std::vector<SkGlyphID>* uniqueGlyphIDs)
- : fDenseIndex{denseIndex}
- , fPositions{positions}
- , fUniqueGlyphIDs{uniqueGlyphIDs} {}
-
- SkSpan<const uint16_t> denseIndex(size_t start, size_t size) {
- return SkSpan<const uint16_t>(&(*fDenseIndex)[start], size);
- }
-
- SkSpan<const SkPoint> positions(size_t start, size_t size) const {
- return SkSpan<const SkPoint>(&(*fPositions)[start], size);
- }
-
- SkSpan<const SkGlyphID> uniqueGlyphIDs(size_t start, size_t size) const {
- return SkSpan<const SkGlyphID>(&(*fUniqueGlyphIDs)[start], size);
- }
-
-private:
- const std::vector<uint16_t>* fDenseIndex;
- const std::vector<SkPoint>* fPositions;
- const std::vector<SkGlyphID>* fUniqueGlyphIDs;
-};
-
class SkGlyphRun {
public:
SkGlyphRun() = default;
- SkGlyphRun(const SkIndexedRunInfo* runInfo,
- size_t denseOffset, size_t denseSize,
- size_t fUniqueOffset, uint16_t fUniqueSize,
- SkSpan<SkGlyphID> scratchGlyphs,
+ SkGlyphRun(SkPaint&& runPaint,
+ SkSpan<const uint16_t> denseIndices,
+ SkSpan<const SkPoint> positions,
+ SkSpan<const SkGlyphID> glyphIDs,
+ SkSpan<const SkGlyphID> uniqueGlyphIDs,
SkSpan<const char> text,
- SkSpan<uint32_t> clusters);
+ SkSpan<const uint32_t> clusters);
// The temporaryShunt calls are to allow inter-operating with existing code while glyph runs
// are developed.
- void temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device);
+ void temporaryShuntToDrawPosText(SkBaseDevice* device);
using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>;
void temporaryShuntToCallback(TemporaryShuntCallback callback);
- size_t runSize() const { return fDenseSize; }
- uint16_t uniqueSize() const { return fUniqueSize; }
- SkSpan<const SkPoint> positions() const {
- return fRunInfo->positions(fDenseOffset, fDenseSize);
- }
- SkSpan<const SkGlyphID> uniqueGlyphIDs() const {
- return fRunInfo->uniqueGlyphIDs(fUniqueOffset, fUniqueSize);
- }
+ size_t runSize() const { return fUniqueGlyphIDIndices.size(); }
+ uint16_t uniqueSize() const { return fUniqueGlyphIDs.size(); }
+ SkSpan<const SkPoint> positions() const { return fPositions; }
+ SkSpan<const SkGlyphID> uniqueGlyphIDs() const { return fUniqueGlyphIDs; }
+ SkSpan<const SkGlyphID> shuntGlyphsIDs() const { return fTemporaryShuntGlyphIDs; }
private:
- const SkIndexedRunInfo* fRunInfo;
- size_t fDenseOffset;
- size_t fDenseSize;
- size_t fUniqueOffset;
- uint16_t fUniqueSize;
-
+ //
+ const SkSpan<const uint16_t> fUniqueGlyphIDIndices;
+ //
+ const SkSpan<const SkPoint> fPositions;
// This is temporary while converting from the old per glyph code to the bulk code.
- const SkSpan<SkGlyphID> fTemporaryShuntGlyphIDs;
+ const SkSpan<const SkGlyphID> fTemporaryShuntGlyphIDs;
+ // The unique glyphs from fTemporaryShuntGlyphIDs.
+ const SkSpan<const SkGlyphID> fUniqueGlyphIDs;
// Original text from SkTextBlob if present. Will be empty of not present.
const SkSpan<const char> fText;
// Original clusters from SkTextBlob if present. Will be empty if not present.
- const SkSpan<uint32_t> fClusters;
+ const SkSpan<const uint32_t> fClusters;
+ // Paint for this run modified to have glyph encoding and left alignment.
+ const SkPaint fRunPaint;
};
// A faster set implementation that does not need any initialization, and reading the set items
@@ -145,41 +120,34 @@ public:
SkGlyphRun* useGlyphRun();
private:
- size_t runSize() const;
- size_t uniqueSize() const;
void initialize();
- SkGlyphID* addDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength);
+ void addDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength);
void makeGlyphRun(
- SkGlyphID* temporaryShuntGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters);
+ const SkPaint& runPaint, SkSpan<const char> text, SkSpan<const uint32_t> clusters);
void drawText(
const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin,
- SkSpan<const char> text, SkSpan<uint32_t> clusters);
+ SkSpan<const char> text, SkSpan<const uint32_t> clusters);
void drawPosTextH(
const SkPaint& paint, const void* bytes, size_t byteLength,
const SkScalar* xpos, SkScalar constY,
- SkSpan<const char> text, SkSpan<uint32_t> clusters);
+ SkSpan<const char> text, SkSpan<const uint32_t> clusters);
void drawPosText(
const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint* pos,
- SkSpan<const char> text, SkSpan<uint32_t> clusters);
+ SkSpan<const char> text, SkSpan<const uint32_t> clusters);
- uint64_t fUniqueID{0};
+ uint64_t fUniqueID{0};
- std::vector<uint16_t> fDenseIndex;
- std::vector<SkPoint> fPositions;
+ std::vector<uint16_t> fDenseIndex;
+ std::vector<SkPoint> fPositions;
std::vector<SkGlyphID> fUniqueGlyphIDs;
- SkIndexedRunInfo fIndexed{&fDenseIndex, &fPositions, &fUniqueGlyphIDs};
-
- size_t fLastDenseIndex{0};
- size_t fLastUniqueIndex{0};
-
// Used as a temporary for preparing using utfN text. This implies that only one run of
// glyph ids will ever be needed because blobs are already glyph based.
std::vector<SkGlyphID> fScratchGlyphIDs;
// Used as temporary storage for calculating positions for drawText.
- std::vector<SkPoint> fScratchAdvances;
+ std::vector<SkPoint> fScratchAdvances;
// Used as temporary glyph run for the rest of the Text stack.