void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob,
                                                  const SkPaint& skPaint) {
    fCpuMemorySize = sizeof(TextBlob);
    SkPaint runPaint(skPaint);
    for (SkTextBlobRunIterator iter(skBlob); !iter.done(); iter.next()) {
        iter.applyFontToPaint(&runPaint); // No need to re-seed the paint.
        if (runPaint.getTextSize() <= 0) {
            continue;
        }
        TextRun* run = this->addToTail(runPaint);

        const char* text = reinterpret_cast<const char*>(iter.glyphs());
        size_t byteLength = sizeof(uint16_t) * iter.glyphCount();
        const SkPoint& runOffset = iter.offset();

        switch (iter.positioning()) {
            case SkTextBlob::kDefault_Positioning:
                run->setText(text, byteLength, runOffset.fX, runOffset.fY);
                break;
            case SkTextBlob::kHorizontal_Positioning:
                run->setPosText(text, byteLength, iter.pos(), 1, SkPoint::Make(0, runOffset.fY));
                break;
            case SkTextBlob::kFull_Positioning:
                run->setPosText(text, byteLength, iter.pos(), 2, SkPoint::Make(0, 0));
                break;
        }

        fCpuMemorySize += run->computeSizeInCache();
    }
}
void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob, const SkPaint& skPaint,
                                                  GrContext* ctx, const SkSurfaceProps* props) {
    fCpuMemorySize = sizeof(TextBlob);
    SkPaint runPaint(skPaint);
    for (SkTextBlob::RunIterator 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));

        const char* text = reinterpret_cast<const char*>(iter.glyphs());
        size_t byteLength = sizeof(uint16_t) * iter.glyphCount();
        const SkPoint& runOffset = iter.offset();

        switch (iter.positioning()) {
            case SkTextBlob::kDefault_Positioning:
                run->setText(text, byteLength, runOffset.fX, runOffset.fY, ctx, props);
                break;
            case SkTextBlob::kHorizontal_Positioning:
                run->setPosText(text, byteLength, iter.pos(), 1, SkPoint::Make(0, runOffset.fY),
                                ctx, props);
                break;
            case SkTextBlob::kFull_Positioning:
                run->setPosText(text, byteLength, iter.pos(), 2, SkPoint::Make(0, 0), ctx, props);
                break;
        }

        fCpuMemorySize += run->cpuMemorySize();
    }
}
void GrStencilAndCoverTextContext::uncachedDrawTextBlob(GrContext* context,
                                                        GrRenderTargetContext* rtc,
                                                        const GrClip& clip,
                                                        const SkPaint& skPaint,
                                                        const SkMatrix& viewMatrix,
                                                        const SkSurfaceProps& props,
                                                        const SkTextBlob* blob,
                                                        SkScalar x, SkScalar y,
                                                        SkDrawFilter* drawFilter,
                                                        const SkIRect& clipBounds) {
    GrTextUtils::Paint paint(&skPaint);
    GrTextUtils::RunPaint runPaint(&paint, drawFilter, props);
    SkTextBlobRunIterator it(blob);
    for (;!it.done(); it.next()) {
        if (!runPaint.modifyForRun(it)) {
            continue;
        }
        size_t textLen = it.glyphCount() * sizeof(uint16_t);
        const SkPoint& offset = it.offset();

        switch (it.positioning()) {
            case SkTextBlob::kDefault_Positioning:
                this->drawText(context, rtc, clip, runPaint, viewMatrix, props,
                               (const char*)it.glyphs(), textLen, x + offset.x(), y + offset.y(),
                               clipBounds);
                break;
            case SkTextBlob::kHorizontal_Positioning:
                this->drawPosText(context, rtc, clip, runPaint, viewMatrix, props,
                                  (const char*)it.glyphs(), textLen, it.pos(), 1,
                                  SkPoint::Make(x, y + offset.y()), clipBounds);
                break;
            case SkTextBlob::kFull_Positioning:
                this->drawPosText(context, rtc, clip, runPaint, viewMatrix, props,
                                  (const char*)it.glyphs(), textLen, it.pos(), 2,
                                  SkPoint::Make(x, y), clipBounds);
                break;
        }
    }
}