aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkGlyphCache.cpp2
-rw-r--r--src/core/SkGlyphCache.h2
-rw-r--r--src/core/SkGlyphRun.cpp42
-rw-r--r--src/core/SkGlyphRun.h63
-rw-r--r--tests/GlyphRunTest.cpp27
5 files changed, 90 insertions, 46 deletions
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp
index e5c871fd7d..45e67f2c14 100644
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -130,7 +130,7 @@ const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi
return *this->lookupByPackedGlyphID(packedGlyphID, kFull_MetricsType);
}
-void SkGlyphCache::getAdvances(SkSpan<SkGlyphID> glyphIDs, SkPoint advances[]) {
+void SkGlyphCache::getAdvances(SkSpan<const SkGlyphID> glyphIDs, SkPoint advances[]) {
for (ptrdiff_t i = 0; i < glyphIDs.size(); i++) {
auto glyph = this->getGlyphIDAdvance(glyphIDs[i]);
advances[i] = SkPoint::Make(glyph.fAdvanceX, glyph.fAdvanceY);
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 612ddb48c6..0d979d3afa 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -68,7 +68,7 @@ public:
const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y);
const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y);
- void getAdvances(SkSpan<SkGlyphID>, SkPoint[]);
+ void getAdvances(SkSpan<const SkGlyphID>, SkPoint[]);
/** Return the glyphID for the specified Unichar. If the char has already been seen, use the
existing cache entry. If not, ask the scalercontext to compute it for us.
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index 61909656c0..5bf1aa86f9 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -35,7 +35,6 @@ static SkTypeface::Encoding convert_encoding(SkPaint::TextEncoding encoding) {
}
} // namespace
-
// -- SkGlyphSet ----------------------------------------------------------------------------------
uint32_t SkGlyphSet::uniqueSize() {
// The size is how big the vector is grown since being passed into reuse.
@@ -86,34 +85,32 @@ void SkGlyphSet::reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqu
}
// -- SkGlyphRun -----------------------------------------------------------------------------------
-SkGlyphRun::SkGlyphRun(SkSpan<uint16_t> denseIndex,
- SkSpan<SkPoint> positions,
+SkGlyphRun::SkGlyphRun(const SkIndexedRunInfo& runInfo,
+ size_t denseOffset, size_t denseSize,
+ size_t uniqueOffset, uint16_t uniqueSize,
SkSpan<SkGlyphID> scratchGlyphs,
- SkSpan<SkGlyphID> uniqueGlyphIDs,
SkSpan<const char> text,
SkSpan<uint32_t> clusters)
- : fDenseIndex{denseIndex}, fPositions{positions}
+ : fRunInfo{runInfo}
+ , fDenseOffset{denseOffset}, fDenseSize{denseSize}
+ , fUniqueOffset{uniqueOffset}, fUniqueSize{uniqueSize}
, fTemporaryShuntGlyphIDs{scratchGlyphs}
- , fUniqueGlyphIDs{uniqueGlyphIDs}
, fText{text}
- , fClusters{clusters} {
- SkASSERT(denseIndex.size() == positions.size());
- SkASSERT(denseIndex.size() == scratchGlyphs.size());
-}
+ , fClusters{clusters} { }
void SkGlyphRun::temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device) {
- auto pos = (const SkScalar*) fPositions.data();
+ auto pos = (const SkScalar*) this->positions().data();
device->drawPosText(
- fTemporaryShuntGlyphIDs.data(), fDenseIndex.size() * sizeof(SkGlyphID),
+ fTemporaryShuntGlyphIDs.data(), fDenseSize * 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();
+ auto pos = (const SkScalar*) this->positions().data();
callback(this->runSize(), bytes, pos);
}
@@ -202,13 +199,13 @@ SkGlyphRunList* SkGlyphRunBuilder::useGlyphRunList() {
size_t SkGlyphRunBuilder::runSize() const { return fDenseIndex.size() - fLastDenseIndex; }
-size_t SkGlyphRunBuilder::uniqueSize() const { return fUniqueGlyphs.size() - fLastUniqueIndex; }
+size_t SkGlyphRunBuilder::uniqueSize() const { return fUniqueGlyphIDs.size() - fLastUniqueIndex; }
void SkGlyphRunBuilder::initialize() {
fUniqueID = 0;
fDenseIndex.clear();
fPositions.clear();
- fUniqueGlyphs.clear();
+ fUniqueGlyphIDs.clear();
fGlyphRuns.clear();
fLastDenseIndex = 0;
fLastUniqueIndex = 0;
@@ -238,7 +235,7 @@ SkGlyphID* SkGlyphRunBuilder::addDenseAndUnique(
SkASSERT(glyphIDs != nullptr);
if (runSize > 0) {
- fGlyphSet.reuse(typeface->countGlyphs(), &fUniqueGlyphs);
+ fGlyphSet.reuse(typeface->countGlyphs(), &fUniqueGlyphIDs);
for (size_t i = 0; i < runSize; i++) {
fDenseIndex.push_back(fGlyphSet.add(glyphIDs[i]));
}
@@ -256,15 +253,15 @@ void SkGlyphRunBuilder::addGlyphRunToList(
auto uniqueSize = this->uniqueSize();
fGlyphRuns.emplace_back(
- SkSpan<uint16_t>(&fDenseIndex[fLastDenseIndex], runSize),
- SkSpan<SkPoint>(&fPositions[fLastDenseIndex], runSize),
+ fIndexed,
+ fLastDenseIndex, runSize,
+ fLastUniqueIndex, uniqueSize,
SkSpan<SkGlyphID>(temporaryShuntGlyphIDs, runSize),
- SkSpan<SkGlyphID>(&fUniqueGlyphs[fLastDenseIndex], uniqueSize),
text,
clusters);
fLastDenseIndex = fDenseIndex.size();
- fLastUniqueIndex = fUniqueGlyphs.size();
+ fLastUniqueIndex = fUniqueGlyphIDs.size();
}
}
@@ -277,14 +274,15 @@ void SkGlyphRunBuilder::drawText(
fScratchAdvances.resize(this->uniqueSize());
{
auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
- cache->getAdvances(SkSpan<SkGlyphID>{fUniqueGlyphs}, fScratchAdvances.data());
+ cache->getAdvances(
+ fIndexed.uniqueGlyphIDs(fLastUniqueIndex, uniqueSize()), fScratchAdvances.data());
}
SkPoint endOfLastGlyph = origin;
for (size_t i = 0; i < this->runSize(); i++) {
fPositions.push_back(endOfLastGlyph);
- endOfLastGlyph += fScratchAdvances[fDenseIndex[i]];
+ endOfLastGlyph += fScratchAdvances[fDenseIndex[fLastDenseIndex + i]];
}
if (paint.getTextAlign() != SkPaint::kLeft_Align) {
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h
index 1b41da5350..739ad0bc38 100644
--- a/src/core/SkGlyphRun.h
+++ b/src/core/SkGlyphRun.h
@@ -41,13 +41,38 @@ private:
size_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(SkSpan<uint16_t> denseIndex,
- SkSpan<SkPoint> positions,
+ SkGlyphRun(const SkIndexedRunInfo& runInfo,
+ size_t denseOffset, size_t denseSize,
+ size_t fUniqueOffset, uint16_t fUniqueSize,
SkSpan<SkGlyphID> scratchGlyphs,
- SkSpan<SkGlyphID> uniqueGlyphIDs,
SkSpan<const char> text,
SkSpan<uint32_t> clusters);
@@ -57,19 +82,24 @@ public:
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); }
+ 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);
+ }
private:
- // 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;
+ const SkIndexedRunInfo& fRunInfo;
+ const size_t fDenseOffset;
+ const size_t fDenseSize;
+ const size_t fUniqueOffset;
+ const uint16_t fUniqueSize;
+
// 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;
// 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.
@@ -152,12 +182,15 @@ private:
std::vector<uint16_t> fDenseIndex;
std::vector<SkPoint> fPositions;
- std::vector<SkGlyphID> fUniqueGlyphs;
+ 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.
+ // 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.
diff --git a/tests/GlyphRunTest.cpp b/tests/GlyphRunTest.cpp
index ca97404e7c..cd2a221719 100644
--- a/tests/GlyphRunTest.cpp
+++ b/tests/GlyphRunTest.cpp
@@ -44,7 +44,8 @@ DEF_TEST(GlyphRunBasic, reporter) {
}
DEF_TEST(GlyphRunBlob, reporter) {
- constexpr uint16_t count = 10;
+ constexpr uint16_t count = 5;
+ constexpr int runCount = 2;
auto tf = SkTypeface::MakeFromName("monospace", SkFontStyle());
@@ -57,14 +58,14 @@ DEF_TEST(GlyphRunBlob, reporter) {
font.setTextSize(1u);
SkTextBlobBuilder blobBuilder;
- for (int runNum = 0; runNum < 2; runNum++) {
+ for (int runNum = 0; runNum < runCount; runNum++) {
const auto& runBuffer = blobBuilder.allocRunPosH(font, count, runNum);
SkASSERT(runBuffer.utf8text == nullptr);
SkASSERT(runBuffer.clusters == nullptr);
for (int i = 0; i < count; i++) {
- runBuffer.glyphs[i] = static_cast<SkGlyphID>(i + runNum * 10);
- runBuffer.pos[i] = SkIntToScalar(i + runNum * 10);
+ runBuffer.glyphs[i] = static_cast<SkGlyphID>(i + runNum * count);
+ runBuffer.pos[i] = SkIntToScalar(i + runNum * count);
}
}
@@ -78,9 +79,21 @@ DEF_TEST(GlyphRunBlob, reporter) {
auto runList = runBuilder.useGlyphRunList();
- REPORTER_ASSERT(reporter, runList->size() == 2);
+ REPORTER_ASSERT(reporter, runList->size() == runCount);
+ int runIndex = 0;
for (auto& run : *runList) {
- REPORTER_ASSERT(reporter, run.runSize() == 10);
- REPORTER_ASSERT(reporter, run.uniqueSize() == 10);
+ REPORTER_ASSERT(reporter, run.runSize() == count);
+ REPORTER_ASSERT(reporter, run.uniqueSize() == count);
+
+ int index = 0;
+ for (auto p : run.positions()) {
+ if (p.x() != runIndex * count + index) {
+ ERRORF(reporter, "x: %g != k: %d", p.x(), runIndex * count + index);
+ break;
+ }
+ index += 1;
+ }
+
+ runIndex += 1;
}
} \ No newline at end of file