Add an index to SkGlyphPos

In the mask case, the original position is needed for the fallback case.
Add an index from the original sequence to lookup the source position
when needed.

Change-Id: I16ca08cab6be685af45e4ccabf3d1f76efd7e61e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/206709
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2019-04-08 16:29:36 -04:00 committed by Skia Commit-Bot
parent b156c41d87
commit 13df106d59
7 changed files with 49 additions and 47 deletions

View File

@ -306,13 +306,13 @@ void SkGlyphRunListPainter::processARGBFallback(SkScalar maxSourceGlyphDimension
fStrikeCache->findOrCreateScopedStrike(
*ad.getDesc(), effects, *runFont.getTypefaceOrDefault());
int drawableGlyphCount = strike->glyphMetrics(fARGBGlyphsIDs.data(),
fARGBPositions.data(),
fARGBGlyphsIDs.size(),
fGlyphPos);
size_t drawableGlyphCount = strike->glyphMetrics(fARGBGlyphsIDs.data(),
fARGBPositions.data(),
fARGBGlyphsIDs.size(),
fGlyphPos);
if (process) {
process->processDeviceFallback(
SkSpan<const SkGlyphPos>{fGlyphPos, SkTo<size_t>(drawableGlyphCount)},
SkSpan<const SkGlyphPos>{fGlyphPos, drawableGlyphCount},
strike.get());
}
@ -354,10 +354,11 @@ void SkGlyphRunListPainter::processARGBFallback(SkScalar maxSourceGlyphDimension
SkPoint* posCursor = fARGBPositions.data();
int glyphCount = 0;
for (SkGlyphID glyphID : fARGBGlyphsIDs) {
for (size_t i = 0; i < fARGBGlyphsIDs.size(); i++) {
SkGlyphID glyphID = fARGBGlyphsIDs[i];
SkPoint pos = *posCursor++;
const SkGlyph& glyph = strike->getGlyphMetrics(glyphID, {0, 0});
fGlyphPos[glyphCount++] = {&glyph, pos};
fGlyphPos[glyphCount++] = {i, &glyph, pos};
}
if (process) {
@ -430,19 +431,19 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi
*ad.getDesc(), effects, *dfFont.getTypefaceOrDefault());
int glyphCount = 0;
const SkPoint* positionCursor = fPositions;
for (auto glyphID : glyphRun.glyphsIDs()) {
SkPoint glyphSourcePosition = *positionCursor++;
for (size_t i = 0; i < glyphRun.runSize(); i++) {
SkGlyphID glyphID = glyphRun.glyphsIDs()[i];
SkPoint glyphSourcePosition = fPositions[i];
const SkGlyph& glyph = strike->getGlyphMetrics(glyphID, {0, 0});
if (glyph.isEmpty()) {
// do nothing
} else if (glyph.fMaskFormat == SkMask::kSDF_Format
&& glyph.maxDimension() <= SkStrikeCommon::kSkSideTooBigForAtlas) {
fGlyphPos[glyphCount++] = {&glyph, glyphSourcePosition};
fGlyphPos[glyphCount++] = {i, &glyph, glyphSourcePosition};
} else if (glyph.fMaskFormat != SkMask::kARGB32_Format
&& strike->decideCouldDrawFromPath(glyph)) {
fPaths.push_back({&glyph, glyphSourcePosition});
fPaths.push_back({i, &glyph, glyphSourcePosition});
} else {
addFallback(glyph, glyphSourcePosition);
}
@ -505,9 +506,9 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi
*ad.getDesc(), effects,*pathFont.getTypefaceOrDefault());
int glyphCount = 0;
const SkPoint* positionCursor = fPositions;
for (auto glyphID : glyphRun.glyphsIDs()) {
SkPoint glyphSourcePosition = *positionCursor++;
for (size_t i = 0; i < glyphRun.runSize(); i++) {
SkGlyphID glyphID = glyphRun.glyphsIDs()[i];
SkPoint glyphSourcePosition = fPositions[i];
// Use outline from {0, 0} because all transforms including subpixel translation
// happen during drawing.
@ -516,7 +517,7 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi
// do nothing
} else if (glyph.fMaskFormat != SkMask::kARGB32_Format
&& strike->decideCouldDrawFromPath(glyph)) {
fGlyphPos[glyphCount++] = {&glyph, glyphSourcePosition};
fGlyphPos[glyphCount++] = {i, &glyph, glyphSourcePosition};
} else {
addFallback(glyph, glyphSourcePosition);
}
@ -554,26 +555,25 @@ void SkGlyphRunListPainter::processGlyphRunList(const SkGlyphRunList& glyphRunLi
mapping.postTranslate(rounding.x(), rounding.y());
mapping.mapPoints(fPositions, glyphRun.positions().data(), glyphRun.runSize());
int glyphsWithMaskCount = 0;
const SkPoint* sourcePositionCursor = glyphRun.positions().data();
const SkPoint* devicePositionCursor = fPositions;
for (auto glyphID : glyphRun.glyphsIDs()) {
SkPoint glyphSourcePosition = *sourcePositionCursor++;
SkPoint glyphDevicePosition = *devicePositionCursor++;
if (!SkScalarsAreFinite(glyphDevicePosition.x(), glyphDevicePosition.y())) {
size_t drawableGlyphCount = strike->glyphMetrics(
glyphRun.glyphsIDs().data(), fPositions, glyphRun.runSize(), fGlyphPos);
size_t glyphsWithMaskCount = 0;
for (size_t i = 0; i < drawableGlyphCount; i++) {
SkGlyphPos glyphPos = fGlyphPos[i];
const SkGlyph& glyph = *glyphPos.glyph;
const SkPoint position = glyphPos.position;
if (!SkScalarsAreFinite(position.x(), position.y())) {
continue;
}
const SkGlyph& glyph = strike->getGlyphMetrics(glyphID, glyphDevicePosition);
if (glyph.isEmpty()) {
// do nothing
} else if (glyph.maxDimension() <= SkStrikeCommon::kSkSideTooBigForAtlas) {
fGlyphPos[glyphsWithMaskCount++] = {&glyph, glyphDevicePosition};
if (glyph.maxDimension() <= SkStrikeCommon::kSkSideTooBigForAtlas) {
fGlyphPos[glyphsWithMaskCount++] = glyphPos;
} else if (glyph.fMaskFormat != SkMask::kARGB32_Format
&& strike->decideCouldDrawFromPath(glyph)) {
fPaths.push_back({&glyph, glyphDevicePosition});
fPaths.push_back(glyphPos);
} else {
addFallback(glyph, origin + glyphSourcePosition);
addFallback(glyph, origin + glyphRun.positions()[glyphPos.index]);
}
}

View File

@ -610,12 +610,12 @@ void SkStrikeServer::SkGlyphCacheState::writeGlyphPath(const SkPackedGlyphID& gl
// This version of glyphMetrics only adds entries to result if their data need to be sent to the
// GPU process.
int SkStrikeServer::SkGlyphCacheState::glyphMetrics(
const SkGlyphID glyphIDs[], const SkPoint positions[], int n, SkGlyphPos result[]) {
size_t SkStrikeServer::SkGlyphCacheState::glyphMetrics(
const SkGlyphID glyphIDs[], const SkPoint positions[], size_t n, SkGlyphPos result[]) {
int glyphsToSendCount = 0;
size_t glyphsToSendCount = 0;
const SkPoint* posCursor = positions;
for (int i = 0; i < n; i++) {
for (size_t i = 0; i < n; i++) {
SkPoint glyphPos = *posCursor++;
SkGlyphID glyphID = glyphIDs[i];
SkIPoint lookupPoint = SkStrikeCommon::SubpixelLookup(fAxisAlignmentForHText, glyphPos);
@ -634,7 +634,7 @@ int SkStrikeServer::SkGlyphCacheState::glyphMetrics(
this->ensureScalerContext();
fContext->getMetrics(glyphPtr);
result[glyphsToSendCount++] = {glyphPtr, glyphPos};
result[glyphsToSendCount++] = {i, glyphPtr, glyphPos};
// Make sure to send the glyph to the GPU because we always send the image for a glyph.
fCachedGlyphImages.add(packedGlyphID);

View File

@ -43,7 +43,7 @@ public:
const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) override;
int glyphMetrics(const SkGlyphID[], const SkPoint[], int n, SkGlyphPos result[]) override;
size_t glyphMetrics(const SkGlyphID[], const SkPoint[], size_t n, SkGlyphPos result[]) override;
bool decideCouldDrawFromPath(const SkGlyph& glyph) override;

View File

@ -233,19 +233,19 @@ const SkGlyph& SkStrike::getGlyphMetrics(SkGlyphID glyphID, SkPoint position) {
// N.B. This glyphMetrics call culls all the glyphs which will not display based on a non-finite
// position or that there are no mask pixels.
int SkStrike::glyphMetrics(const SkGlyphID glyphIDs[],
const SkPoint positions[],
int n,
SkGlyphPos result[]) {
size_t SkStrike::glyphMetrics(const SkGlyphID glyphIDs[],
const SkPoint positions[],
size_t n,
SkGlyphPos result[]) {
int drawableGlyphCount = 0;
size_t drawableGlyphCount = 0;
const SkPoint* posCursor = positions;
for (int i = 0; i < n; i++) {
for (size_t i = 0; i < n; i++) {
SkPoint glyphPos = *posCursor++;
if (SkScalarsAreFinite(glyphPos.x(), glyphPos.y())) {
const SkGlyph& glyph = this->getGlyphMetrics(glyphIDs[i], glyphPos);
if (!glyph.isEmpty()) {
result[drawableGlyphCount++] = {&glyph, glyphPos};
result[drawableGlyphCount++] = {i, &glyph, glyphPos};
}
}
}

View File

@ -136,7 +136,7 @@ public:
this->getScalerContext()->getEffects()};
}
int glyphMetrics(const SkGlyphID[], const SkPoint[], int n, SkGlyphPos result[]) override;
size_t glyphMetrics(const SkGlyphID[], const SkPoint[], size_t n, SkGlyphPos result[]) override;
void onAboutToExitScope() override;

View File

@ -36,8 +36,8 @@ public:
return fStrike.getGlyphMetrics(glyphID, position);
}
int glyphMetrics(
const SkGlyphID id[], const SkPoint point[], int n, SkGlyphPos result[]) override {
size_t glyphMetrics(
const SkGlyphID id[], const SkPoint point[], size_t n, SkGlyphPos result[]) override {
return fStrike.glyphMetrics(id, point, n, result);
}

View File

@ -53,6 +53,7 @@ private:
};
struct SkGlyphPos {
size_t index;
const SkGlyph* glyph;
SkPoint position;
};
@ -70,7 +71,8 @@ public:
virtual SkStrikeSpec strikeSpec() const = 0;
// glyphMetrics writes its results to result, but only returns a subspan of result.
virtual int glyphMetrics(const SkGlyphID[], const SkPoint[], int n, SkGlyphPos result[]) = 0;
virtual size_t glyphMetrics(
const SkGlyphID[], const SkPoint[], size_t n, SkGlyphPos result[]) = 0;
virtual const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) = 0;
virtual bool decideCouldDrawFromPath(const SkGlyph& glyph) = 0;
virtual void onAboutToExitScope() = 0;