aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGlyphRun.cpp
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-07-12 15:30:35 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-13 03:21:54 +0000
commit8a6348e6d2ef095358cfc7d29d2a50d684cc719e (patch)
tree0554d2811a9550190ebca43f847b1c48e987f8cc /src/core/SkGlyphRun.cpp
parent1c5fd18927d5a128a12d7d5fe27f08d898be1e5b (diff)
Introduce text blob processing but don't wire it up
Have all the old code paths start using lists in preparation for introducing text blobs. Change-Id: I65cc02ee3da63bc3c9492db78a08b0eee3b1f931 Reviewed-on: https://skia-review.googlesource.com/141081 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
Diffstat (limited to 'src/core/SkGlyphRun.cpp')
-rw-r--r--src/core/SkGlyphRun.cpp141
1 files changed, 124 insertions, 17 deletions
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index 781263c103..6cb458544f 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -69,6 +69,36 @@ void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) {
callback(fTemporaryShuntGlyphIDs.size(), bytes, pos);
}
+// -- SkGlyphRunList -------------------------------------------------------------------------------
+SkGlyphRunList::SkGlyphRunList(
+ const SkPaint& paint,
+ const SkTextBlob* blob,
+ SkPoint origin,
+ SkSpan<SkGlyphRun> glyphRunList)
+ : fOriginalPaint{&paint}
+ , fOriginalTextBlob{blob}
+ , fOrigin{origin}
+ , fGlyphRuns{glyphRunList} { }
+
+uint64_t SkGlyphRunList::uniqueID() const {
+ return fOriginalTextBlob != nullptr ? fOriginalTextBlob->uniqueID()
+ : SK_InvalidUniqueID;
+}
+
+bool SkGlyphRunList::anyRunsLCD() const {
+ for (const auto& r : fGlyphRuns) {
+ if (r.paint().isLCDRenderText()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void SkGlyphRunList::temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) const {
+ SkASSERT(fOriginalTextBlob != nullptr);
+ fOriginalTextBlob->notifyAddedToCache(cacheID);
+}
+
// -- SkGlyphIDSet ---------------------------------------------------------------------------------
// A faster set implementation that does not need any initialization, and reading the set items
// is order the number of items, and not the size of the universe.
@@ -140,6 +170,8 @@ void SkGlyphRunBuilder::drawText(
this->simplifyDrawText(
paint, glyphIDs, origin, fUniqueGlyphIDIndices, fUniqueGlyphIDs, fPositions);
}
+
+ this->makeGlyphRunList(paint, nullptr, SkPoint::Make(0, 0));
}
void SkGlyphRunBuilder::drawPosTextH(const SkPaint& paint, const void* bytes,
@@ -151,6 +183,8 @@ void SkGlyphRunBuilder::drawPosTextH(const SkPaint& paint, const void* bytes,
this->simplifyDrawPosTextH(
paint, glyphIDs, xpos, constY, fUniqueGlyphIDIndices, fUniqueGlyphIDs, fPositions);
}
+
+ this->makeGlyphRunList(paint, nullptr, SkPoint::Make(0, 0));
}
void SkGlyphRunBuilder::drawPosText(const SkPaint& paint, const void* bytes,
@@ -158,17 +192,82 @@ void SkGlyphRunBuilder::drawPosText(const SkPaint& paint, const void* bytes,
auto glyphIDs = textToGlyphIDs(paint, bytes, byteLength);
if (!glyphIDs.empty()) {
this->initialize(glyphIDs.size());
- this->simplifyDrawPosText(
- paint, glyphIDs, pos, fUniqueGlyphIDIndices, fUniqueGlyphIDs);
+ this->simplifyDrawPosText(paint, glyphIDs, pos, fUniqueGlyphIDIndices, fUniqueGlyphIDs);
}
+
+ this->makeGlyphRunList(paint, nullptr, SkPoint::Make(0, 0));
}
-SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() {
- return &fScratchGlyphRun;
+void SkGlyphRunBuilder::drawTextBlob(const SkPaint& paint, const SkTextBlob& blob, SkPoint origin) {
+ SkPaint runPaint = paint;
+
+ // Figure out all the storage needed to pre-size everything below.
+ size_t totalGlyphs = 0;
+ for (SkTextBlobRunIterator it(&blob); !it.done(); it.next()) {
+ totalGlyphs += it.glyphCount();
+ }
+
+ // Pre-size all the buffers so they don't move during processing.
+ this->initialize(totalGlyphs);
+
+ uint16_t* currentDenseIndices = fUniqueGlyphIDIndices;
+ SkPoint* currentPositions = fPositions;
+ SkGlyphID* currentUniqueGlyphIDs = fUniqueGlyphIDs;
+
+ 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);
+ size_t runSize = it.glyphCount();
+
+ // These better be glyphs
+ SkASSERT(runPaint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
+
+ auto text = SkSpan<const char>(it.text(), it.textSize());
+ auto clusters = SkSpan<const uint32_t>(it.clusters(), runSize);
+ const SkPoint& offset = it.offset();
+ auto glyphIDs = SkSpan<const SkGlyphID>{it.glyphs(), runSize};
+
+ size_t uniqueGlyphIDsSize = 0;
+ switch (it.positioning()) {
+ case SkTextBlob::kDefault_Positioning: {
+ uniqueGlyphIDsSize = this->simplifyDrawText(
+ runPaint, glyphIDs, offset,
+ currentDenseIndices, currentUniqueGlyphIDs, currentPositions,
+ text, clusters);
+ }
+ break;
+ case SkTextBlob::kHorizontal_Positioning: {
+ auto constY = offset.y();
+ uniqueGlyphIDsSize = this->simplifyDrawPosTextH(
+ runPaint, glyphIDs, it.pos(), constY,
+ currentDenseIndices, currentUniqueGlyphIDs, currentPositions,
+ text, clusters);
+ }
+ break;
+ case SkTextBlob::kFull_Positioning:
+ uniqueGlyphIDsSize = this->simplifyDrawPosText(
+ runPaint, glyphIDs, (const SkPoint*)it.pos(),
+ currentDenseIndices, currentUniqueGlyphIDs,
+ text, clusters);
+ break;
+ default:
+ SK_ABORT("unhandled positioning mode");
+ }
+
+ currentDenseIndices += runSize;
+ currentPositions += runSize;
+ currentUniqueGlyphIDs += uniqueGlyphIDsSize;
+ }
+
+ this->makeGlyphRunList(paint, &blob, origin);
+}
+
+SkGlyphRunList* SkGlyphRunBuilder::useGlyphRunList() {
+ return &fGlyphRunList;
}
void SkGlyphRunBuilder::initialize(size_t totalRunSize) {
- fUniqueID = 0;
if (totalRunSize > fMaxTotalRunSize) {
fMaxTotalRunSize = totalRunSize;
@@ -177,8 +276,7 @@ void SkGlyphRunBuilder::initialize(size_t totalRunSize) {
fUniqueGlyphIDs.reset(fMaxTotalRunSize);
}
- // Be sure to clean up the last run before we reuse it.
- fScratchGlyphRun.~SkGlyphRun();
+ fGlyphRunListStorage.clear();
}
SkSpan<const SkGlyphID> SkGlyphRunBuilder::textToGlyphIDs(
@@ -236,25 +334,31 @@ void SkGlyphRunBuilder::makeGlyphRun(
glyphRunPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
glyphRunPaint.setTextAlign(SkPaint::kLeft_Align);
- new ((void*)&fScratchGlyphRun) SkGlyphRun{
+ fGlyphRunListStorage.emplace_back(
std::move(glyphRunPaint),
uniqueGlyphIDIndices,
positions,
glyphIDs,
uniqueGlyphIDs,
text,
- clusters
- };
+ clusters);
}
}
-void SkGlyphRunBuilder::simplifyDrawText(
+void SkGlyphRunBuilder::makeGlyphRunList(
+ const SkPaint& paint, const SkTextBlob* blob, SkPoint origin) {
+
+ fGlyphRunList.~SkGlyphRunList();
+ new (&fGlyphRunList) SkGlyphRunList{
+ paint, blob, origin, SkSpan<SkGlyphRun>{fGlyphRunListStorage}};
+}
+
+size_t SkGlyphRunBuilder::simplifyDrawText(
const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs, SkPoint origin,
uint16_t* uniqueGlyphIDIndicesBuffer, SkGlyphID* uniqueGlyphIDsBuffer, SkPoint* positions,
SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
SkASSERT(!glyphIDs.empty());
-
auto runSize = glyphIDs.size();
auto unqiueGlyphIDs = this->addDenseAndUnique(
@@ -271,7 +375,7 @@ void SkGlyphRunBuilder::simplifyDrawText(
for (size_t i = 0; i < runSize; i++) {
positions[i] = endOfLastGlyph;
- endOfLastGlyph += fScratchAdvances[fUniqueGlyphIDIndices[i]];
+ endOfLastGlyph += fScratchAdvances[uniqueGlyphIDIndicesBuffer[i]];
}
if (paint.getTextAlign() != SkPaint::kLeft_Align) {
@@ -289,14 +393,16 @@ void SkGlyphRunBuilder::simplifyDrawText(
paint,
glyphIDs,
SkSpan<const SkPoint>{positions, runSize},
- SkSpan<const uint16_t>{fUniqueGlyphIDIndices, runSize},
+ SkSpan<const uint16_t>{uniqueGlyphIDIndicesBuffer, runSize},
unqiueGlyphIDs,
text,
clusters);
}
+
+ return unqiueGlyphIDs.size();
}
-void SkGlyphRunBuilder::simplifyDrawPosTextH(
+size_t SkGlyphRunBuilder::simplifyDrawPosTextH(
const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs,
const SkScalar* xpos, SkScalar constY,
uint16_t* uniqueGlyphIDIndicesBuffer, SkGlyphID* uniqueGlyphIDsBuffer, SkPoint* positions,
@@ -307,13 +413,13 @@ void SkGlyphRunBuilder::simplifyDrawPosTextH(
*posCursor++ = SkPoint::Make(x, constY);
}
- this->simplifyDrawPosText(
+ return this->simplifyDrawPosText(
paint, glyphIDs, positions,
uniqueGlyphIDIndicesBuffer, uniqueGlyphIDsBuffer,
text, clusters);
}
-void SkGlyphRunBuilder::simplifyDrawPosText(
+size_t SkGlyphRunBuilder::simplifyDrawPosText(
const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs, const SkPoint* pos,
uint16_t* uniqueGlyphIDIndicesBuffer, SkGlyphID* uniqueGlyphIDsBuffer,
SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
@@ -336,6 +442,7 @@ void SkGlyphRunBuilder::simplifyDrawPosText(
uniqueGlyphIDs,
text,
clusters);
+ return 0;
}