Remove runIndex as a concept for GrTextBlob

Change-Id: I8ac756a088c1dddf475bf96f9a4a84ec2cb500be
Reviewed-on: https://skia-review.googlesource.com/c/169763
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
Herb Derby 2018-11-08 15:03:48 -05:00 committed by Skia Commit-Bot
parent 5cd242b4fc
commit 2bb343c5e8
5 changed files with 205 additions and 239 deletions

View File

@ -317,29 +317,6 @@ void SkGlyphRunListPainter::processARGBFallback(
}
}
static SkRect rect_to_draw(
const SkGlyph& glyph, SkPoint origin, SkScalar textScale, bool isDFT) {
SkScalar dx = SkIntToScalar(glyph.fLeft);
SkScalar dy = SkIntToScalar(glyph.fTop);
SkScalar width = SkIntToScalar(glyph.fWidth);
SkScalar height = SkIntToScalar(glyph.fHeight);
if (isDFT) {
dx += SK_DistanceFieldInset;
dy += SK_DistanceFieldInset;
width -= 2 * SK_DistanceFieldInset;
height -= 2 * SK_DistanceFieldInset;
}
dx *= textScale;
dy *= textScale;
width *= textScale;
height *= textScale;
return SkRect::MakeXYWH(origin.x() + dx, origin.y() + dy, width, height);
}
// Beware! The following code will end up holding two glyph caches at the same time, but they
// will not be the same cache (which would cause two separate caches to be created).
template <typename PerPathT>
@ -395,15 +372,7 @@ void SkGlyphRunListPainter::drawGlyphRunAsBMPWithPathFallback(
if (SkScalarsAreFinite(mappedPt.x(), mappedPt.y())) {
const SkGlyph& glyph = cache->getGlyphMetrics(glyphID, mappedPt);
if (SkGlyphCacheCommon::GlyphTooBigForAtlas(glyph)) {
SkScalar sx = SkScalarFloorToScalar(mappedPt.fX),
sy = SkScalarFloorToScalar(mappedPt.fY);
SkRect glyphRect =
rect_to_draw(glyph, {sx, sy}, SK_Scalar1, false);
if (!glyphRect.isEmpty()) {
perPath(glyph, mappedPt);
}
perPath(glyph, mappedPt);
} else {
perGlyph(glyph, mappedPt);
}
@ -552,34 +521,6 @@ void GrTextContext::drawGlyphRunList(
clip, viewMatrix, origin.x(), origin.y());
}
static void append_glyph(GrTextBlob* blob, int runIndex,
const sk_sp<GrTextStrike>& strike,
const SkGlyph& skGlyph, GrGlyph::MaskStyle maskStyle,
SkScalar sx, SkScalar sy,
const SkPMColor4f& color, SkGlyphCache* skGlyphCache,
SkScalar textRatio, bool needsTransform) {
GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
skGlyph.getSubXFixed(),
skGlyph.getSubYFixed(),
maskStyle);
GrGlyph* glyph = strike->getGlyph(skGlyph, id, skGlyphCache);
if (!glyph) {
return;
}
SkASSERT(skGlyph.fWidth == glyph->width());
SkASSERT(skGlyph.fHeight == glyph->height());
bool isDFT = maskStyle == GrGlyph::kDistance_MaskStyle;
SkRect glyphRect = rect_to_draw(skGlyph, {sx, sy}, textRatio, isDFT);
if (!glyphRect.isEmpty()) {
blob->appendGlyph(runIndex, glyphRect, color, strike, glyph, !needsTransform);
}
}
void GrTextBlob::generateFromGlyphRunList(GrGlyphCache* glyphCache,
const GrShaderCaps& shaderCaps,
const GrTextContext::Options& options,
@ -595,26 +536,25 @@ void GrTextBlob::generateFromGlyphRunList(GrGlyphCache* glyphCache,
SkSpan<const SkPoint> positions, SkScalar textScale,
const SkMatrix& glyphCacheMatrix,
SkGlyphRunListPainter::NeedsTransform needsTransform) const {
fBlob->initOverride(fRunIndex);
fRun->initOverride();
fBlob->setHasBitmap();
fBlob->setSubRunHasW(fRunIndex, glyphCacheMatrix.hasPerspective());
fRun->setSubRunHasW(glyphCacheMatrix.hasPerspective());
SkExclusiveStrikePtr fallbackCache =
fBlob->setupCache(fRunIndex,
fallbackPaint, fProps, fScalerContextFlags, glyphCacheMatrix);
fRun->setupCache(fallbackPaint, fProps, fScalerContextFlags, glyphCacheMatrix);
sk_sp<GrTextStrike> strike = fGlyphCache->getStrike(fallbackCache.get());
const SkPoint* glyphPos = positions.data();
for (auto glyphID : glyphIDs) {
const SkGlyph& glyph = fallbackCache->getGlyphIDMetrics(glyphID);
append_glyph(fBlob, fRunIndex, strike, glyph,
GrGlyph::kCoverage_MaskStyle,
glyphPos->fX, glyphPos->fY, fFilteredColor,
fallbackCache.get(), textScale, needsTransform);
fRun->appendGlyph(fBlob, strike, glyph,
GrGlyph::kCoverage_MaskStyle,
*glyphPos, fFilteredColor,
fallbackCache.get(), textScale, needsTransform);
glyphPos++;
}
}
GrTextBlob* const fBlob;
const int fRunIndex;
GrTextBlob::Run* fRun;
const SkSurfaceProps& fProps;
const SkScalerContextFlags fScalerContextFlags;
GrGlyphCache* const fGlyphCache;
@ -625,12 +565,11 @@ void GrTextBlob::generateFromGlyphRunList(GrGlyphCache* glyphCache,
this->initReusableBlob(
glyphRunList.paint().computeLuminanceColor(), viewMatrix, origin.x(), origin.y());
int runIndex = 0;
for (const auto& glyphRun : glyphRunList) {
const SkPaint& runPaint = glyphRun.paint();
this->pushBackRun(runIndex);
Run* run = this->pushBackRun();
this->setRunPaintFlags(runIndex, runPaint.getFlags());
run->setRunPaintFlags(runPaint.getFlags());
if (GrTextContext::CanDrawAsDistanceFields(runPaint, viewMatrix, props,
shaderCaps.supportsDistanceFieldText(), options)) {
@ -644,42 +583,36 @@ void GrTextBlob::generateFromGlyphRunList(GrGlyphCache* glyphCache,
GrTextContext::InitDistanceFieldPaint(this, &distanceFieldPaint, viewMatrix,
options, &textRatio, &flags);
this->setHasDistanceField();
this->setSubRunHasDistanceFields(runIndex, runPaint.isLCDRenderText(),
runPaint.isAntiAlias(), hasWCoord);
run->setSubRunHasDistanceFields(runPaint.isLCDRenderText(),
runPaint.isAntiAlias(), hasWCoord);
{
auto cache = this->setupCache(
runIndex, distanceFieldPaint, props, flags, SkMatrix::I());
auto cache = run->setupCache(distanceFieldPaint, props, flags, SkMatrix::I());
sk_sp<GrTextStrike> currStrike = glyphCache->getStrike(cache.get());
auto perSDF =
[this, runIndex, &currStrike, filteredColor, cache{cache.get()}, textRatio]
[this, run, &currStrike, filteredColor, cache{cache.get()}, textRatio]
(const SkGlyph& glyph, SkPoint position) {
if (!glyph.isEmpty()) {
SkScalar sx = position.fX,
sy = position.fY;
append_glyph(this, runIndex, currStrike,
glyph, GrGlyph::kDistance_MaskStyle, sx, sy,
run->appendGlyph(this, currStrike,
glyph, GrGlyph::kDistance_MaskStyle, position,
filteredColor,
cache, textRatio, true);
}
};
auto perPath =
[this, runIndex, textRatio, cache{cache.get()}]
[run, textRatio, cache{cache.get()}]
(const SkGlyph& glyph, SkPoint position) {
if (!glyph.isEmpty()) {
if (const SkPath* glyphPath = cache->findPath(glyph)) {
SkScalar sx = position.fX,
sy = position.fY;
this->appendPathGlyph(
runIndex, *glyphPath, sx, sy, textRatio, false);
run->appendPathGlyph(*glyphPath, position, textRatio, false);
}
}
};
ARGBFallbackHelper argbFallback{this, runIndex, props, scalerContextFlags,
ARGBFallbackHelper argbFallback{this, run, props, scalerContextFlags,
glyphCache, filteredColor};
glyphPainter->drawGlyphRunAsSDFWithARGBFallback(
@ -701,18 +634,17 @@ void GrTextBlob::generateFromGlyphRunList(GrGlyphCache* glyphCache,
pathPaint, props, scalerContextFlags, SkMatrix::I());
// Given a glyph that is not ARGB, draw it.
auto perPath = [textScale, runIndex, this, &pathCache]
auto perPath = [textScale, run, &pathCache]
(const SkGlyph& glyph, SkPoint position) {
if (!glyph.isEmpty()) {
const SkPath* path = pathCache->findPath(glyph);
if (path != nullptr) {
this->appendPathGlyph(
runIndex, *path, position.fX, position.fY, textScale, false);
run->appendPathGlyph(*path, position, textScale, false);
}
}
};
ARGBFallbackHelper argbFallback{this, runIndex, props, scalerContextFlags,
ARGBFallbackHelper argbFallback{this, run, props, scalerContextFlags,
glyphCache, filteredColor};
glyphPainter->drawGlyphRunAsPathWithARGBFallback(
@ -722,35 +654,33 @@ void GrTextBlob::generateFromGlyphRunList(GrGlyphCache* glyphCache,
// Ensure the blob is set for bitmaptext
this->setHasBitmap();
auto cache = this->setupCache(
runIndex, runPaint, props, scalerContextFlags, viewMatrix);
auto cache = run->setupCache(runPaint, props, scalerContextFlags, viewMatrix);
sk_sp<GrTextStrike> currStrike = glyphCache->getStrike(cache.get());
auto perGlyph =
[this, runIndex, &currStrike, filteredColor, cache{cache.get()}]
[this, run, &currStrike, filteredColor, cache{cache.get()}]
(const SkGlyph& glyph, SkPoint mappedPt) {
if (!glyph.isEmpty()) {
const void* glyphImage = cache->findImage(glyph);
if (glyphImage != nullptr) {
SkScalar sx = SkScalarFloorToScalar(mappedPt.fX),
sy = SkScalarFloorToScalar(mappedPt.fY);
append_glyph(this, runIndex, currStrike,
glyph, GrGlyph::kCoverage_MaskStyle, sx, sy,
filteredColor, cache, SK_Scalar1, false);
SkPoint pt{SkScalarFloorToScalar(mappedPt.fX),
SkScalarFloorToScalar(mappedPt.fY)};
run->appendGlyph(this, currStrike,
glyph, GrGlyph::kCoverage_MaskStyle, pt,
filteredColor, cache, SK_Scalar1, false);
}
}
};
auto perPath =
[this, runIndex, cache{cache.get()}]
[run, cache{cache.get()}]
(const SkGlyph& glyph, SkPoint position) {
const SkPath* glyphPath = cache->findPath(glyph);
if (glyphPath != nullptr) {
SkScalar sx = SkScalarFloorToScalar(position.fX),
sy = SkScalarFloorToScalar(position.fY);
this->appendPathGlyph(
runIndex, *glyphPath, sx, sy, SK_Scalar1, true);
SkPoint pt{SkScalarFloorToScalar(position.fX),
SkScalarFloorToScalar(position.fY)};
run->appendPathGlyph(*glyphPath, pt, SK_Scalar1, true);
}
};
@ -758,7 +688,6 @@ void GrTextBlob::generateFromGlyphRunList(GrGlyphCache* glyphCache,
cache.get(), glyphRun, origin, viewMatrix,
std::move(perGlyph), std::move(perPath));
}
runIndex += 1;
}
}

View File

@ -40,7 +40,6 @@ public:
static bool GlyphTooBigForAtlas(const SkGlyph& glyph);
};
class SkGlyphRunListPainter {
public:
// Constructor for SkBitmpapDevice.

View File

@ -126,7 +126,7 @@ SkString GrAtlasTextOp::dumpInfo() const {
fGeoData[i].fColor.toBytes_RGBA(),
fGeoData[i].fX,
fGeoData[i].fY,
fGeoData[i].fBlob->runCount());
fGeoData[i].fBlob->runCountLimit());
}
str += fProcessors.dumpProcessors();

View File

@ -54,96 +54,133 @@ sk_sp<GrTextBlob> GrTextBlob::Make(int glyphCount, int runCount) {
for (int i = 0; i < runCount; i++) {
new (&cacheBlob->fRuns[i]) GrTextBlob::Run;
}
cacheBlob->fRunCount = runCount;
cacheBlob->fRunCountLimit = runCount;
return cacheBlob;
}
SkExclusiveStrikePtr GrTextBlob::setupCache(int runIndex,
const SkPaint& skPaint,
const SkSurfaceProps& props,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix) {
GrTextBlob::Run* run = &fRuns[runIndex];
SkExclusiveStrikePtr GrTextBlob::Run::setupCache(const SkPaint& skPaint,
const SkSurfaceProps& props,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix) {
// if we have an override descriptor for the run, then we should use that
SkAutoDescriptor* desc = run->fOverrideDescriptor.get() ? run->fOverrideDescriptor.get() :
&run->fDescriptor;
SkAutoDescriptor* desc = fOverrideDescriptor.get() ? fOverrideDescriptor.get() : &fDescriptor;
SkScalerContextEffects effects;
SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
skPaint, props, scalerContextFlags, viewMatrix, desc, &effects);
run->fTypeface = SkPaintPriv::RefTypefaceOrDefault(skPaint);
run->fPathEffect = sk_ref_sp(effects.fPathEffect);
run->fMaskFilter = sk_ref_sp(effects.fMaskFilter);
return SkStrikeCache::FindOrCreateStrikeExclusive(*desc->getDesc(), effects, *run->fTypeface);
fTypeface = SkPaintPriv::RefTypefaceOrDefault(skPaint);
fPathEffect = sk_ref_sp(effects.fPathEffect);
fMaskFilter = sk_ref_sp(effects.fMaskFilter);
return SkStrikeCache::FindOrCreateStrikeExclusive(*desc->getDesc(), effects, *fTypeface);
}
void GrTextBlob::appendGlyph(int runIndex,
const SkRect& positions,
const SkPMColor4f& color4f,
const sk_sp<GrTextStrike>& strike,
GrGlyph* glyph, bool preTransformed) {
// TODO4F: Preserve float colors
GrColor color = color4f.toBytes_RGBA();
static SkRect rect_to_draw(
const SkGlyph& glyph, SkPoint origin, SkScalar textScale, bool isDFT) {
Run& run = fRuns[runIndex];
GrMaskFormat format = glyph->fMaskFormat;
SkScalar dx = SkIntToScalar(glyph.fLeft);
SkScalar dy = SkIntToScalar(glyph.fTop);
SkScalar width = SkIntToScalar(glyph.fWidth);
SkScalar height = SkIntToScalar(glyph.fHeight);
Run::SubRunInfo* subRun = &run.fSubRunInfo.back();
if (run.fInitialized && subRun->maskFormat() != format) {
subRun = &run.push_back();
subRun->setStrike(strike);
} else if (!run.fInitialized) {
subRun->setStrike(strike);
if (isDFT) {
dx += SK_DistanceFieldInset;
dy += SK_DistanceFieldInset;
width -= 2 * SK_DistanceFieldInset;
height -= 2 * SK_DistanceFieldInset;
}
run.fInitialized = true;
dx *= textScale;
dy *= textScale;
width *= textScale;
height *= textScale;
bool hasW = subRun->hasWCoord();
// glyphs drawn in perspective must always have a w coord.
SkASSERT(hasW || !fInitialViewMatrix.hasPerspective());
size_t vertexStride = GetVertexStride(format, hasW);
subRun->setMaskFormat(format);
subRun->joinGlyphBounds(positions);
subRun->setColor(color);
intptr_t vertex = reinterpret_cast<intptr_t>(this->fVertices + subRun->vertexEndIndex());
// We always write the third position component used by SDFs. If it is unused it gets
// overwritten. Similarly, we always write the color and the blob will later overwrite it
// with texture coords if it is unused.
size_t colorOffset = hasW ? sizeof(SkPoint3) : sizeof(SkPoint);
// V0
*reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fTop, 1.f};
*reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
vertex += vertexStride;
// V1
*reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fBottom, 1.f};
*reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
vertex += vertexStride;
// V2
*reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fTop, 1.f};
*reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
vertex += vertexStride;
// V3
*reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fBottom, 1.f};
*reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
subRun->appendVertices(vertexStride);
fGlyphs[subRun->glyphEndIndex()] = glyph;
subRun->glyphAppended();
subRun->setNeedsTransform(!preTransformed);
return SkRect::MakeXYWH(origin.x() + dx, origin.y() + dy, width, height);
}
void GrTextBlob::appendPathGlyph(int runIndex, const SkPath& path, SkScalar x, SkScalar y,
void GrTextBlob::Run::appendGlyph(GrTextBlob* blob,
const sk_sp<GrTextStrike>& strike,
const SkGlyph& skGlyph, GrGlyph::MaskStyle maskStyle,
SkPoint origin,
const SkPMColor4f& color4f, SkGlyphCache* skGlyphCache,
SkScalar textRatio, bool needsTransform) {
GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
skGlyph.getSubXFixed(),
skGlyph.getSubYFixed(),
maskStyle);
GrGlyph* glyph = strike->getGlyph(skGlyph, id, skGlyphCache);
if (!glyph) {
return;
}
SkASSERT(skGlyph.fWidth == glyph->width());
SkASSERT(skGlyph.fHeight == glyph->height());
bool isDFT = maskStyle == GrGlyph::kDistance_MaskStyle;
SkRect glyphRect = rect_to_draw(skGlyph, origin, textRatio, isDFT);
if (!glyphRect.isEmpty()) {
// TODO4F: Preserve float colors
GrColor color = color4f.toBytes_RGBA();
GrMaskFormat format = glyph->fMaskFormat;
Run::SubRunInfo* subRun = &fSubRunInfo.back();
if (fInitialized && subRun->maskFormat() != format) {
subRun = &pushBackSubRun();
subRun->setStrike(strike);
} else if (!fInitialized) {
subRun->setStrike(strike);
}
fInitialized = true;
bool hasW = subRun->hasWCoord();
// glyphs drawn in perspective must always have a w coord.
SkASSERT(hasW || !blob->fInitialViewMatrix.hasPerspective());
size_t vertexStride = GetVertexStride(format, hasW);
subRun->setMaskFormat(format);
subRun->joinGlyphBounds(glyphRect);
subRun->setColor(color);
intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->vertexEndIndex());
// We always write the third position component used by SDFs. If it is unused it gets
// overwritten. Similarly, we always write the color and the blob will later overwrite it
// with texture coords if it is unused.
size_t colorOffset = hasW ? sizeof(SkPoint3) : sizeof(SkPoint);
// V0
*reinterpret_cast<SkPoint3*>(vertex) = {glyphRect.fLeft, glyphRect.fTop, 1.f};
*reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
vertex += vertexStride;
// V1
*reinterpret_cast<SkPoint3*>(vertex) = {glyphRect.fLeft, glyphRect.fBottom, 1.f};
*reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
vertex += vertexStride;
// V2
*reinterpret_cast<SkPoint3*>(vertex) = {glyphRect.fRight, glyphRect.fTop, 1.f};
*reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
vertex += vertexStride;
// V3
*reinterpret_cast<SkPoint3*>(vertex) = {glyphRect.fRight, glyphRect.fBottom, 1.f};
*reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
subRun->appendVertices(vertexStride);
blob->fGlyphs[subRun->glyphEndIndex()] = glyph;
subRun->glyphAppended();
subRun->setNeedsTransform(needsTransform);
}
}
void GrTextBlob::Run::appendPathGlyph(const SkPath& path, SkPoint position,
SkScalar scale, bool preTransformed) {
Run& run = fRuns[runIndex];
run.fPathGlyphs.push_back(GrTextBlob::Run::PathGlyph(path, x, y, scale, preTransformed));
fPathGlyphs.push_back(PathGlyph(path, position.x(), position.y(), scale, preTransformed));
}
bool GrTextBlob::mustRegenerate(const SkPaint& paint, bool anyRunHasSubpixelPosition,
@ -294,7 +331,7 @@ void GrTextBlob::flush(GrTextTarget* target, const SkSurfaceProps& props,
// GrTextBlob::makeOp only takes uint16_t values for run and subRun indices.
// Encountering something larger than this is highly unlikely, so we'll just not draw it.
int lastRun = SkTMin(fRunCount, (1 << 16)) - 1;
int lastRun = SkTMin(fRunCountLimit, (1 << 16)) - 1;
// For each run in the GrTextBlob we're going to churn through all the glyphs.
// Each run is broken into a path part and a Mask / DFT / ARGB part.
for (int runIndex = 0; runIndex <= lastRun; runIndex++) {
@ -465,8 +502,8 @@ void GrTextBlob::AssertEqual(const GrTextBlob& l, const GrTextBlob& r) {
SkASSERT_RELEASE(l.fMinMaxScale == r.fMinMaxScale);
SkASSERT_RELEASE(l.fTextType == r.fTextType);
SkASSERT_RELEASE(l.fRunCount == r.fRunCount);
for (int i = 0; i < l.fRunCount; i++) {
SkASSERT_RELEASE(l.fRunCountLimit == r.fRunCountLimit);
for (int i = 0; i < l.fRunCountLimit; i++) {
const Run& lRun = l.fRuns[i];
const Run& rRun = r.fRuns[i];

View File

@ -132,36 +132,18 @@ public:
void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; }
void setHasBitmap() { fTextType |= kHasBitmap_TextType; }
int runCount() const { return fRunCount; }
int runCountLimit() const { return fRunCountLimit; }
void pushBackRun(int currRun) {
SkASSERT(currRun < fRunCount);
if (currRun > 0) {
Run::SubRunInfo& newRun = fRuns[currRun].fSubRunInfo.back();
Run::SubRunInfo& lastRun = fRuns[currRun - 1].fSubRunInfo.back();
Run* pushBackRun() {
SkASSERT(fRunCount < fRunCountLimit);
if (fRunCount > 0) {
Run::SubRunInfo& newRun = fRuns[fRunCount].fSubRunInfo.back();
Run::SubRunInfo& lastRun = fRuns[fRunCount - 1].fSubRunInfo.back();
newRun.setAsSuccessor(lastRun);
}
}
// sets the last subrun of runIndex to use distance field text
void setSubRunHasDistanceFields(int runIndex, bool hasLCD, bool isAntiAlias, bool hasWCoord) {
Run& run = fRuns[runIndex];
Run::SubRunInfo& subRun = run.fSubRunInfo.back();
subRun.setUseLCDText(hasLCD);
subRun.setAntiAliased(isAntiAlias);
subRun.setDrawAsDistanceFields();
subRun.setHasWCoord(hasWCoord);
}
// sets the last subrun of runIndex to use w values
void setSubRunHasW(int runIndex, bool hasWCoord) {
Run& run = fRuns[runIndex];
Run::SubRunInfo& subRun = run.fSubRunInfo.back();
subRun.setHasWCoord(hasWCoord);
}
void setRunPaintFlags(int runIndex, uint16_t paintFlags) {
fRuns[runIndex].fPaintFlags = paintFlags & Run::kPaintFlagsMask;
fRunCount++;
return &fRuns[fRunCount - 1];
}
void setMinAndMaxScale(SkScalar scaledMax, SkScalar scaledMin) {
@ -170,33 +152,6 @@ public:
fMinMaxScale = SkMinScalar(scaledMin, fMinMaxScale);
}
// inits the override descriptor on the current run. All following subruns must use this
// descriptor
void initOverride(int runIndex) {
Run& run = fRuns[runIndex];
// Push back a new subrun to fill and set the override descriptor
run.push_back();
run.fOverrideDescriptor.reset(new SkAutoDescriptor);
}
SkExclusiveStrikePtr setupCache(int runIndex,
const SkPaint& skPaint,
const SkSurfaceProps& props,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix);
// Appends a glyph to the blob. If the glyph is too large, the glyph will be appended
// as a path.
void appendGlyph(int runIndex,
const SkRect& positions,
const SkPMColor4f& color,
const sk_sp<GrTextStrike>& strike,
GrGlyph* glyph, bool preTransformed);
// Appends a glyph to the blob as a path only.
void appendPathGlyph(int runIndex, const SkPath& path,
SkScalar x, SkScalar y, SkScalar scale, bool preTransformed);
static size_t GetVertexStride(GrMaskFormat maskFormat, bool hasWCoord) {
switch (maskFormat) {
case kA8_GrMaskFormat:
@ -280,7 +235,7 @@ public:
size_t size() const { return fSize; }
~GrTextBlob() {
for (int i = 0; i < fRunCount; i++) {
for (int i = 0; i < fRunCountLimit; i++) {
fRuns[i].~Run();
}
}
@ -313,7 +268,7 @@ private:
fInitialY = y;
// make sure all initial subruns have the correct VM and X/Y applied
for (int i = 0; i < fRunCount; i++) {
for (int i = 0; i < fRunCountLimit; i++) {
fRuns[i].fSubRunInfo[0].init(fInitialViewMatrix, x, y);
}
}
@ -474,7 +429,52 @@ private:
uint32_t fFlags;
}; // SubRunInfo
SubRunInfo& push_back() {
// sets the last subrun of runIndex to use w values
void setSubRunHasW(bool hasWCoord) {
Run::SubRunInfo& subRun = this->fSubRunInfo.back();
subRun.setHasWCoord(hasWCoord);
}
// inits the override descriptor on the current run. All following subruns must use this
// descriptor
void initOverride() {
// Push back a new subrun to fill and set the override descriptor
this->pushBackSubRun();
fOverrideDescriptor.reset(new SkAutoDescriptor);
}
// Appends a glyph to the blob as a path only.
void appendPathGlyph(
const SkPath& path, SkPoint position, SkScalar scale, bool preTransformed);
// Appends a glyph to the blob. If the glyph is too large, the glyph will be appended
// as a path.
void appendGlyph(GrTextBlob* blob,
const sk_sp<GrTextStrike>& strike,
const SkGlyph& skGlyph, GrGlyph::MaskStyle maskStyle,
SkPoint origin,
const SkPMColor4f& color, SkGlyphCache* skGlyphCache,
SkScalar textRatio, bool needsTransform);
SkExclusiveStrikePtr setupCache(const SkPaint& skPaint,
const SkSurfaceProps& props,
SkScalerContextFlags scalerContextFlags,
const SkMatrix& viewMatrix);
void setRunPaintFlags(uint16_t paintFlags) {
fPaintFlags = paintFlags & Run::kPaintFlagsMask;
}
// sets the last subrun of runIndex to use distance field text
void setSubRunHasDistanceFields(bool hasLCD, bool isAntiAlias, bool hasWCoord) {
Run::SubRunInfo& subRun = fSubRunInfo.back();
subRun.setUseLCDText(hasLCD);
subRun.setAntiAliased(isAntiAlias);
subRun.setDrawAsDistanceFields();
subRun.setHasWCoord(hasWCoord);
}
SubRunInfo& pushBackSubRun() {
// Forward glyph / vertex information to seed the new sub run
SubRunInfo& newSubRun = fSubRunInfo.push_back();
const SubRunInfo& prevSubRun = fSubRunInfo.fromBack(1);
@ -559,7 +559,8 @@ private:
// maximum minimum scale, and minimum maximum scale, we can support before we need to regen
SkScalar fMaxMinScale;
SkScalar fMinMaxScale;
int fRunCount;
int fRunCount{0};
int fRunCountLimit;
uint8_t fTextType;
};