Index: src/gpu/GrBitmapTextContext.cpp |
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp |
index b21d7ea9063c1e8d18df1108907cedc994b648f9..a887ec983887d6129c89040bd976ddd61e852be2 100755 |
--- a/src/gpu/GrBitmapTextContext.cpp |
+++ b/src/gpu/GrBitmapTextContext.cpp |
@@ -101,31 +101,80 @@ bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const |
paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() != blob.fStyle; |
} |
+ |
+inline SkGlyphCache* GrBitmapTextContextB::setupCache(BitmapTextBlob::Run* run, |
+ const SkPaint& skPaint, |
+ const SkMatrix& viewMatrix) { |
+ skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &viewMatrix, false); |
+ run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
+ return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc()); |
+} |
+ |
+inline void GrBitmapTextContextB::BlobGlyphCount(int* glyphCount, int* runCount, |
+ const SkTextBlob* blob) { |
+ SkTextBlob::RunIterator itCounter(blob); |
+ for (; !itCounter.done(); itCounter.next(), (*runCount)++) { |
+ *glyphCount += itCounter.glyphCount(); |
+ } |
+} |
+ |
+GrBitmapTextContextB::BitmapTextBlob* GrBitmapTextContextB::CreateBlob(int glyphCount, |
+ int runCount) { |
+ // We allocate size for the BitmapTextBlob itself, plus size for the vertices array, |
+ // and size for the glyphIds array. |
+ SK_COMPILE_ASSERT(kGrayTextVASize >= kColorTextVASize && kGrayTextVASize >= kLCDTextVASize, |
+ vertex_attribute_changed); |
+ size_t verticesCount = glyphCount * kVerticesPerGlyph * kGrayTextVASize; |
+ size_t length = sizeof(BitmapTextBlob) + |
+ verticesCount + |
+ glyphCount * sizeof(GrGlyph::PackedID) + |
+ sizeof(BitmapTextBlob::Run) * runCount; |
+ |
+ BitmapTextBlob* cacheBlob = SkNEW_PLACEMENT(sk_malloc_throw(length), BitmapTextBlob); |
+ |
+ // setup offsets for vertices / glyphs |
+ cacheBlob->fVertices = sizeof(BitmapTextBlob) + reinterpret_cast<unsigned char*>(cacheBlob); |
+ cacheBlob->fGlyphIDs = |
+ reinterpret_cast<GrGlyph::PackedID*>(cacheBlob->fVertices + verticesCount); |
+ cacheBlob->fRuns = reinterpret_cast<BitmapTextBlob::Run*>(cacheBlob->fGlyphIDs + glyphCount); |
+ |
+ // Initialize runs |
+ for (int i = 0; i < runCount; i++) { |
+ SkNEW_PLACEMENT(&cacheBlob->fRuns[i], BitmapTextBlob::Run); |
+ } |
+ cacheBlob->fRunCount = runCount; |
+ return cacheBlob; |
+} |
+ |
void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
const SkPaint& skPaint, const SkMatrix& viewMatrix, |
const SkTextBlob* blob, SkScalar x, SkScalar y, |
SkDrawFilter* drawFilter, const SkIRect& clipBounds) { |
BitmapTextBlob* cacheBlob; |
BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID()); |
- |
SkIRect clipRect; |
clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
if (foundBlob) { |
cacheBlob = *foundBlob; |
if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { |
- // We can get away with reusing the blob if there are no outstanding refs on it. |
- // However, we still have to reset all of the runs. |
- if (!cacheBlob->unique()) { |
- cacheBlob->unref(); |
- cacheBlob = SkNEW(BitmapTextBlob); |
- fCache.set(blob->uniqueID(), cacheBlob); |
- } |
+ // We have to remake the blob because changes may invalidate our masks. |
+ // TODO we could probably get away reuse most of the time if the pointer is unique, |
+ // but we'd have to clear the subrun information |
+ cacheBlob->unref(); |
+ int glyphCount = 0; |
+ int runCount = 0; |
+ BlobGlyphCount(&glyphCount, &runCount, blob); |
+ cacheBlob = CreateBlob(glyphCount, runCount); |
+ fCache.set(blob->uniqueID(), cacheBlob); |
this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, |
clipRect); |
} |
} else { |
- cacheBlob = SkNEW(BitmapTextBlob); |
+ int glyphCount = 0; |
+ int runCount = 0; |
+ BlobGlyphCount(&glyphCount, &runCount, blob); |
+ cacheBlob = CreateBlob(glyphCount, runCount); |
fCache.set(blob->uniqueID(), cacheBlob); |
this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, clipRect); |
} |
@@ -147,13 +196,13 @@ void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
cacheBlob->fX = x; |
cacheBlob->fY = y; |
cacheBlob->fStyle = skPaint.getStyle(); |
- cacheBlob->fRuns.reset(blob->fRunCount); |
// Regenerate textblob |
SkPaint runPaint = skPaint; |
SkTextBlob::RunIterator it(blob); |
for (int run = 0; !it.done(); it.next(), run++) { |
- size_t textLen = it.glyphCount() * sizeof(uint16_t); |
+ int glyphCount = it.glyphCount(); |
+ size_t textLen = glyphCount * sizeof(uint16_t); |
const SkPoint& offset = it.offset(); |
// applyFontToPaint() always overwrites the exact same attributes, |
// so it is safe to not re-seed the paint for this reason. |
@@ -167,19 +216,33 @@ void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); |
+ SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPaint, viewMatrix); |
+ |
+ // setup vertex / glyphIndex for the new run |
+ if (run > 0) { |
+ PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back(); |
+ PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back(); |
+ |
+ newRun.fVertexStartIndex = lastRun.fVertexEndIndex; |
+ newRun.fVertexEndIndex = lastRun.fVertexEndIndex; |
+ |
+ newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex; |
+ newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex; |
+ } |
+ |
switch (it.positioning()) { |
case SkTextBlob::kDefault_Positioning: |
- this->internalDrawText(cacheBlob, run, runPaint, viewMatrix, |
+ this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatrix, |
(const char *)it.glyphs(), textLen, |
x + offset.x(), y + offset.y(), clipRect); |
break; |
case SkTextBlob::kHorizontal_Positioning: |
- this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, |
+ this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewMatrix, |
(const char*)it.glyphs(), textLen, it.pos(), 1, |
SkPoint::Make(x, y + offset.y()), clipRect); |
break; |
case SkTextBlob::kFull_Positioning: |
- this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, |
+ this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewMatrix, |
(const char*)it.glyphs(), textLen, it.pos(), 2, |
SkPoint::Make(x, y), clipRect); |
break; |
@@ -189,6 +252,8 @@ void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
// A draw filter may change the paint arbitrarily, so we must re-seed in this case. |
runPaint = skPaint; |
} |
+ |
+ SkGlyphCache::AttachCache(cache); |
} |
} |
@@ -197,21 +262,26 @@ void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip, |
const SkMatrix& viewMatrix, |
const char text[], size_t byteLength, |
SkScalar x, SkScalar y, const SkIRect& regionClipBounds) { |
- SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); |
+ int glyphCount = skPaint.countText(text, byteLength); |
+ SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1)); |
blob->fViewMatrix = viewMatrix; |
blob->fX = x; |
blob->fY = y; |
blob->fStyle = skPaint.getStyle(); |
- blob->fRuns.push_back(); |
SkIRect clipRect; |
clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
- this->internalDrawText(blob, 0, skPaint, viewMatrix, text, byteLength, x, y, clipRect); |
+ |
+ // setup cache |
+ SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix); |
+ this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength, x, y, clipRect); |
+ SkGlyphCache::AttachCache(cache); |
+ |
this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, skPaint.getAlpha()); |
} |
void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, |
- const SkPaint& skPaint, |
+ SkGlyphCache* cache, const SkPaint& skPaint, |
const SkMatrix& viewMatrix, |
const char text[], size_t byteLength, |
SkScalar x, SkScalar y, const SkIRect& clipRect) { |
@@ -226,12 +296,6 @@ void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, |
SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
// Get GrFontScaler from cache |
- BitmapTextBlob::Run& run = blob->fRuns[runIndex]; |
- run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties, &viewMatrix, |
- false)); |
- run.fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
- const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor->data()); |
- SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc); |
GrFontScaler* fontScaler = GetGrFontScaler(cache); |
// transform our starting point |
@@ -303,8 +367,6 @@ void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, |
fx += glyph.fAdvanceX; |
fy += glyph.fAdvanceY; |
} |
- |
- SkGlyphCache::AttachCache(cache); |
} |
void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, |
@@ -313,20 +375,25 @@ void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, |
const char text[], size_t byteLength, |
const SkScalar pos[], int scalarsPerPosition, |
const SkPoint& offset, const SkIRect& regionClipBounds) { |
- SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); |
+ int glyphCount = skPaint.countText(text, byteLength); |
+ SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1)); |
blob->fStyle = skPaint.getStyle(); |
- blob->fRuns.push_back(); |
blob->fViewMatrix = viewMatrix; |
SkIRect clipRect; |
clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
- this->internalDrawPosText(blob, 0, skPaint, viewMatrix, text, byteLength, pos, |
+ |
+ // setup cache |
+ SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix); |
+ this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLength, pos, |
scalarsPerPosition, offset, clipRect); |
+ SkGlyphCache::AttachCache(cache); |
+ |
this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fSkPaint.getAlpha()); |
} |
void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runIndex, |
- const SkPaint& skPaint, |
+ SkGlyphCache* cache, const SkPaint& skPaint, |
const SkMatrix& viewMatrix, |
const char text[], size_t byteLength, |
const SkScalar pos[], int scalarsPerPosition, |
@@ -343,12 +410,6 @@ void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde |
SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
// Get GrFontScaler from cache |
- BitmapTextBlob::Run& run = blob->fRuns[runIndex]; |
- run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties, &viewMatrix, |
- false)); |
- run.fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
- const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor->data()); |
- SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc); |
GrFontScaler* fontScaler = GetGrFontScaler(cache); |
const char* stop = text + byteLength; |
@@ -487,7 +548,6 @@ void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde |
} |
} |
} |
- SkGlyphCache::AttachCache(cache); |
} |
static size_t get_vertex_stride(GrMaskFormat maskFormat) { |
@@ -540,13 +600,28 @@ void GrBitmapTextContextB::appendGlyph(BitmapTextBlob* blob, int runIndex, GrGly |
blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, vy)); |
return; |
} |
+ |
+ Run& run = blob->fRuns[runIndex]; |
+ |
GrMaskFormat format = glyph->fMaskFormat; |
- size_t vertexStride = get_vertex_stride(format); |
- BitmapTextBlob::Run& run = blob->fRuns[runIndex]; |
- int glyphIdx = run.fInfos[format].fGlyphIDs.count(); |
- *run.fInfos[format].fGlyphIDs.append() = packed; |
- run.fInfos[format].fVertices.append(static_cast<int>(vertexStride * kVerticesPerGlyph)); |
+ PerSubRunInfo* subRun = &run.fSubRunInfo.back(); |
+ if (run.fInitialized && subRun->fMaskFormat != format) { |
+ PerSubRunInfo* newSubRun = &run.fSubRunInfo.push_back(); |
+ newSubRun->fGlyphStartIndex = subRun->fGlyphEndIndex; |
+ newSubRun->fGlyphEndIndex = subRun->fGlyphEndIndex; |
+ |
+ newSubRun->fVertexStartIndex = subRun->fVertexEndIndex; |
+ newSubRun->fVertexEndIndex = subRun->fVertexEndIndex; |
+ |
+ subRun = newSubRun; |
+ } |
+ |
+ run.fInitialized = true; |
+ subRun->fMaskFormat = format; |
+ blob->fGlyphIDs[subRun->fGlyphEndIndex] = packed; |
+ |
+ size_t vertexStride = get_vertex_stride(format); |
SkRect r; |
r.fLeft = SkIntToScalar(x); |
@@ -558,8 +633,7 @@ void GrBitmapTextContextB::appendGlyph(BitmapTextBlob* blob, int runIndex, GrGly |
GrColor color = fPaint.getColor(); |
run.fColor = color; |
- intptr_t vertex = reinterpret_cast<intptr_t>(run.fInfos[format].fVertices.begin()); |
- vertex += vertexStride * glyphIdx * kVerticesPerGlyph; |
+ intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->fVertexEndIndex); |
// V0 |
SkPoint* position = reinterpret_cast<SkPoint*>(vertex); |
@@ -595,27 +669,32 @@ void GrBitmapTextContextB::appendGlyph(BitmapTextBlob* blob, int runIndex, GrGly |
SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); |
*colorPtr = color; |
} |
+ |
+ subRun->fGlyphEndIndex++; |
+ subRun->fVertexEndIndex += vertexStride * kVerticesPerGlyph; |
} |
class BitmapTextBatch : public GrBatch { |
public: |
typedef GrBitmapTextContextB::BitmapTextBlob Blob; |
typedef Blob::Run Run; |
- typedef Run::PerFormatInfo TextInfo; |
+ typedef Run::SubRunInfo TextInfo; |
struct Geometry { |
Geometry() {} |
Geometry(const Geometry& geometry) |
: fBlob(SkRef(geometry.fBlob.get())) |
, fRun(geometry.fRun) |
+ , fSubRun(geometry.fSubRun) |
, fColor(geometry.fColor) {} |
SkAutoTUnref<Blob> fBlob; |
int fRun; |
+ int fSubRun; |
GrColor fColor; |
}; |
static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat maskFormat, |
- GrBatchFontCache* fontCache) { |
- return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, fontCache)); |
+ int glyphCount, GrBatchFontCache* fontCache) { |
+ return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, glyphCount, fontCache)); |
} |
const char* name() const override { return "BitmapTextBatch"; } |
@@ -718,12 +797,12 @@ public: |
Geometry& args = fGeoData[i]; |
Blob* blob = args.fBlob; |
Run& run = blob->fRuns[args.fRun]; |
- TextInfo& info = run.fInfos[fMaskFormat]; |
+ TextInfo& info = run.fSubRunInfo[args.fSubRun]; |
uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); |
bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen; |
bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor; |
- int glyphCount = info.fGlyphIDs.count(); |
+ int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
// We regenerate both texture coords and colors in the blob itself, and update the |
// atlas generation. If we don't end up purging any unused plots, we can avoid |
@@ -741,13 +820,13 @@ public: |
GrBatchTextStrike* strike = NULL; |
bool brokenRun = false; |
if (regenerateTextureCoords) { |
- desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor->data()); |
+ desc = run.fDescriptor.getDesc(); |
cache = SkGlyphCache::DetachCache(run.fTypeface, desc); |
scaler = GrTextContext::GetGrFontScaler(cache); |
strike = fFontCache->getStrike(scaler); |
} |
for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { |
- GrGlyph::PackedID glyphID = info.fGlyphIDs[glyphIdx]; |
+ GrGlyph::PackedID glyphID = blob->fGlyphIDs[glyphIdx + info.fGlyphStartIndex]; |
if (regenerateTextureCoords) { |
// Upload the glyph only if needed |
@@ -771,7 +850,8 @@ public: |
// Texture coords are the last vertex attribute so we get a pointer to the |
// first one and then map with stride in regenerateTextureCoords |
- intptr_t vertex = reinterpret_cast<intptr_t>(info.fVertices.begin()); |
+ intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices); |
+ vertex += info.fVertexStartIndex; |
vertex += vertexStride * glyphIdx * kVerticesPerGlyph; |
vertex += vertexStride - sizeof(SkIPoint16); |
@@ -779,7 +859,8 @@ public: |
} |
if (regenerateColors) { |
- intptr_t vertex = reinterpret_cast<intptr_t>(info.fVertices.begin()); |
+ intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices); |
+ vertex += info.fVertexStartIndex; |
vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint); |
this->regenerateColors(vertex, vertexStride, args.fColor); |
} |
@@ -797,8 +878,8 @@ public: |
} |
// now copy all vertices |
- int byteCount = info.fVertices.count(); |
- memcpy(currVertex, info.fVertices.begin(), byteCount); |
+ size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex; |
+ memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCount); |
currVertex += byteCount; |
} |
@@ -810,7 +891,7 @@ public: |
private: |
BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFormat, |
- GrBatchFontCache* fontCache) |
+ int glyphCount, GrBatchFontCache* fontCache) |
: fMaskFormat(maskFormat) |
, fPixelConfig(fontCache->getPixelConfig(maskFormat)) |
, fFontCache(fontCache) { |
@@ -818,8 +899,7 @@ private: |
fGeoData.push_back(geometry); |
fBatch.fColor = color; |
fBatch.fViewMatrix = geometry.fBlob->fViewMatrix; |
- int numGlyphs = geometry.fBlob->fRuns[geometry.fRun].fInfos[maskFormat].fGlyphIDs.count(); |
- fBatch.fNumGlyphs = numGlyphs; |
+ fBatch.fNumGlyphs = glyphCount; |
} |
void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexStride) { |
@@ -932,27 +1012,6 @@ private: |
GrBatchFontCache* fFontCache; |
}; |
-void GrBitmapTextContextB::flushSubRun(GrDrawTarget* target, BitmapTextBlob* blob, int i, |
- GrPipelineBuilder* pipelineBuilder, GrMaskFormat format, |
- GrColor color, int paintAlpha) { |
- if (0 == blob->fRuns[i].fInfos[format].fGlyphIDs.count()) { |
- return; |
- } |
- |
- if (kARGB_GrMaskFormat == format) { |
- color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha); |
- } |
- |
- BitmapTextBatch::Geometry geometry; |
- geometry.fBlob.reset(SkRef(blob)); |
- geometry.fRun = i; |
- geometry.fColor = color; |
- SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format, |
- fContext->getBatchFontCache())); |
- |
- target->drawBatch(pipelineBuilder, batch, &blob->fRuns[i].fVertexBounds); |
-} |
- |
void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrRenderTarget* rt, |
const GrPaint& paint, const GrClip& clip, |
const SkMatrix& viewMatrix, int paintAlpha) { |
@@ -960,10 +1019,29 @@ void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR |
pipelineBuilder.setFromPaint(paint, rt, clip); |
GrColor color = paint.getColor(); |
- for (int i = 0; i < blob->fRuns.count(); i++) { |
- this->flushSubRun(target, blob, i, &pipelineBuilder, kA8_GrMaskFormat, color, paintAlpha); |
- this->flushSubRun(target, blob, i, &pipelineBuilder, kA565_GrMaskFormat, color, paintAlpha); |
- this->flushSubRun(target, blob, i, &pipelineBuilder, kARGB_GrMaskFormat, color, paintAlpha); |
+ for (uint32_t run = 0; run < blob->fRunCount; run++) { |
+ for (int subRun = 0; subRun < blob->fRuns[run].fSubRunInfo.count(); subRun++) { |
+ PerSubRunInfo& info = blob->fRuns[run].fSubRunInfo[subRun]; |
+ int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
+ if (0 == glyphCount) { |
+ continue; |
+ } |
+ |
+ GrMaskFormat format = info.fMaskFormat; |
+ if (kARGB_GrMaskFormat == format) { |
+ color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha); |
+ } |
+ |
+ BitmapTextBatch::Geometry geometry; |
+ geometry.fBlob.reset(SkRef(blob)); |
+ geometry.fRun = run; |
+ geometry.fSubRun = subRun; |
+ geometry.fColor = color; |
+ SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format, glyphCount, |
+ fContext->getBatchFontCache())); |
+ |
+ target->drawBatch(&pipelineBuilder, batch, &blob->fRuns[run].fVertexBounds); |
+ } |
} |
// Now flush big glyphs |