Dont try to draw glyphs with unexpected mask formats

BUG=510931

Review URL: https://codereview.chromium.org/1269743003
This commit is contained in:
joshualitt 2015-07-30 07:59:20 -07:00 committed by Commit bot
parent ef004e1b49
commit 4f19ca325e
5 changed files with 32 additions and 10 deletions

View File

@ -1681,7 +1681,8 @@ public:
glyph->fMaskFormat == this->maskFormat());
if (!fFontCache->hasGlyph(glyph) &&
!strike->addGlyphToAtlas(batchTarget, glyph, scaler, skGlyph)) {
!strike->addGlyphToAtlas(batchTarget, glyph, scaler, skGlyph,
maskFormat)) {
this->flush(batchTarget, &flushInfo);
batchTarget->initDraw(gp, pipeline);
brokenRun = glyphIdx > 0;
@ -1689,7 +1690,8 @@ public:
SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(batchTarget,
glyph,
scaler,
skGlyph);
skGlyph,
maskFormat);
SkASSERT(success);
}
fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseToken, glyph,

View File

@ -196,7 +196,8 @@ void GrBatchTextStrike::removeID(GrBatchAtlas::AtlasID id) {
}
bool GrBatchTextStrike::addGlyphToAtlas(GrBatchTarget* batchTarget, GrGlyph* glyph,
GrFontScaler* scaler, const SkGlyph& skGlyph) {
GrFontScaler* scaler, const SkGlyph& skGlyph,
GrMaskFormat expectedMaskFormat) {
SkASSERT(glyph);
SkASSERT(scaler);
SkASSERT(fCache.find(glyph->fPackedID));
@ -204,7 +205,7 @@ bool GrBatchTextStrike::addGlyphToAtlas(GrBatchTarget* batchTarget, GrGlyph* gly
SkAutoUnref ar(SkSafeRef(scaler));
int bytesPerPixel = GrMaskFormatBytesPerPixel(glyph->fMaskFormat);
int bytesPerPixel = GrMaskFormatBytesPerPixel(expectedMaskFormat);
size_t size = glyph->fBounds.area() * bytesPerPixel;
SkAutoSMalloc<1024> storage(size);
@ -216,12 +217,13 @@ bool GrBatchTextStrike::addGlyphToAtlas(GrBatchTarget* batchTarget, GrGlyph* gly
}
} else {
if (!scaler->getPackedGlyphImage(skGlyph, glyph->width(), glyph->height(),
glyph->width() * bytesPerPixel, storage.get())) {
glyph->width() * bytesPerPixel, expectedMaskFormat,
storage.get())) {
return false;
}
}
bool success = fBatchFontCache->addToAtlas(this, &glyph->fID, batchTarget, glyph->fMaskFormat,
bool success = fBatchFontCache->addToAtlas(this, &glyph->fID, batchTarget, expectedMaskFormat,
glyph->width(), glyph->height(),
storage.get(), &glyph->fAtlasLocation);
if (success) {

View File

@ -40,8 +40,13 @@ public:
return glyph;
}
// returns true if glyph successfully added to texture atlas, false otherwise
bool addGlyphToAtlas(GrBatchTarget*, GrGlyph*, GrFontScaler*, const SkGlyph&);
// returns true if glyph successfully added to texture atlas, false otherwise. If the glyph's
// mask format has changed, then addGlyphToAtlas will draw a clear box. This will almost never
// happen.
// TODO we can handle some of these cases if we really want to, but the long term solution is to
// get the actual glyph image itself when we get the glyph metrics.
bool addGlyphToAtlas(GrBatchTarget*, GrGlyph*, GrFontScaler*, const SkGlyph&,
GrMaskFormat expectedMaskFormat);
// testing
int countGlyphs() const { return fCache.count(); }

View File

@ -103,7 +103,7 @@ void expand_bits(INT_TYPE* dst,
}
bool GrFontScaler::getPackedGlyphImage(const SkGlyph& glyph, int width, int height, int dstRB,
void* dst) {
GrMaskFormat expectedMaskFormat, void* dst) {
SkASSERT(glyph.fWidth == width);
SkASSERT(glyph.fHeight == height);
const void* src = fStrike->findImage(glyph);
@ -111,6 +111,18 @@ bool GrFontScaler::getPackedGlyphImage(const SkGlyph& glyph, int width, int heig
return false;
}
// crbug:510931
// Retrieving the image from the cache can actually change the mask format. This case is very
// uncommon so for now we just draw a clear box for these glyphs.
if (getPackedGlyphMaskFormat(glyph) != expectedMaskFormat) {
const int bpp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
for (int y = 0; y < height; y++) {
sk_bzero(dst, width * bpp);
dst = (char*)dst + dstRB;
}
return true;
}
int srcRB = glyph.rowBytes();
// The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to
// check the glyph's format, not the strike's format, and to be able to convert to any of the

View File

@ -52,7 +52,8 @@ public:
GrMaskFormat getMaskFormat() const;
GrMaskFormat getPackedGlyphMaskFormat(const SkGlyph&) const;
bool getPackedGlyphBounds(const SkGlyph&, SkIRect* bounds);
bool getPackedGlyphImage(const SkGlyph&, int width, int height, int rowBytes, void* image);
bool getPackedGlyphImage(const SkGlyph&, int width, int height, int rowBytes,
GrMaskFormat expectedMaskFormat, void* image);
bool getPackedGlyphDFBounds(const SkGlyph&, SkIRect* bounds);
bool getPackedGlyphDFImage(const SkGlyph&, int width, int height, void* image);
const SkPath* getGlyphPath(const SkGlyph&);