| Index: src/gpu/GrStencilAndCoverTextContext.cpp
|
| diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
|
| index 9c0fc2a8ec2a2fe10a5bb1e2930224b1dfea736c..9f394f901875364ff3fc59570716a215410f86f1 100644
|
| --- a/src/gpu/GrStencilAndCoverTextContext.cpp
|
| +++ b/src/gpu/GrStencilAndCoverTextContext.cpp
|
| @@ -25,9 +25,7 @@
|
|
|
| GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context,
|
| const SkSurfaceProps& surfaceProps)
|
| - : INHERITED(context, surfaceProps)
|
| - , fDraw(nullptr)
|
| - , fStroke(SkStrokeRec::kFill_InitStyle) {
|
| + : INHERITED(context, surfaceProps) {
|
| }
|
|
|
| GrStencilAndCoverTextContext*
|
| @@ -71,20 +69,103 @@ void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget*
|
| size_t byteLength,
|
| SkScalar x, SkScalar y,
|
| const SkIRect& regionClipBounds) {
|
| - SkASSERT(byteLength == 0 || text != nullptr);
|
| + TextRun run(skPaint);
|
| + run.setText(text, byteLength, x, y, fContext, &fSurfaceProps);
|
| + run.draw(dc, rt, clip, paint, viewMatrix, regionClipBounds, fFallbackTextContext, skPaint);
|
| +}
|
| +
|
| +void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarget* rt,
|
| + const GrClip& clip,
|
| + const GrPaint& paint,
|
| + const SkPaint& skPaint,
|
| + const SkMatrix& viewMatrix,
|
| + const char text[],
|
| + size_t byteLength,
|
| + const SkScalar pos[],
|
| + int scalarsPerPosition,
|
| + const SkPoint& offset,
|
| + const SkIRect& regionClipBounds) {
|
| + TextRun run(skPaint);
|
| + run.setPosText(text, byteLength, pos, scalarsPerPosition, offset, fContext, &fSurfaceProps);
|
| + run.draw(dc, rt, clip, paint, viewMatrix, regionClipBounds, fFallbackTextContext, skPaint);
|
| +}
|
|
|
| - if (text == nullptr || byteLength == 0 /*|| fRC->isEmpty()*/) {
|
| - return;
|
| +////////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
|
| + : fStroke(fontAndStroke),
|
| + fFont(fontAndStroke) {
|
| + SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
|
| +
|
| + // Setting to "fill" ensures that no strokes get baked into font outlines. (We use the GPU path
|
| + // rendering API for stroking).
|
| + fFont.setStyle(SkPaint::kFill_Style);
|
| +
|
| + if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle()) {
|
| + // Instead of letting fake bold get baked into the glyph outlines, do it with GPU stroke.
|
| + SkScalar fakeBoldScale = SkScalarInterpFunc(fFont.getTextSize(),
|
| + kStdFakeBoldInterpKeys,
|
| + kStdFakeBoldInterpValues,
|
| + kStdFakeBoldInterpLength);
|
| + SkScalar extra = SkScalarMul(fFont.getTextSize(), fakeBoldScale);
|
| + fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extra : extra,
|
| + true /*strokeAndFill*/);
|
| +
|
| + fFont.setFakeBoldText(false);
|
| }
|
|
|
| - this->init(rt, clip, paint, skPaint, byteLength, viewMatrix, regionClipBounds);
|
| + if (!fFont.getPathEffect() && !fStroke.isDashed()) {
|
| + // We can draw the glyphs from canonically sized paths.
|
| + fTextRatio = fFont.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
|
| + fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fFont.getTextSize();
|
|
|
| - SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
|
| + // Compensate for the glyphs being scaled by fTextRatio.
|
| + if (!fStroke.isFillStyle()) {
|
| + fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio,
|
| + SkStrokeRec::kStrokeAndFill_Style == fStroke.getStyle());
|
| + }
|
| +
|
| + fFont.setLinearText(true);
|
| + fFont.setLCDRenderText(false);
|
| + fFont.setAutohinted(false);
|
| + fFont.setHinting(SkPaint::kNo_Hinting);
|
| + fFont.setSubpixelText(true);
|
| + fFont.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
|
| +
|
| + fUsingRawGlyphPaths = SK_Scalar1 == fFont.getTextScaleX() &&
|
| + 0 == fFont.getTextSkewX() &&
|
| + !fFont.isFakeBoldText() &&
|
| + !fFont.isVerticalText();
|
| + } else {
|
| + fTextRatio = fTextInverseRatio = 1.0f;
|
| + fUsingRawGlyphPaths = false;
|
| + }
|
| +
|
| + // When drawing from canonically sized paths, the actual local coords are fTextRatio * coords.
|
| + fLocalMatrix.setScale(fTextRatio, fTextRatio);
|
| +}
|
| +
|
| +GrStencilAndCoverTextContext::TextRun::~TextRun() {
|
| +}
|
| +
|
| +void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t byteLength,
|
| + SkScalar x, SkScalar y, GrContext* ctx,
|
| + const SkSurfaceProps* surfaceProps) {
|
| + SkASSERT(byteLength == 0 || text != nullptr);
|
| +
|
| + SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
|
| + SkGlyphCache* glyphCache = autoGlyphCache.getCache();
|
| +
|
| + fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
|
| + GrPathRendering::kTranslate_PathTransformType,
|
| + fFont.countText(text, byteLength)));
|
| +
|
| + SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
|
|
|
| const char* stop = text + byteLength;
|
|
|
| // Measure first if needed.
|
| - if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
|
| + if (fFont.getTextAlign() != SkPaint::kLeft_Align) {
|
| SkFixed stopX = 0;
|
| SkFixed stopY = 0;
|
|
|
| @@ -92,7 +173,7 @@ void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget*
|
| while (textPtr < stop) {
|
| // We don't need x, y here, since all subpixel variants will have the
|
| // same advance.
|
| - const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &textPtr, 0, 0);
|
| + const SkGlyph& glyph = glyphCacheProc(glyphCache, &textPtr, 0, 0);
|
|
|
| stopX += glyph.fAdvanceX;
|
| stopY += glyph.fAdvanceY;
|
| @@ -102,7 +183,7 @@ void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget*
|
| SkScalar alignX = SkFixedToScalar(stopX) * fTextRatio;
|
| SkScalar alignY = SkFixedToScalar(stopY) * fTextRatio;
|
|
|
| - if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
|
| + if (fFont.getTextAlign() == SkPaint::kCenter_Align) {
|
| alignX = SkScalarHalf(alignX);
|
| alignY = SkScalarHalf(alignY);
|
| }
|
| @@ -118,7 +199,7 @@ void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget*
|
| SkFixed fx = SkScalarToFixed(x);
|
| SkFixed fy = SkScalarToFixed(y);
|
| while (text < stop) {
|
| - const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
|
| + 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)));
|
| @@ -127,39 +208,30 @@ void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget*
|
| fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio);
|
| fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
|
| }
|
| -
|
| - this->finish(dc);
|
| }
|
|
|
| -void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarget* rt,
|
| - const GrClip& clip,
|
| - const GrPaint& paint,
|
| - const SkPaint& skPaint,
|
| - const SkMatrix& viewMatrix,
|
| - const char text[],
|
| - size_t byteLength,
|
| - const SkScalar pos[],
|
| - int scalarsPerPosition,
|
| - const SkPoint& offset,
|
| - const SkIRect& regionClipBounds) {
|
| +void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
|
| + const SkScalar pos[], int scalarsPerPosition,
|
| + const SkPoint& offset, GrContext* ctx,
|
| + const SkSurfaceProps* surfaceProps) {
|
| SkASSERT(byteLength == 0 || text != nullptr);
|
| SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
|
|
|
| - // nothing to draw
|
| - if (text == nullptr || byteLength == 0/* || fRC->isEmpty()*/) {
|
| - return;
|
| - }
|
| + SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
|
| + SkGlyphCache* glyphCache = autoGlyphCache.getCache();
|
|
|
| - this->init(rt, clip, paint, skPaint, byteLength, viewMatrix, regionClipBounds);
|
| + fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
|
| + GrPathRendering::kTranslate_PathTransformType,
|
| + fFont.countText(text, byteLength)));
|
|
|
| - SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
|
| + SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
|
|
|
| const char* stop = text + byteLength;
|
|
|
| SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
|
| - SkTextAlignProc alignProc(fSkPaint.getTextAlign());
|
| + SkTextAlignProc alignProc(fFont.getTextAlign());
|
| while (text < stop) {
|
| - const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
|
| + const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
|
| if (glyph.fWidth) {
|
| SkPoint tmsLoc;
|
| tmsProc(pos, &tmsLoc);
|
| @@ -170,23 +242,22 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarg
|
| }
|
| pos += scalarsPerPosition;
|
| }
|
| -
|
| - this->finish(dc);
|
| }
|
|
|
| -static GrPathRange* get_gr_glyphs(GrContext* ctx,
|
| - const SkTypeface* typeface,
|
| - const SkDescriptor* desc,
|
| - const GrStrokeInfo& stroke) {
|
| +GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx,
|
| + SkGlyphCache* glyphCache) {
|
| + SkTypeface* typeface = fUsingRawGlyphPaths ? fFont.getTypeface()
|
| + : glyphCache->getScalerContext()->getTypeface();
|
| + const SkDescriptor* desc = fUsingRawGlyphPaths ? nullptr : &glyphCache->getDescriptor();
|
|
|
| static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDomain();
|
| - int strokeDataCount = stroke.computeUniqueKeyFragmentData32Cnt();
|
| + int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt();
|
| GrUniqueKey glyphKey;
|
| GrUniqueKey::Builder builder(&glyphKey, kPathGlyphDomain, 2 + strokeDataCount);
|
| reinterpret_cast<uint32_t&>(builder[0]) = desc ? desc->getChecksum() : 0;
|
| reinterpret_cast<uint32_t&>(builder[1]) = typeface ? typeface->uniqueID() : 0;
|
| if (strokeDataCount > 0) {
|
| - stroke.asUniqueKeyFragment(&builder[2]);
|
| + fStroke.asUniqueKeyFragment(&builder[2]);
|
| }
|
| builder.finish();
|
|
|
| @@ -194,7 +265,7 @@ static GrPathRange* get_gr_glyphs(GrContext* ctx,
|
| static_cast<GrPathRange*>(
|
| ctx->resourceProvider()->findAndRefResourceByUniqueKey(glyphKey)));
|
| if (nullptr == glyphs) {
|
| - glyphs.reset(ctx->resourceProvider()->createGlyphs(typeface, desc, stroke));
|
| + glyphs.reset(ctx->resourceProvider()->createGlyphs(typeface, desc, fStroke));
|
| ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs);
|
| } else {
|
| SkASSERT(nullptr == desc || glyphs->isEqualTo(*desc));
|
| @@ -203,107 +274,32 @@ static GrPathRange* get_gr_glyphs(GrContext* ctx,
|
| return glyphs.detach();
|
| }
|
|
|
| -void GrStencilAndCoverTextContext::init(GrRenderTarget* rt,
|
| - const GrClip& clip,
|
| - const GrPaint& paint,
|
| - const SkPaint& skPaint,
|
| - size_t textByteLength,
|
| - const SkMatrix& viewMatrix,
|
| - const SkIRect& regionClipBounds) {
|
| - fClip = clip;
|
| -
|
| - fRenderTarget.reset(SkRef(rt));
|
| -
|
| - fRegionClipBounds = regionClipBounds;
|
| - fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect);
|
| -
|
| - fPaint = paint;
|
| - fSkPaint = skPaint;
|
| -
|
| - // Don't bake strokes into the glyph outlines. We will stroke the glyphs using the GPU instead.
|
| - fStroke = GrStrokeInfo(fSkPaint);
|
| - fSkPaint.setStyle(SkPaint::kFill_Style);
|
| -
|
| - SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
|
| -
|
| - if (fSkPaint.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle()) {
|
| - // Instead of baking fake bold into the glyph outlines, do it with the GPU stroke.
|
| - SkScalar fakeBoldScale = SkScalarInterpFunc(fSkPaint.getTextSize(),
|
| - kStdFakeBoldInterpKeys,
|
| - kStdFakeBoldInterpValues,
|
| - kStdFakeBoldInterpLength);
|
| - SkScalar extra = SkScalarMul(fSkPaint.getTextSize(), fakeBoldScale);
|
| - fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extra : extra,
|
| - true /*strokeAndFill*/);
|
| -
|
| - fSkPaint.setFakeBoldText(false);
|
| - }
|
| -
|
| - bool canUseRawPaths;
|
| - if (!fStroke.isDashed()) {
|
| - // We can draw the glyphs from canonically sized paths.
|
| - fTextRatio = fSkPaint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
|
| - fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fSkPaint.getTextSize();
|
| -
|
| - // Compensate for the glyphs being scaled by fTextRatio.
|
| - if (!fStroke.isFillStyle()) {
|
| - fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio,
|
| - SkStrokeRec::kStrokeAndFill_Style == fStroke.getStyle());
|
| - }
|
| -
|
| - fSkPaint.setLinearText(true);
|
| - fSkPaint.setLCDRenderText(false);
|
| - fSkPaint.setAutohinted(false);
|
| - fSkPaint.setHinting(SkPaint::kNo_Hinting);
|
| - fSkPaint.setSubpixelText(true);
|
| - fSkPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
|
| -
|
| - canUseRawPaths = SK_Scalar1 == fSkPaint.getTextScaleX() &&
|
| - 0 == fSkPaint.getTextSkewX() &&
|
| - !fSkPaint.isFakeBoldText() &&
|
| - !fSkPaint.isVerticalText();
|
| - } else {
|
| - fTextRatio = fTextInverseRatio = 1.0f;
|
| - canUseRawPaths = false;
|
| - }
|
| -
|
| - fViewMatrix = viewMatrix;
|
| - fViewMatrix.preScale(fTextRatio, fTextRatio);
|
| - fLocalMatrix.setScale(fTextRatio, fTextRatio);
|
| -
|
| - fGlyphCache = fSkPaint.detachCache(&fSurfaceProps, nullptr, true /*ignoreGamma*/);
|
| - fGlyphs = canUseRawPaths ?
|
| - get_gr_glyphs(fContext, fSkPaint.getTypeface(), nullptr, fStroke) :
|
| - get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTypeface(),
|
| - &fGlyphCache->getDescriptor(), fStroke);
|
| -}
|
| -
|
| -inline void GrStencilAndCoverTextContext::appendGlyph(const SkGlyph& glyph, const SkPoint& pos) {
|
| +inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& glyph,
|
| + const SkPoint& pos) {
|
| // Stick the glyphs we can't draw into the fallback arrays.
|
| if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
|
| fFallbackIndices.push_back(glyph.getGlyphID());
|
| fFallbackPositions.push_back(pos);
|
| } else {
|
| - // TODO: infer the reserve count from the text length.
|
| - if (!fDraw) {
|
| - fDraw = GrPathRangeDraw::Create(fGlyphs,
|
| - GrPathRendering::kTranslate_PathTransformType,
|
| - 64);
|
| - }
|
| float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * pos.y() };
|
| fDraw->append(glyph.getGlyphID(), translate);
|
| }
|
| }
|
|
|
| -void GrStencilAndCoverTextContext::flush(GrDrawContext* dc) {
|
| - if (fDraw) {
|
| - SkASSERT(fDraw->count());
|
| +void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
|
| + GrRenderTarget* rt,
|
| + const GrClip& clip,
|
| + const GrPaint& paint,
|
| + const SkMatrix& viewMatrix,
|
| + const SkIRect& regionClipBounds,
|
| + GrTextContext* fallbackTextContext,
|
| + const SkPaint& originalSkPaint) const {
|
| + SkASSERT(fDraw);
|
|
|
| - // We should only be flushing about once every run. However, if this impacts performance
|
| - // we could move the creation of the GrPipelineBuilder earlier.
|
| - GrPipelineBuilder pipelineBuilder(fPaint, fRenderTarget, fClip);
|
| - SkASSERT(fRenderTarget->isStencilBufferMultisampled() || !fPaint.isAntiAlias());
|
| - pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, fPaint.isAntiAlias());
|
| + if (fDraw->count()) {
|
| + GrPipelineBuilder pipelineBuilder(paint, rt, clip);
|
| + SkASSERT(rt->isStencilBufferMultisampled() || !paint.isAntiAlias());
|
| + pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, paint.isAntiAlias());
|
|
|
| GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
|
| kZero_StencilOp,
|
| @@ -315,50 +311,38 @@ void GrStencilAndCoverTextContext::flush(GrDrawContext* dc) {
|
|
|
| *pipelineBuilder.stencil() = kStencilPass;
|
|
|
| - dc->drawPathsFromRange(&pipelineBuilder, fViewMatrix, fLocalMatrix, fPaint.getColor(),
|
| - fDraw, GrPathRendering::kWinding_FillType);
|
| - fDraw->unref();
|
| - fDraw = nullptr;
|
| + SkMatrix drawMatrix(viewMatrix);
|
| + drawMatrix.preScale(fTextRatio, fTextRatio);
|
| +
|
| + dc->drawPathsFromRange(&pipelineBuilder, drawMatrix, fLocalMatrix, paint.getColor(), fDraw,
|
| + GrPathRendering::kWinding_FillType);
|
| }
|
|
|
| if (fFallbackIndices.count()) {
|
| SkASSERT(fFallbackPositions.count() == fFallbackIndices.count());
|
|
|
| - SkPaint fallbackSkPaint(fSkPaint);
|
| + enum { kPreservedFlags = SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag |
|
| + SkPaint::kLCDRenderText_Flag | SkPaint::kAutoHinting_Flag };
|
| +
|
| + 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(fSkPaint.getTextSize() * fTextRatio);
|
| -
|
| - SkMatrix fallbackMatrix(fViewMatrix);
|
| - fallbackMatrix.preScale(fTextInverseRatio, fTextInverseRatio);
|
| -
|
| - fFallbackTextContext->drawPosText(dc, fRenderTarget, fClip, fPaint, fallbackSkPaint,
|
| - fallbackMatrix, (char*)fFallbackIndices.begin(),
|
| - sizeof(uint16_t) * fFallbackIndices.count(),
|
| - fFallbackPositions[0].asScalars(), 2, SkPoint::Make(0, 0),
|
| - fRegionClipBounds);
|
| - fFallbackIndices.reset();
|
| - fFallbackPositions.reset();
|
| - }
|
| -}
|
| -
|
| -void GrStencilAndCoverTextContext::finish(GrDrawContext* dc) {
|
| - this->flush(dc);
|
| + fallbackSkPaint.setTextSize(fFont.getTextSize() * fTextRatio);
|
|
|
| - SkASSERT(!fDraw);
|
| - SkASSERT(!fFallbackIndices.count());
|
| - SkASSERT(!fFallbackPositions.count());
|
| -
|
| - fGlyphs->unref();
|
| - fGlyphs = nullptr;
|
| -
|
| - SkGlyphCache::AttachCache(fGlyphCache);
|
| - fGlyphCache = nullptr;
|
| + 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);
|
| + }
|
| }
|
|
|