diff options
-rw-r--r-- | src/gpu/GrAtlasTextContext.cpp | 41 | ||||
-rw-r--r-- | src/gpu/GrAtlasTextContext.h | 29 |
2 files changed, 44 insertions, 26 deletions
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index 34c691a9d7..aac3e3311f 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -545,7 +545,8 @@ inline void GrAtlasTextContext::initDistanceFieldPaint(SkPaint* skPaint, SkScala skPaint->setSubpixelText(true); } -inline void GrAtlasTextContext::fallbackDrawPosText(GrRenderTarget* rt, const GrClip& clip, +inline void GrAtlasTextContext::fallbackDrawPosText(BitmapTextBlob* blob, + GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, const SkPaint& skPaint, const SkMatrix& viewMatrix, @@ -554,20 +555,18 @@ inline void GrAtlasTextContext::fallbackDrawPosText(GrRenderTarget* rt, const Gr int scalarsPerPosition, const SkPoint& offset, const SkIRect& clipRect) { - int glyphCount = fallbackTxt.count(); - SkASSERT(glyphCount); - // TODO currently we have to create a whole new blob for fallback text. This is because - // they have a different descriptor and we currently only have one descriptor per run. - // We should fix this and allow an override descriptor on each subrun - SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTextVASize)); - blob->fViewMatrix = viewMatrix; - - SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMatrix, false); + SkASSERT(fallbackTxt.count()); + Run& run = blob->fRuns[0]; + PerSubRunInfo& subRun = run.fSubRunInfo.push_back(); + subRun.fOverrideDescriptor.reset(SkNEW(SkAutoDescriptor)); + skPaint.getScalerContextDescriptor(subRun.fOverrideDescriptor, + &fDeviceProperties, &viewMatrix, false); + SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, + subRun.fOverrideDescriptor->getDesc()); this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, fallbackTxt.begin(), fallbackTxt.count(), fallbackPos.begin(), scalarsPerPosition, offset, clipRect); SkGlyphCache::AttachCache(cache); - this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); } inline GrAtlasTextContext::BitmapTextBlob* @@ -610,11 +609,11 @@ void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, byteLength, x, y, clipRect, textRatio, &fallbackTxt, &fallbackPos, &offset, skPaint); SkGlyphCache::AttachCache(cache); - this->flush(fContext->getTextTarget(), blob, rt, dfPaint, paint, clip); if (fallbackTxt.count()) { - this->fallbackDrawPosText(rt, clip, paint, skPaint, viewMatrix, fallbackTxt, + this->fallbackDrawPosText(blob, rt, clip, paint, skPaint, viewMatrix, fallbackTxt, fallbackPos, 2, offset, clipRect); } + this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); } else { SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTextVASize)); blob->fViewMatrix = viewMatrix; @@ -651,11 +650,11 @@ void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, byteLength, pos, scalarsPerPosition, offset, clipRect, textRatio, &fallbackTxt, &fallbackPos); SkGlyphCache::AttachCache(cache); - this->flush(fContext->getTextTarget(), blob, rt, dfPaint, paint, clip); if (fallbackTxt.count()) { - this->fallbackDrawPosText(rt, clip, paint, skPaint, viewMatrix, fallbackTxt, + this->fallbackDrawPosText(blob, rt, clip, paint, skPaint, viewMatrix, fallbackTxt, fallbackPos, scalarsPerPosition, offset, clipRect); } + this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); } else { SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTextVASize)); blob->fViewMatrix = viewMatrix; @@ -1134,14 +1133,7 @@ void GrAtlasTextContext::bmpAppendGlyph(BitmapTextBlob* blob, int runIndex, 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; + subRun = &run.fSubRunInfo.push_back(); } run.fInitialized = true; @@ -1475,7 +1467,8 @@ public: bool brokenRun = false; if (regenerateTextureCoords) { info.fBulkUseToken.reset(); - desc = run.fDescriptor.getDesc(); + desc = info.fOverrideDescriptor ? info.fOverrideDescriptor->getDesc() : + run.fDescriptor.getDesc(); cache = SkGlyphCache::DetachCache(run.fTypeface, desc); scaler = GrTextContext::GetGrFontScaler(cache); strike = fFontCache->getStrike(scaler); diff --git a/src/gpu/GrAtlasTextContext.h b/src/gpu/GrAtlasTextContext.h index 6fd35538f6..cf2ba6bcc2 100644 --- a/src/gpu/GrAtlasTextContext.h +++ b/src/gpu/GrAtlasTextContext.h @@ -114,6 +114,14 @@ private: // distance field properties bool fDrawAsDistanceFields; bool fUseLCDText; + // Distance field text cannot draw coloremoji, and so has to fall back. However, + // though the distance field text and the coloremoji may share the same run, they + // will have different descriptors. If fOverrideDescriptor is non-NULL, then it + // will be used in place of the run's descriptor to regen texture coords + // TODO we could have a descriptor cache, it would reduce the size of these blobs + // significantly, and then the subrun could just have a refed pointer to the + // correct descriptor. + SkAutoTDelete<SkAutoDescriptor> fOverrideDescriptor; }; class SubRunInfoArray { @@ -121,8 +129,16 @@ private: SubRunInfoArray() : fSubRunCount(0) , fSubRunAllocation(kMinSubRuns) { + SK_COMPILE_ASSERT(kMinSubRuns > 0, insufficient_subrun_allocation); + // We always seed with one here, so we can assume a valid subrun during + // push_back fPtr = reinterpret_cast<SubRunInfo*>(fSubRunStorage.get()); - this->push_back(); + SkNEW_PLACEMENT(&fPtr[fSubRunCount++], SubRunInfo); + } + ~SubRunInfoArray() { + for (int i = 0; i < fSubRunCount; i++) { + fPtr[i].~SubRunInfo(); + } } int count() const { return fSubRunCount; } @@ -134,6 +150,15 @@ private: fPtr = reinterpret_cast<SubRunInfo*>(fSubRunStorage.get()); } SkNEW_PLACEMENT(&fPtr[fSubRunCount], SubRunInfo); + + // Forward glyph / vertex information to seed the new sub run + SubRunInfo& newSubRun = fPtr[fSubRunCount]; + SubRunInfo& prevSubRun = fPtr[fSubRunCount - 1]; + newSubRun.fGlyphStartIndex = prevSubRun.fGlyphEndIndex; + newSubRun.fGlyphEndIndex = prevSubRun.fGlyphEndIndex; + + newSubRun.fVertexStartIndex = prevSubRun.fVertexEndIndex; + newSubRun.fVertexEndIndex = prevSubRun.fVertexEndIndex; return fPtr[fSubRunCount++]; } SubRunInfo& operator[](int index) { @@ -268,7 +293,7 @@ private: const GrPaint&, const GrClip&); // A helper for drawing BitmapText in a run of distance fields - inline void fallbackDrawPosText(GrRenderTarget*, const GrClip&, + inline void fallbackDrawPosText(BitmapTextBlob*, GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const SkTDArray<char>& fallbackTxt, |