aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGlyphRun.cpp
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-06-21 16:03:47 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-28 03:36:16 +0000
commite2e52e46ca63540d429656baeee48fd3a402be26 (patch)
tree574c2f990282798988f47a5519a5ed5f3a990569 /src/core/SkGlyphRun.cpp
parent0ce5ab9d3122bcd9dce65ecb51a0da973da09816 (diff)
Remove drawTextBlob from device use drawGlyphRunList
Convert all backends to use GlyphRunList instead of text blobs. If the device did not originally implement drawTextBlob it will be simulated by drawPosText on the device. Other changes: Change to using an origin from absolulte positioning. The GPU code uses origin change to update blobs under translation. Change cluster to use const uint32_t instead of just uint32_t. Add SkPaint to runs. The draw filter is hosted up to the canavas level and applied there. Change-Id: Ib105b6bd26b67db55f1c954e37c79fbdcaa9d4a2 Reviewed-on: https://skia-review.googlesource.com/137224 Reviewed-by: Herb Derby <herb@google.com> Reviewed-by: Khusal Sagar <khushalsagar@chromium.org> Reviewed-by: Hal Canary <halcanary@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Herb Derby <herb@google.com>
Diffstat (limited to 'src/core/SkGlyphRun.cpp')
-rw-r--r--src/core/SkGlyphRun.cpp136
1 files changed, 95 insertions, 41 deletions
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index ce1c336d88..583d676940 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -12,7 +12,7 @@
#include <tuple>
#include "SkDevice.h"
-#include "SkDraw.h"
+#include "SkDrawFilter.h"
#include "SkGlyphCache.h"
#include "SkMSAN.h"
#include "SkMakeUnique.h"
@@ -90,22 +90,23 @@ SkGlyphRun::SkGlyphRun(const SkIndexedRunInfo& runInfo,
size_t uniqueOffset, uint16_t uniqueSize,
SkSpan<SkGlyphID> scratchGlyphs,
SkSpan<const char> text,
- SkSpan<uint32_t> clusters)
+ SkSpan<const uint32_t> clusters,
+ SkPaint&& runPaint)
: fRunInfo{runInfo}
, fDenseOffset{denseOffset}, fDenseSize{denseSize}
, fUniqueOffset{uniqueOffset}, fUniqueSize{uniqueSize}
, fTemporaryShuntGlyphIDs{scratchGlyphs}
, fText{text}
- , fClusters{clusters} { }
+ , fClusters{clusters}
+ , fRunPaint{std::move(runPaint)} {}
-
-void SkGlyphRun::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) {
+void SkGlyphRun::temporaryShuntToDrawPosText(SkBaseDevice* device, SkPoint origin) {
auto pos = (const SkScalar*) this->positions().data();
device->drawPosText(
fTemporaryShuntGlyphIDs.data(), fDenseSize * sizeof(SkGlyphID),
- pos, 2, SkPoint::Make(0, 0), paint);
+ pos, 2, origin, fRunPaint);
}
void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) {
@@ -115,19 +116,40 @@ void SkGlyphRun::temporaryShuntToCallback(TemporaryShuntCallback callback) {
}
// -- SkGlyphRunList -------------------------------------------------------------------------------
-SkGlyphRunList::SkGlyphRunList(SkSpan<SkGlyphRun> glyphRuns, uint64_t uniqueID)
- : fUniqueID{uniqueID}
- , fGlyphRuns{glyphRuns} { }
+SkGlyphRunList::SkGlyphRunList(
+ SkSpan<SkGlyphRun> glyphRuns, SkPoint origin, const SkTextBlob* textBlob)
+ : fGlyphRuns{glyphRuns}
+ , fOrigin{origin}
+ , fTemporaryTextBlobShunt{textBlob} { }
+
+uint64_t SkGlyphRunList::uniqueID() const {
+ return fTemporaryTextBlobShunt != nullptr ? fTemporaryTextBlobShunt->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(fTemporaryTextBlobShunt != nullptr);
+ fTemporaryTextBlobShunt->notifyAddedToCache(cacheID);
+}
+
+// -- SkGlyphRunListIterator -----------------------------------------------------------------------
+constexpr SkPoint SkGlyphRunListIterator::fZero;
// -- 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->drawText(paint, bytes, byteLength, origin, originalText, SkSpan<uint32_t>());
+ this->drawText(
+ paint, bytes, byteLength, origin, SkSpan<const char>(), SkSpan<const uint32_t>());
}
void SkGlyphRunBuilder::prepareDrawPosTextH(const SkPaint& paint, const void* bytes,
@@ -135,19 +157,22 @@ 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>());
+ this->drawPosText(paint, bytes, byteLength, pos,
+ SkSpan<const char>(), SkSpan<const uint32_t>());
}
void SkGlyphRunBuilder::prepareTextBlob(
- const SkPaint& paint, const SkTextBlob& blob, SkPoint origin) {
+ const SkPaint& paint, const SkTextBlob& blob, SkPoint origin, SkDrawFilter* drawFilter) {
this->initialize();
- fUniqueID = blob.uniqueID();
+ fTemporaryTextBlobShunt = &blob;
+ fOrigin = origin;
SkPaint runPaint = paint;
@@ -156,33 +181,44 @@ void SkGlyphRunBuilder::prepareTextBlob(
// so it is safe to not re-seed the paint for this reason.
it.applyFontToPaint(&runPaint);
+ if (drawFilter != nullptr && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) {
+ // A false return from filter() means we should abort the current draw.
+ runPaint = paint;
+ continue;
+ }
+
// 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());
+ auto clusters = SkSpan<const 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);
+ this->drawText(runPaint, it.glyphs(), glyphLen, offset, text, clusters);
}
break;
case SkTextBlob::kHorizontal_Positioning: {
- auto constY = origin.y() + offset.y();
+ auto constY = 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);
+ runPaint, it.glyphs(), glyphLen, (const SkPoint*)it.pos(), text,
+ clusters);
break;
default:
SK_ABORT("unhandled positioning mode");
}
+
+ if (drawFilter != nullptr) {
+ // A draw filter may change the paint arbitrarily, so we must re-seed in this case.
+ runPaint = paint;
+ }
}
}
@@ -193,22 +229,29 @@ SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() {
}
SkGlyphRunList* SkGlyphRunBuilder::useGlyphRunList() {
- new ((void*)&fScratchGlyphRunList) SkGlyphRunList{SkSpan<SkGlyphRun>(fGlyphRuns), fUniqueID};
+ new ((void*)&fScratchGlyphRunList)
+ SkGlyphRunList{SkSpan<SkGlyphRun>(fGlyphRuns), fOrigin, fTemporaryTextBlobShunt};
return &fScratchGlyphRunList;
}
+void SkGlyphRunBuilder::draw(SkBaseDevice* device) {
+ auto glyphRunList = this->useGlyphRunList();
+ device->drawGlyphRunList(glyphRunList);
+}
+
size_t SkGlyphRunBuilder::runSize() const { return fDenseIndex.size() - fLastDenseIndex; }
size_t SkGlyphRunBuilder::uniqueSize() const { return fUniqueGlyphIDs.size() - fLastUniqueIndex; }
void SkGlyphRunBuilder::initialize() {
- fUniqueID = 0;
+ fTemporaryTextBlobShunt = nullptr;
fDenseIndex.clear();
fPositions.clear();
fUniqueGlyphIDs.clear();
fGlyphRuns.clear();
fLastDenseIndex = 0;
fLastUniqueIndex = 0;
+ fOrigin = {0, 0};
}
SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique(
@@ -245,10 +288,19 @@ SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique(
}
void SkGlyphRunBuilder::addGlyphRunToList(
- SkGlyphID* temporaryShuntGlyphIDs, SkSpan<const char> text, SkSpan<uint32_t> clusters) {
+ const SkPaint& runPaint,
+ SkGlyphID* temporaryShuntGlyphIDs,
+ SkSpan<const char> text,
+ SkSpan<const uint32_t> clusters) {
// Ignore empty runs.
if (fDenseIndex.size() != fLastDenseIndex) {
+ SkPaint modifiedRunPaint{runPaint};
+
+ // TODO: remove these once the text stack has all the encoding and align code removed.
+ modifiedRunPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ modifiedRunPaint.setTextAlign(SkPaint::kLeft_Align);
+
auto runSize = this->runSize();
auto uniqueSize = this->uniqueSize();
@@ -258,7 +310,8 @@ void SkGlyphRunBuilder::addGlyphRunToList(
fLastUniqueIndex, SkTo<uint16_t>(uniqueSize),
SkSpan<SkGlyphID>(temporaryShuntGlyphIDs, runSize),
text,
- clusters);
+ clusters,
+ std::move(modifiedRunPaint));
fLastDenseIndex = fDenseIndex.size();
fLastUniqueIndex = fUniqueGlyphIDs.size();
@@ -267,7 +320,7 @@ void SkGlyphRunBuilder::addGlyphRunToList(
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);
@@ -286,22 +339,22 @@ void SkGlyphRunBuilder::drawText(
}
if (paint.getTextAlign() != SkPaint::kLeft_Align) {
- SkVector len = endOfLastGlyph - origin;
+ SkVector runWidth = endOfLastGlyph - origin;
if (paint.getTextAlign() == SkPaint::kCenter_Align) {
- len.scale(SK_ScalarHalf);
+ runWidth.scale(SK_ScalarHalf);
}
for (size_t i = fLastDenseIndex; i < this->runSize(); i++) {
- fPositions[i] -= len;
+ fPositions[i] -= runWidth;
}
}
- this->addGlyphRunToList(temporaryShuntGlyphIDs, text, clusters);
+ this->addGlyphRunToList(paint, 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) {
+void SkGlyphRunBuilder::drawPosTextH(
+ const SkPaint& paint, const void* bytes, size_t byteLength,
+ const SkScalar* xpos, SkScalar constY,
+ SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
SkGlyphID* temporaryShuntGlyphIDs = this->addDenseAndUnique(paint, bytes, byteLength);
@@ -309,19 +362,20 @@ void SkGlyphRunBuilder::drawPosTextH(const SkPaint& paint, const void* bytes,
fPositions.push_back(SkPoint::Make(xpos[i], constY));
}
- this->addGlyphRunToList(temporaryShuntGlyphIDs, text, clusters);
+ this->addGlyphRunToList(paint, 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) {
+void SkGlyphRunBuilder::drawPosText(
+ const SkPaint& paint, const void* bytes,
+ size_t byteLength, const SkPoint* pos,
+ SkSpan<const char> text, SkSpan<const 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);
+ this->addGlyphRunToList(paint, temporaryShuntGlyphIDs, text, clusters);
}