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
This commit is contained in:
halcanary 2015-10-27 14:01:05 -07:00 committed by Commit bot
parent aef4971443
commit 337797580d
10 changed files with 72 additions and 58 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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));

View File

@ -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();
}

View File

@ -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();

View File

@ -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<const SkTextBlob> 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());