diff options
author | 2015-10-05 15:28:20 -0700 | |
---|---|---|
committer | 2015-10-05 15:28:21 -0700 | |
commit | 02015e51d90597e13525d46aa1757f34fc19307b (patch) | |
tree | 7cc73e2fd26fe5aab75d9b8322bcb00fa641445c /src/gpu | |
parent | 3bd909a44c46976e81d806dcaf69dbf0bbbb8501 (diff) |
Use SkTextBlob for nvpr color bitmap fallbacks
BUG=skia:
Review URL: https://codereview.chromium.org/1381873003
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrStencilAndCoverTextContext.cpp | 121 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverTextContext.h | 7 |
2 files changed, 98 insertions, 30 deletions
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index 9f394f9018..61f7f864d7 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -92,6 +92,32 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarg //////////////////////////////////////////////////////////////////////////////////////////////////// +class GrStencilAndCoverTextContext::FallbackBlobBuilder { +public: + FallbackBlobBuilder() : fBuffIdx(0) {} + + bool isInitialized() const { return SkToBool(fBuilder); } + + void init(const SkPaint& font, SkScalar textRatio); + + void appendGlyph(uint16_t glyphId, const SkPoint& pos); + + const SkTextBlob* buildIfInitialized(); + +private: + enum { kWriteBufferSize = 1024 }; + + void flush(); + + SkAutoTDelete<SkTextBlobBuilder> fBuilder; + SkPaint fFont; + int fBuffIdx; + uint16_t fGlyphIds[kWriteBufferSize]; + SkPoint fPositions[kWriteBufferSize]; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke) : fStroke(fontAndStroke), fFont(fontAndStroke) { @@ -198,16 +224,20 @@ void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by SkFixed fx = SkScalarToFixed(x); SkFixed fy = SkScalarToFixed(y); + FallbackBlobBuilder fallback; while (text < stop) { const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0); fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio); if (glyph.fWidth) { - this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedToScalar(fy))); + this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedToScalar(fy)), + &fallback); } fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio); fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio); } + + fFallbackTextBlob.reset(fallback.buildIfInitialized()); } void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength, @@ -230,6 +260,7 @@ void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); SkTextAlignProc alignProc(fFont.getTextAlign()); + FallbackBlobBuilder fallback; while (text < stop) { const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0); if (glyph.fWidth) { @@ -238,10 +269,12 @@ void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t SkPoint loc; alignProc(tmsLoc, glyph, &loc); - this->appendGlyph(glyph, loc); + this->appendGlyph(glyph, loc, &fallback); } pos += scalarsPerPosition; } + + fFallbackTextBlob.reset(fallback.buildIfInitialized()); } GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx, @@ -275,11 +308,14 @@ GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx, } inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& glyph, - const SkPoint& pos) { - // Stick the glyphs we can't draw into the fallback arrays. + const SkPoint& pos, + FallbackBlobBuilder* fallback) { + // Stick the glyphs we can't draw into the fallback text blob. if (SkMask::kARGB32_Format == glyph.fMaskFormat) { - fFallbackIndices.push_back(glyph.getGlyphID()); - fFallbackPositions.push_back(pos); + if (!fallback->isInitialized()) { + fallback->init(fFont, fTextRatio); + } + fallback->appendGlyph(glyph.getGlyphID(), pos); } else { float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * pos.y() }; fDraw->append(glyph.getGlyphID(), translate); @@ -318,31 +354,62 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc, GrPathRendering::kWinding_FillType); } - if (fFallbackIndices.count()) { - SkASSERT(fFallbackPositions.count() == fFallbackIndices.count()); - - enum { kPreservedFlags = SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag | - SkPaint::kLCDRenderText_Flag | SkPaint::kAutoHinting_Flag }; - + if (fFallbackTextBlob) { SkPaint fallbackSkPaint(originalSkPaint); fStroke.applyToPaint(&fallbackSkPaint); if (!fStroke.isFillStyle()) { fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio); } - fallbackSkPaint.setTextAlign(SkPaint::kLeft_Align); // Align has already been accounted for. - fallbackSkPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - fallbackSkPaint.setHinting(fFont.getHinting()); - fallbackSkPaint.setFlags((fFont.getFlags() & kPreservedFlags) | - (originalSkPaint.getFlags() & ~kPreservedFlags)); - // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non-bitmap color - // glyphs show up and https://code.google.com/p/skia/issues/detail?id=4408 gets resolved. - fallbackSkPaint.setSubpixelText(false); - fallbackSkPaint.setTextSize(fFont.getTextSize() * fTextRatio); - - fallbackTextContext->drawPosText(dc, rt, clip, paint, fallbackSkPaint, viewMatrix, - (char*)fFallbackIndices.begin(), - sizeof(uint16_t) * fFallbackIndices.count(), - fFallbackPositions[0].asScalars(), 2, SkPoint::Make(0, 0), - regionClipBounds); + + fallbackTextContext->drawTextBlob(dc, rt, clip, fallbackSkPaint, viewMatrix, + fFallbackTextBlob, 0, 0, nullptr, regionClipBounds); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void GrStencilAndCoverTextContext::FallbackBlobBuilder::init(const SkPaint& font, + SkScalar textRatio) { + SkASSERT(!this->isInitialized()); + fBuilder.reset(new SkTextBlobBuilder); + fFont = font; + fFont.setTextAlign(SkPaint::kLeft_Align); // The glyph positions will already account for align. + fFont.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non-bitmap color glyphs + // show up and https://code.google.com/p/skia/issues/detail?id=4408 gets resolved. + fFont.setSubpixelText(false); + fFont.setTextSize(fFont.getTextSize() * textRatio); + fBuffIdx = 0; +} + +void GrStencilAndCoverTextContext::FallbackBlobBuilder::appendGlyph(uint16_t glyphId, + const SkPoint& pos) { + SkASSERT(this->isInitialized()); + if (fBuffIdx >= kWriteBufferSize) { + this->flush(); + } + fGlyphIds[fBuffIdx] = glyphId; + fPositions[fBuffIdx] = pos; + fBuffIdx++; +} + +void GrStencilAndCoverTextContext::FallbackBlobBuilder::flush() { + SkASSERT(this->isInitialized()); + SkASSERT(fBuffIdx <= kWriteBufferSize); + if (!fBuffIdx) { + return; + } + // This will automatically merge with previous runs since we use the same font. + const SkTextBlobBuilder::RunBuffer& buff = fBuilder->allocRunPos(fFont, fBuffIdx); + memcpy(buff.glyphs, fGlyphIds, fBuffIdx * sizeof(uint16_t)); + memcpy(buff.pos, fPositions[0].asScalars(), fBuffIdx * 2 * sizeof(SkScalar)); + fBuffIdx = 0; +} + +const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfInitialized() { + if (!this->isInitialized()) { + return nullptr; } + this->flush(); + return fBuilder->build(); } diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h index c5c29ad86f..9e85e89c88 100644 --- a/src/gpu/GrStencilAndCoverTextContext.h +++ b/src/gpu/GrStencilAndCoverTextContext.h @@ -45,6 +45,8 @@ private: const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset, const SkIRect& regionClipBounds) override; + class FallbackBlobBuilder; + class TextRun { public: TextRun(const SkPaint& fontAndStroke); @@ -64,7 +66,7 @@ private: private: GrPathRange* createGlyphs(GrContext*, SkGlyphCache*); - void appendGlyph(const SkGlyph&, const SkPoint&); + void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*); GrStrokeInfo fStroke; SkPaint fFont; @@ -73,8 +75,7 @@ private: SkMatrix fLocalMatrix; bool fUsingRawGlyphPaths; SkAutoTUnref<GrPathRangeDraw> fDraw; - SkSTArray<32, uint16_t, true> fFallbackIndices; - SkSTArray<32, SkPoint, true> fFallbackPositions; + SkAutoTUnref<const SkTextBlob> fFallbackTextBlob; }; typedef GrTextContext INHERITED; |