aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGlyphRun.cpp
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-06-21 20:03:04 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-21 20:03:07 +0000
commit149b541d8889198b61cec85dcfcb85dd872eccc4 (patch)
tree221b4edf90e0985a5b5dc5630ca12231ecde3e84 /src/core/SkGlyphRun.cpp
parent5c0c7983bb6371c493561dbc97671e4997f822d5 (diff)
Revert "Add SkGlyphRunList"
This reverts commit f2e4a039df33d9246bd0ec68602d4d06e6199553. Reason for revert: Breaks asan tests Original change's description: > Add SkGlyphRunList > > Extend the glyph run system with a glyph run list. This > allows the processing of text blobs. > > Add original text an cluster to runs for PDF. > > Change-Id: If4867d000e45f8975a30e982fc8fdbe104ef4332 > Reviewed-on: https://skia-review.googlesource.com/135627 > Reviewed-by: Ben Wagner <bungeman@google.com> > Commit-Queue: Herb Derby <herb@google.com> TBR=bungeman@google.com,herb@google.com Change-Id: I903592714da901383efc7e5f47ce3dfd529e2aca No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/136761 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Herb Derby <herb@google.com>
Diffstat (limited to 'src/core/SkGlyphRun.cpp')
-rw-r--r--src/core/SkGlyphRun.cpp241
1 files changed, 59 insertions, 182 deletions
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index 191dc75952..29c1dfdb78 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -19,8 +19,6 @@
#include "SkPaint.h"
#include "SkPaintPriv.h"
#include "SkStrikeCache.h"
-#include "SkTextBlob.h"
-#include "SkTextBlobRunIterator.h"
#include "SkTo.h"
#include "SkUtils.h"
@@ -60,9 +58,15 @@ void SkGlyphSet::reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqu
SkASSERT(glyphUniverseSize <= (1 << 16));
fUniverseSize = glyphUniverseSize;
fUniqueGlyphIDs = uniqueGlyphIDs;
-
// If we're hanging onto these arrays for a long time, we don't want their size to drift
- // endlessly upwards. It's unusual to see a typeface with more than 4096 possible glyphs.
+ // endlessly upwards. It's unusual to see more than 256 unique glyphs used in a run,
+ // or a typeface with more than 4096 possible glyphs.
+ if (fUniqueGlyphIDs->size() > 256) {
+ fUniqueGlyphIDs->resize(256);
+ fUniqueGlyphIDs->shrink_to_fit();
+ }
+ fUniqueGlyphIDs->clear();
+
if (glyphUniverseSize < 4096 && fIndices.size() > 4096) {
fIndices.resize(4096);
fIndices.shrink_to_fit();
@@ -73,21 +77,6 @@ void SkGlyphSet::reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqu
}
// -- SkGlyphRun -----------------------------------------------------------------------------------
-SkGlyphRun::SkGlyphRun(SkSpan<uint16_t> denseIndex,
- SkSpan<SkPoint> positions,
- SkSpan<SkGlyphID> scratchGlyphs,
- SkSpan<SkGlyphID> uniqueGlyphIDs,
- SkSpan<const char> text,
- SkSpan<uint32_t> clusters)
- : fDenseIndex{denseIndex}, fPositions{positions}
- , fTemporaryShuntGlyphIDs{scratchGlyphs}
- , fUniqueGlyphIDs{uniqueGlyphIDs}
- , fText{text}
- , fClusters{clusters} {
- SkASSERT(denseIndex.size() == positions.size());
- SkASSERT(denseIndex.size() == scratchGlyphs.size());
-}
-
void SkGlyphRun::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) {
@@ -104,110 +93,78 @@ void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) {
callback(this->runSize(), bytes, pos);
}
-// -- SkGlyphRunList -------------------------------------------------------------------------------
-SkGlyphRunList::SkGlyphRunList(SkSpan<SkGlyphRun> glyphRuns, uint64_t uniqueID)
- : fUniqueID{uniqueID}
- , fGlyphRuns{glyphRuns} { }
// -- SkGlyphRunBuilder ----------------------------------------------------------------------------
void SkGlyphRunBuilder::prepareDrawText(
const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin) {
- this->initialize();
- SkSpan<const char> originalText((const char*)bytes, byteLength);
- if (paint.getTextEncoding() != SkPaint::kUTF8_TextEncoding) {
- originalText = SkSpan<const char>();
+
+ this->initializeDenseAndUnique(paint, bytes, byteLength);
+
+ fScratchAdvances.resize(this->uniqueSize());
+ {
+ auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
+ cache->getAdvances(SkSpan<SkGlyphID>{fUniqueGlyphs}, fScratchAdvances.data());
+ }
+
+ SkPoint endOfLastGlyph = origin;
+
+ for (size_t i = 0; i < this->runSize(); i++) {
+ fPositions.push_back(endOfLastGlyph);
+ endOfLastGlyph += fScratchAdvances[fDenseIndex[i]];
+ }
+
+ if (paint.getTextAlign() != SkPaint::kLeft_Align) {
+ SkVector len = endOfLastGlyph - origin;
+ if (paint.getTextAlign() == SkPaint::kCenter_Align) {
+ len.scale(SK_ScalarHalf);
+ }
+ for (size_t i = 0; i < this->runSize(); i++) {
+ fPositions[i] -= len;
+ }
}
- this->drawText(paint, bytes, byteLength, origin, originalText, SkSpan<uint32_t>());
+
}
void SkGlyphRunBuilder::prepareDrawPosTextH(const SkPaint& paint, const void* bytes,
size_t byteLength, const SkScalar* xpos,
SkScalar constY) {
- this->initialize();
- this->drawPosTextH(
- paint, bytes, byteLength, xpos, constY, SkSpan<const char>(), SkSpan<uint32_t>());
+
+ this->initializeDenseAndUnique(paint, bytes, byteLength);
+
+ for (size_t i = 0; i < runSize(); i++) {
+ fPositions.push_back(SkPoint::Make(xpos[i], constY));
+ }
}
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>());
-}
+ this->initializeDenseAndUnique(paint, bytes, byteLength);
-void SkGlyphRunBuilder::prepareTextBlob(
- const SkPaint& paint, const SkTextBlob& blob, SkPoint origin) {
- this->initialize();
- fUniqueID = blob.uniqueID();
-
- SkPaint runPaint = paint;
-
- SkTextBlobRunIterator it(&blob);
- for (;!it.done(); it.next()) {
- size_t glyphLen = it.glyphCount() * sizeof(uint16_t);
- const SkPoint& offset = it.offset();
-
- // 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());
-
- 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");
- }
+ for (size_t i = 0; i < runSize(); i++) {
+ fPositions.push_back(pos[i]);
}
}
SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() {
- auto glyphRunList = this->useGlyphRunList();
- SkASSERT(glyphRunList->size() == 1);
- return &(*glyphRunList)[0];
-}
-
-SkGlyphRunList* SkGlyphRunBuilder::useGlyphRunList() {
- new ((void*)&fScratchGlyphRunList) SkGlyphRunList{SkSpan<SkGlyphRun>(fGlyphRuns), fUniqueID};
- return &fScratchGlyphRunList;
+ fScratchGlyphRun.~SkGlyphRun();
+ new ((void*)&fScratchGlyphRun) SkGlyphRun{SkSpan<uint16_t>(fDenseIndex),
+ SkSpan<SkPoint>(fPositions),
+ SkSpan<SkGlyphID>(
+ fTemporaryShuntGlyphIDs, fDenseIndex.size()),
+ SkSpan<SkGlyphID>(fUniqueGlyphs)};
+ return &fScratchGlyphRun;
}
-size_t SkGlyphRunBuilder::runSize() const { return fDenseIndex.size(); }
-
-size_t SkGlyphRunBuilder::uniqueSize() const { return fUniqueGlyphs.size(); }
+void SkGlyphRunBuilder::initializeDenseAndUnique(
+ const SkPaint& paint, const void* bytes, size_t byteLength) {
-void SkGlyphRunBuilder::initialize() {
- fUniqueID = 0;
fDenseIndex.clear();
fPositions.clear();
fUniqueGlyphs.clear();
- fGlyphRuns.clear();
- fLastDenseIndex = 0;
- fLastUniqueIndex = 0;
-}
-
-SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique(
- const SkPaint& paint, const void* bytes, size_t byteLength) {
+ fTemporaryShuntGlyphIDs = nullptr;
size_t runSize = 0;
- SkGlyphID* glyphIDs = nullptr;
+ const SkGlyphID* glyphIDs = nullptr;
auto encoding = paint.getTextEncoding();
auto typeface = SkPaintPriv::GetTypefaceOrDefault(paint);
if (encoding != SkPaint::kGlyphID_TextEncoding) {
@@ -221,98 +178,18 @@ SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique(
}
} else {
runSize = byteLength / 2;
- glyphIDs = (SkGlyphID*)bytes;
+ glyphIDs = (const SkGlyphID*)bytes;
}
SkASSERT(glyphIDs != nullptr);
- if (runSize > 0) {
- fGlyphSet.reuse(typeface->countGlyphs(), &fUniqueGlyphs);
- for (size_t i = 0; i < runSize; i++) {
- fDenseIndex.push_back(fGlyphSet.add(glyphIDs[i]));
- }
- }
-
- return glyphIDs;
-}
-
-void SkGlyphRunBuilder::addGlyphRunToList(
- SkGlyphID* temporaryShuntGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters) {
-
- // Ignore empty runs.
- if (fDenseIndex.size() != fLastDenseIndex) {
- auto runSize = fDenseIndex.size() - fLastDenseIndex;
- auto uniqueSize = fUniqueGlyphs.size() - fLastUniqueIndex;
-
- fGlyphRuns.emplace_back(
- SkSpan<uint16_t>(&fDenseIndex[fLastDenseIndex], runSize),
- SkSpan<SkPoint>(&fPositions[fLastDenseIndex], runSize),
- SkSpan<SkGlyphID>(temporaryShuntGlyphIDs, runSize),
- SkSpan<SkGlyphID>(&fUniqueGlyphs[fLastDenseIndex], uniqueSize),
- text,
- clusters);
-
- fLastDenseIndex = fDenseIndex.size();
- fLastUniqueIndex = fUniqueGlyphs.size();
- }
-}
-
-void SkGlyphRunBuilder::drawText(
- const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin,
- SkSpan<const char> text, SkSpan<uint32_t> clusters) {
-
- SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength);
-
- fScratchAdvances.resize(this->uniqueSize());
- {
- auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
- cache->getAdvances(SkSpan<SkGlyphID>{fUniqueGlyphs}, fScratchAdvances.data());
- }
-
- SkPoint endOfLastGlyph = origin;
-
- for (size_t i = 0; i < this->runSize(); i++) {
- fPositions.push_back(endOfLastGlyph);
- endOfLastGlyph += fScratchAdvances[fDenseIndex[i]];
- }
-
- if (paint.getTextAlign() != SkPaint::kLeft_Align) {
- SkVector len = endOfLastGlyph - origin;
- if (paint.getTextAlign() == SkPaint::kCenter_Align) {
- len.scale(SK_ScalarHalf);
- }
- for (size_t i = fLastDenseIndex; i < this->runSize(); i++) {
- fPositions[i] -= len;
- }
- }
-
- this->addGlyphRunToList(temporaryShuntGlyphIDs, 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) {
+ if (runSize == 0) { return; }
+ fTemporaryShuntGlyphIDs = glyphIDs;
- SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength);
-
- for (size_t i = 0; i < runSize(); i++) {
- fPositions.push_back(SkPoint::Make(xpos[i], constY));
+ fGlyphSet.reuse(typeface->countGlyphs(), &fUniqueGlyphs);
+ for (size_t i = 0; i < runSize; i++) {
+ fDenseIndex.push_back(fGlyphSet.add(glyphIDs[i]));
}
-
- this->addGlyphRunToList(temporaryShuntGlyphIDs, 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);
-
- for (size_t i = 0; i < runSize(); i++) {
- fPositions.push_back(pos[i]);
- }
-
- this->addGlyphRunToList(temporaryShuntGlyphIDs, text, clusters);
}