From 337797580de42cdb722caab4bed121311ed7d0d2 Mon Sep 17 00:00:00 2001 From: halcanary Date: Tue, 27 Oct 2015 14:01:05 -0700 Subject: [PATCH] Make SkTextBlob::RunIterator public. Motivation: This will be easier than adding a friend every time I want to create a one-off SkCanvas subclass or SkRemote::Encoder subclass. See also: SkPath::Iter. Review URL: https://codereview.chromium.org/1411723005 --- include/core/SkTextBlob.h | 31 ++---------------- src/core/SkDevice.cpp | 4 +-- src/core/SkTextBlob.cpp | 28 ++++++++--------- src/core/SkTextBlobRunIterator.h | 40 ++++++++++++++++++++++++ src/gpu/GrAtlasTextContext.cpp | 8 ++--- src/gpu/GrAtlasTextContext.h | 4 +-- src/gpu/GrStencilAndCoverTextContext.cpp | 3 +- src/gpu/GrTextBlobCache.h | 4 +-- src/gpu/GrTextContext.cpp | 4 +-- tests/TextBlobTest.cpp | 4 +-- 10 files changed, 72 insertions(+), 58 deletions(-) create mode 100644 src/core/SkTextBlobRunIterator.h diff --git a/include/core/SkTextBlob.h b/include/core/SkTextBlob.h index a39f378abc..b0ab8929e6 100644 --- a/include/core/SkTextBlob.h +++ b/include/core/SkTextBlob.h @@ -46,37 +46,15 @@ public: */ static const SkTextBlob* CreateFromBuffer(SkReadBuffer&); -private: enum GlyphPositioning { kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph. kFull_Positioning = 2 // Point positioning -- two scalars per glyph. }; +private: class RunRecord; - class RunIterator { - public: - RunIterator(const SkTextBlob* blob); - - bool done() const; - void next(); - - uint32_t glyphCount() const; - const uint16_t* glyphs() const; - const SkScalar* pos() const; - const SkPoint& offset() const; - void applyFontToPaint(SkPaint*) const; - GlyphPositioning positioning() const; - bool isLCD() const; - - private: - const RunRecord* fCurrentRun; - int fRemainingRuns; - - SkDEBUGCODE(uint8_t* fStorageTop;) - }; - SkTextBlob(int runCount, const SkRect& bounds); virtual ~SkTextBlob(); @@ -92,13 +70,8 @@ private: static unsigned ScalarsPerGlyph(GlyphPositioning pos); - friend class GrAtlasTextContext; - friend class GrStencilAndCoverTextContext; - friend class GrTextBlobCache; - friend class GrTextContext; - friend class SkBaseDevice; friend class SkTextBlobBuilder; - friend class TextBlobTester; + friend class SkTextBlobRunIterator; const int fRunCount; const SkRect fBounds; diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 1f270af572..34c171db90 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -17,7 +17,7 @@ #include "SkRasterClip.h" #include "SkRSXform.h" #include "SkShader.h" -#include "SkTextBlob.h" +#include "SkTextBlobRunIterator.h" #include "SkTextToPathIter.h" SkBaseDevice::SkBaseDevice(const SkSurfaceProps& surfaceProps) @@ -103,7 +103,7 @@ void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc SkPaint runPaint = paint; - SkTextBlob::RunIterator it(blob); + SkTextBlobRunIterator it(blob); for (;!it.done(); it.next()) { size_t textLen = it.glyphCount() * sizeof(uint16_t); const SkPoint& offset = it.offset(); diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp index 7fd96ad8b2..ed26f43db8 100644 --- a/src/core/SkTextBlob.cpp +++ b/src/core/SkTextBlob.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "SkTextBlob.h" +#include "SkTextBlobRunIterator.h" #include "SkReadBuffer.h" #include "SkTypeface.h" @@ -220,7 +220,7 @@ void SkTextBlob::flatten(SkWriteBuffer& buffer) const { buffer.writeRect(fBounds); SkPaint runPaint; - RunIterator it(this); + SkTextBlobRunIterator it(this); while (!it.done()) { SkASSERT(it.glyphCount() > 0); @@ -294,58 +294,58 @@ unsigned SkTextBlob::ScalarsPerGlyph(GlyphPositioning pos) { return pos; } -SkTextBlob::RunIterator::RunIterator(const SkTextBlob* blob) - : fCurrentRun(RunRecord::First(blob)) +SkTextBlobRunIterator::SkTextBlobRunIterator(const SkTextBlob* blob) + : fCurrentRun(SkTextBlob::RunRecord::First(blob)) , fRemainingRuns(blob->fRunCount) { SkDEBUGCODE(fStorageTop = (uint8_t*)blob + blob->fStorageSize;) } -bool SkTextBlob::RunIterator::done() const { +bool SkTextBlobRunIterator::done() const { return fRemainingRuns <= 0; } -void SkTextBlob::RunIterator::next() { +void SkTextBlobRunIterator::next() { SkASSERT(!this->done()); if (!this->done()) { SkDEBUGCODE(fCurrentRun->validate(fStorageTop);) - fCurrentRun = RunRecord::Next(fCurrentRun); + fCurrentRun = SkTextBlob::RunRecord::Next(fCurrentRun); fRemainingRuns--; } } -uint32_t SkTextBlob::RunIterator::glyphCount() const { +uint32_t SkTextBlobRunIterator::glyphCount() const { SkASSERT(!this->done()); return fCurrentRun->glyphCount(); } -const uint16_t* SkTextBlob::RunIterator::glyphs() const { +const uint16_t* SkTextBlobRunIterator::glyphs() const { SkASSERT(!this->done()); return fCurrentRun->glyphBuffer(); } -const SkScalar* SkTextBlob::RunIterator::pos() const { +const SkScalar* SkTextBlobRunIterator::pos() const { SkASSERT(!this->done()); return fCurrentRun->posBuffer(); } -const SkPoint& SkTextBlob::RunIterator::offset() const { +const SkPoint& SkTextBlobRunIterator::offset() const { SkASSERT(!this->done()); return fCurrentRun->offset(); } -SkTextBlob::GlyphPositioning SkTextBlob::RunIterator::positioning() const { +SkTextBlob::GlyphPositioning SkTextBlobRunIterator::positioning() const { SkASSERT(!this->done()); return fCurrentRun->positioning(); } -void SkTextBlob::RunIterator::applyFontToPaint(SkPaint* paint) const { +void SkTextBlobRunIterator::applyFontToPaint(SkPaint* paint) const { SkASSERT(!this->done()); fCurrentRun->font().applyToPaint(paint); } -bool SkTextBlob::RunIterator::isLCD() const { +bool SkTextBlobRunIterator::isLCD() const { return SkToBool(fCurrentRun->font().flags() & SkPaint::kLCDRenderText_Flag); } diff --git a/src/core/SkTextBlobRunIterator.h b/src/core/SkTextBlobRunIterator.h new file mode 100644 index 0000000000..42bbac0bc9 --- /dev/null +++ b/src/core/SkTextBlobRunIterator.h @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef SkTextBlobRunIterator_DEFINED +#define SkTextBlobRunIterator_DEFINED + +#include "SkTextBlob.h" + +/** + * Iterate through all of the text runs of the text blob. For example: + * for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) { + * ..... + * } + */ +class SkTextBlobRunIterator { +public: + SkTextBlobRunIterator(const SkTextBlob* blob); + + bool done() const; + void next(); + + uint32_t glyphCount() const; + const uint16_t* glyphs() const; + const SkScalar* pos() const; + const SkPoint& offset() const; + void applyFontToPaint(SkPaint*) const; + SkTextBlob::GlyphPositioning positioning() const; + bool isLCD() const; + +private: + const SkTextBlob::RunRecord* fCurrentRun; + int fRemainingRuns; + + SkDEBUGCODE(uint8_t* fStorageTop;) +}; + +#endif // SkTextBlobRunIterator_DEFINED diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index 108d63c919..4d6a675d99 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -228,7 +228,7 @@ GrColor GrAtlasTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd // textblob is being built and cache it. However, for the time being textblobs mostly only have 1 // run so this is not a big deal to compute here. bool GrAtlasTextContext::HasLCD(const SkTextBlob* blob) { - SkTextBlob::RunIterator it(blob); + SkTextBlobRunIterator it(blob); for (; !it.done(); it.next()) { if (it.isLCD()) { return true; @@ -496,7 +496,7 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob, // Regenerate textblob SkPaint runPaint = skPaint; - SkTextBlob::RunIterator it(blob); + SkTextBlobRunIterator it(blob); for (int run = 0; !it.done(); it.next(), run++) { int glyphCount = it.glyphCount(); size_t textLen = glyphCount * sizeof(uint16_t); @@ -2050,7 +2050,7 @@ private: }; void GrAtlasTextContext::flushRunAsPaths(GrDrawContext* dc, GrRenderTarget* rt, - const SkTextBlob::RunIterator& it, + const SkTextBlobRunIterator& it, const GrClip& clip, const SkPaint& skPaint, SkDrawFilter* drawFilter, const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y) { @@ -2190,7 +2190,7 @@ void GrAtlasTextContext::flush(const SkTextBlob* blob, GrColor color = grPaint.getColor(); - SkTextBlob::RunIterator it(blob); + SkTextBlobRunIterator it(blob); for (int run = 0; !it.done(); it.next(), run++) { if (cacheBlob->fRuns[run].fDrawAsPaths) { this->flushRunAsPaths(dc, rt, it, clip, skPaint, diff --git a/src/gpu/GrAtlasTextContext.h b/src/gpu/GrAtlasTextContext.h index 3462b65058..f5421a669c 100644 --- a/src/gpu/GrAtlasTextContext.h +++ b/src/gpu/GrAtlasTextContext.h @@ -12,7 +12,7 @@ #include "GrAtlasTextBlob.h" #include "GrGeometryProcessor.h" -#include "SkTextBlob.h" +#include "SkTextBlobRunIterator.h" #ifdef GR_TEST_UTILS #include "GrBatchTest.h" @@ -73,7 +73,7 @@ private: GrGlyph*); inline void flushRunAsPaths(GrDrawContext*, GrRenderTarget*, - const SkTextBlob::RunIterator&, const GrClip& clip, + const SkTextBlobRunIterator&, const GrClip& clip, const SkPaint&, SkDrawFilter*, const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y); diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index ee1f1af410..5289d092c7 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -19,6 +19,7 @@ #include "SkGpuDevice.h" #include "SkGrPriv.h" #include "SkPath.h" +#include "SkTextBlobRunIterator.h" #include "SkTextMapStateProc.h" #include "SkTextFormatParams.h" @@ -204,7 +205,7 @@ void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob, const SkPaint& skPaint) { fCpuMemorySize = sizeof(TextBlob); SkPaint runPaint(skPaint); - for (SkTextBlob::RunIterator iter(skBlob); !iter.done(); iter.next()) { + for (SkTextBlobRunIterator iter(skBlob); !iter.done(); iter.next()) { iter.applyFontToPaint(&runPaint); // No need to re-seed the paint. TextRun* run = SkNEW_INSERT_AT_LLIST_TAIL(this, TextRun, (runPaint)); diff --git a/src/gpu/GrTextBlobCache.h b/src/gpu/GrTextBlobCache.h index 5f24e2ac16..8eee9d13db 100644 --- a/src/gpu/GrTextBlobCache.h +++ b/src/gpu/GrTextBlobCache.h @@ -10,7 +10,7 @@ #include "GrAtlasTextContext.h" #include "SkTDynamicHash.h" -#include "SkTextBlob.h" +#include "SkTextBlobRunIterator.h" class GrTextBlobCache { public: @@ -98,7 +98,7 @@ public: // TODO move to SkTextBlob static void BlobGlyphCount(int* glyphCount, int* runCount, const SkTextBlob* blob) { - SkTextBlob::RunIterator itCounter(blob); + SkTextBlobRunIterator itCounter(blob); for (; !itCounter.done(); itCounter.next(), (*runCount)++) { *glyphCount += itCounter.glyphCount(); } diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index a2e245d7e5..0ef18aaeb2 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -17,7 +17,7 @@ #include "SkGlyphCache.h" #include "SkGpuDevice.h" #include "SkGrPriv.h" -#include "SkTextBlob.h" +#include "SkTextBlobRunIterator.h" #include "SkTextMapStateProc.h" #include "SkTextToPathIter.h" @@ -116,7 +116,7 @@ void GrTextContext::drawTextBlob(GrDrawContext* dc, GrRenderTarget* rt, SkDrawFilter* drawFilter, const SkIRect& clipBounds) { SkPaint runPaint = skPaint; - SkTextBlob::RunIterator it(blob); + SkTextBlobRunIterator it(blob); for (;!it.done(); it.next()) { size_t textLen = it.glyphCount() * sizeof(uint16_t); const SkPoint& offset = it.offset(); diff --git a/tests/TextBlobTest.cpp b/tests/TextBlobTest.cpp index 027fd2ac76..aa4b1ea25f 100644 --- a/tests/TextBlobTest.cpp +++ b/tests/TextBlobTest.cpp @@ -7,7 +7,7 @@ #include "SkPaint.h" #include "SkPoint.h" -#include "SkTextBlob.h" +#include "SkTextBlobRunIterator.h" #include "Test.h" @@ -196,7 +196,7 @@ private: SkAutoTUnref blob(builder.build()); - SkTextBlob::RunIterator it(blob); + SkTextBlobRunIterator it(blob); for (unsigned i = 0; i < outCount; ++i) { REPORTER_ASSERT(reporter, !it.done()); REPORTER_ASSERT(reporter, out[i].pos == it.positioning());