| Index: src/gpu/GrBitmapTextContext.cpp
 | 
| diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
 | 
| deleted file mode 100755
 | 
| index efce516b79789f245e548822c9440da1413e8894..0000000000000000000000000000000000000000
 | 
| --- a/src/gpu/GrBitmapTextContext.cpp
 | 
| +++ /dev/null
 | 
| @@ -1,647 +0,0 @@
 | 
| -/*
 | 
| - * Copyright 2013 Google Inc.
 | 
| - *
 | 
| - * Use of this source code is governed by a BSD-style license that can be
 | 
| - * found in the LICENSE file.
 | 
| - */
 | 
| -#include "GrBitmapTextContext.h"
 | 
| -
 | 
| -#include "GrAtlas.h"
 | 
| -#include "GrBatch.h"
 | 
| -#include "GrBatchFontCache.h"
 | 
| -#include "GrBatchTarget.h"
 | 
| -#include "GrDefaultGeoProcFactory.h"
 | 
| -#include "GrDrawTarget.h"
 | 
| -#include "GrFontCache.h"
 | 
| -#include "GrFontScaler.h"
 | 
| -#include "GrIndexBuffer.h"
 | 
| -#include "GrStrokeInfo.h"
 | 
| -#include "GrTexturePriv.h"
 | 
| -
 | 
| -#include "SkAutoKern.h"
 | 
| -#include "SkColorPriv.h"
 | 
| -#include "SkDraw.h"
 | 
| -#include "SkDrawFilter.h"
 | 
| -#include "SkDrawProcs.h"
 | 
| -#include "SkGlyphCache.h"
 | 
| -#include "SkGpuDevice.h"
 | 
| -#include "SkGr.h"
 | 
| -#include "SkPath.h"
 | 
| -#include "SkRTConf.h"
 | 
| -#include "SkStrokeRec.h"
 | 
| -#include "SkTextBlob.h"
 | 
| -#include "SkTextMapStateProc.h"
 | 
| -
 | 
| -#include "effects/GrBitmapTextGeoProc.h"
 | 
| -#include "effects/GrSimpleTextureEffect.h"
 | 
| -
 | 
| -SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
 | 
| -                "Dump the contents of the font cache before every purge.");
 | 
| -
 | 
| -namespace {
 | 
| -static const size_t kLCDTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16);
 | 
| -
 | 
| -// position + local coord
 | 
| -static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16);
 | 
| -
 | 
| -static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof(SkIPoint16);
 | 
| -
 | 
| -static const int kVerticesPerGlyph = 4;
 | 
| -static const int kIndicesPerGlyph = 6;
 | 
| -
 | 
| -static size_t get_vertex_stride(GrMaskFormat maskFormat) {
 | 
| -    switch (maskFormat) {
 | 
| -        case kA8_GrMaskFormat:
 | 
| -            return kGrayTextVASize;
 | 
| -        case kARGB_GrMaskFormat:
 | 
| -            return kColorTextVASize;
 | 
| -        default:
 | 
| -            return kLCDTextVASize;
 | 
| -    }
 | 
| -}
 | 
| -
 | 
| -};
 | 
| -
 | 
| -GrBitmapTextContext::GrBitmapTextContext(GrContext* context,
 | 
| -                                         SkGpuDevice* gpuDevice,
 | 
| -                                         const SkDeviceProperties& properties)
 | 
| -    : GrTextContext(context, gpuDevice, properties) {
 | 
| -    fStrike = NULL;
 | 
| -
 | 
| -    fCurrTexture = NULL;
 | 
| -    fEffectTextureUniqueID = SK_InvalidUniqueID;
 | 
| -
 | 
| -    fVertices = NULL;
 | 
| -    fCurrVertex = 0;
 | 
| -    fAllocVertexCount = 0;
 | 
| -    fTotalVertexCount = 0;
 | 
| -
 | 
| -    fVertexBounds.setLargestInverted();
 | 
| -}
 | 
| -
 | 
| -GrBitmapTextContext* GrBitmapTextContext::Create(GrContext* context,
 | 
| -                                                 SkGpuDevice* gpuDevice,
 | 
| -                                                 const SkDeviceProperties& props) {
 | 
| -    return SkNEW_ARGS(GrBitmapTextContext, (context, gpuDevice, props));
 | 
| -}
 | 
| -
 | 
| -bool GrBitmapTextContext::canDraw(const GrRenderTarget* rt,
 | 
| -                                  const GrClip& clip,
 | 
| -                                  const GrPaint& paint,
 | 
| -                                  const SkPaint& skPaint,
 | 
| -                                  const SkMatrix& viewMatrix) {
 | 
| -    return !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix);
 | 
| -}
 | 
| -
 | 
| -inline void GrBitmapTextContext::init(GrRenderTarget* rt, const GrClip& clip,
 | 
| -                                      const GrPaint& paint, const SkPaint& skPaint,
 | 
| -                                      const SkIRect& regionClipBounds) {
 | 
| -    GrTextContext::init(rt, clip, paint, skPaint, regionClipBounds);
 | 
| -
 | 
| -    fStrike = NULL;
 | 
| -
 | 
| -    fCurrTexture = NULL;
 | 
| -    fCurrVertex = 0;
 | 
| -
 | 
| -    fVertices = NULL;
 | 
| -    fAllocVertexCount = 0;
 | 
| -    fTotalVertexCount = 0;
 | 
| -}
 | 
| -
 | 
| -void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
 | 
| -                                     const GrPaint& paint, const SkPaint& skPaint,
 | 
| -                                     const SkMatrix& viewMatrix,
 | 
| -                                     const char text[], size_t byteLength,
 | 
| -                                     SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
 | 
| -    SkASSERT(byteLength == 0 || text != NULL);
 | 
| -
 | 
| -    // nothing to draw
 | 
| -    if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) {
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    this->init(rt, clip, paint, skPaint, regionClipBounds);
 | 
| -
 | 
| -    SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 | 
| -
 | 
| -    SkAutoGlyphCache    autoCache(fSkPaint, &fDeviceProperties, &viewMatrix);
 | 
| -    SkGlyphCache*       cache = autoCache.getCache();
 | 
| -    GrFontScaler*       fontScaler = GetGrFontScaler(cache);
 | 
| -
 | 
| -    // transform our starting point
 | 
| -    {
 | 
| -        SkPoint loc;
 | 
| -        viewMatrix.mapXY(x, y, &loc);
 | 
| -        x = loc.fX;
 | 
| -        y = loc.fY;
 | 
| -    }
 | 
| -
 | 
| -    // need to measure first
 | 
| -    int numGlyphs;
 | 
| -    if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
 | 
| -        SkVector    stopVector;
 | 
| -        numGlyphs = MeasureText(cache, glyphCacheProc, text, byteLength, &stopVector);
 | 
| -
 | 
| -        SkScalar    stopX = stopVector.fX;
 | 
| -        SkScalar    stopY = stopVector.fY;
 | 
| -
 | 
| -        if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
 | 
| -            stopX = SkScalarHalf(stopX);
 | 
| -            stopY = SkScalarHalf(stopY);
 | 
| -        }
 | 
| -        x -= stopX;
 | 
| -        y -= stopY;
 | 
| -    } else {
 | 
| -        numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL);
 | 
| -    }
 | 
| -    fTotalVertexCount = kVerticesPerGlyph*numGlyphs;
 | 
| -
 | 
| -    const char* stop = text + byteLength;
 | 
| -
 | 
| -    SkAutoKern autokern;
 | 
| -
 | 
| -    SkFixed fxMask = ~0;
 | 
| -    SkFixed fyMask = ~0;
 | 
| -    SkScalar halfSampleX, halfSampleY;
 | 
| -    if (cache->isSubpixel()) {
 | 
| -        halfSampleX = halfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound);
 | 
| -        SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix);
 | 
| -        if (kX_SkAxisAlignment == baseline) {
 | 
| -            fyMask = 0;
 | 
| -            halfSampleY = SK_ScalarHalf;
 | 
| -        } else if (kY_SkAxisAlignment == baseline) {
 | 
| -            fxMask = 0;
 | 
| -            halfSampleX = SK_ScalarHalf;
 | 
| -        }
 | 
| -    } else {
 | 
| -        halfSampleX = halfSampleY = SK_ScalarHalf;
 | 
| -    }
 | 
| -
 | 
| -    Sk48Dot16 fx = SkScalarTo48Dot16(x + halfSampleX);
 | 
| -    Sk48Dot16 fy = SkScalarTo48Dot16(y + halfSampleY);
 | 
| -
 | 
| -    // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix, but for
 | 
| -    // performance reasons we just invert here instead
 | 
| -    if (!viewMatrix.invert(&fLocalMatrix)) {
 | 
| -        SkDebugf("Cannot invert viewmatrix\n");
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    while (text < stop) {
 | 
| -        const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask);
 | 
| -
 | 
| -        fx += autokern.adjust(glyph);
 | 
| -
 | 
| -        if (glyph.fWidth) {
 | 
| -            this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
 | 
| -                                            glyph.getSubXFixed(),
 | 
| -                                            glyph.getSubYFixed(),
 | 
| -                                            GrGlyph::kCoverage_MaskStyle),
 | 
| -                              Sk48Dot16FloorToInt(fx),
 | 
| -                              Sk48Dot16FloorToInt(fy),
 | 
| -                              fontScaler);
 | 
| -        }
 | 
| -
 | 
| -        fx += glyph.fAdvanceX;
 | 
| -        fy += glyph.fAdvanceY;
 | 
| -    }
 | 
| -
 | 
| -    this->finish();
 | 
| -}
 | 
| -
 | 
| -void GrBitmapTextContext::onDrawPosText(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) {
 | 
| -    SkASSERT(byteLength == 0 || text != NULL);
 | 
| -    SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
 | 
| -
 | 
| -    // nothing to draw
 | 
| -    if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) {
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    this->init(rt, clip, paint, skPaint, regionClipBounds);
 | 
| -
 | 
| -    SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 | 
| -
 | 
| -    SkAutoGlyphCache    autoCache(fSkPaint, &fDeviceProperties, &viewMatrix);
 | 
| -    SkGlyphCache*       cache = autoCache.getCache();
 | 
| -    GrFontScaler*       fontScaler = GetGrFontScaler(cache);
 | 
| -
 | 
| -    // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix, but for
 | 
| -    // performance reasons we just invert here instead
 | 
| -    if (!viewMatrix.invert(&fLocalMatrix)) {
 | 
| -        SkDebugf("Cannot invert viewmatrix\n");
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL);
 | 
| -    fTotalVertexCount = kVerticesPerGlyph*numGlyphs;
 | 
| -
 | 
| -    const char*        stop = text + byteLength;
 | 
| -    SkTextAlignProc    alignProc(fSkPaint.getTextAlign());
 | 
| -    SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition);
 | 
| -
 | 
| -    if (cache->isSubpixel()) {
 | 
| -        // maybe we should skip the rounding if linearText is set
 | 
| -        SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix);
 | 
| -
 | 
| -        SkFixed fxMask = ~0;
 | 
| -        SkFixed fyMask = ~0;
 | 
| -        SkScalar halfSampleX = SkFixedToScalar(SkGlyph::kSubpixelRound);
 | 
| -        SkScalar halfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound);
 | 
| -        if (kX_SkAxisAlignment == baseline) {
 | 
| -            fyMask = 0;
 | 
| -            halfSampleY = SK_ScalarHalf;
 | 
| -        } else if (kY_SkAxisAlignment == baseline) {
 | 
| -            fxMask = 0;
 | 
| -            halfSampleX = SK_ScalarHalf;
 | 
| -        }
 | 
| -
 | 
| -        if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
 | 
| -            while (text < stop) {
 | 
| -                SkPoint tmsLoc;
 | 
| -                tmsProc(pos, &tmsLoc);
 | 
| -                Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + halfSampleX);
 | 
| -                Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + halfSampleY);
 | 
| -
 | 
| -                const SkGlyph& glyph = glyphCacheProc(cache, &text,
 | 
| -                                                      fx & fxMask, fy & fyMask);
 | 
| -
 | 
| -                if (glyph.fWidth) {
 | 
| -                    this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
 | 
| -                                                    glyph.getSubXFixed(),
 | 
| -                                                    glyph.getSubYFixed(),
 | 
| -                                                    GrGlyph::kCoverage_MaskStyle),
 | 
| -                                      Sk48Dot16FloorToInt(fx),
 | 
| -                                      Sk48Dot16FloorToInt(fy),
 | 
| -                                      fontScaler);
 | 
| -                }
 | 
| -                pos += scalarsPerPosition;
 | 
| -            }
 | 
| -        } else {
 | 
| -            while (text < stop) {
 | 
| -                const char* currentText = text;
 | 
| -                const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0);
 | 
| -
 | 
| -                if (metricGlyph.fWidth) {
 | 
| -                    SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;)
 | 
| -                    SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;)
 | 
| -                    SkPoint tmsLoc;
 | 
| -                    tmsProc(pos, &tmsLoc);
 | 
| -                    SkPoint alignLoc;
 | 
| -                    alignProc(tmsLoc, metricGlyph, &alignLoc);
 | 
| -
 | 
| -                    Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + halfSampleX);
 | 
| -                    Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + halfSampleY);
 | 
| -
 | 
| -                    // have to call again, now that we've been "aligned"
 | 
| -                    const SkGlyph& glyph = glyphCacheProc(cache, ¤tText,
 | 
| -                                                          fx & fxMask, fy & fyMask);
 | 
| -                    // the assumption is that the metrics haven't changed
 | 
| -                    SkASSERT(prevAdvX == glyph.fAdvanceX);
 | 
| -                    SkASSERT(prevAdvY == glyph.fAdvanceY);
 | 
| -                    SkASSERT(glyph.fWidth);
 | 
| -
 | 
| -                    this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
 | 
| -                                                    glyph.getSubXFixed(),
 | 
| -                                                    glyph.getSubYFixed(),
 | 
| -                                                    GrGlyph::kCoverage_MaskStyle),
 | 
| -                                      Sk48Dot16FloorToInt(fx),
 | 
| -                                      Sk48Dot16FloorToInt(fy),
 | 
| -                                      fontScaler);
 | 
| -                }
 | 
| -                pos += scalarsPerPosition;
 | 
| -            }
 | 
| -        }
 | 
| -    } else {    // not subpixel
 | 
| -
 | 
| -        if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
 | 
| -            while (text < stop) {
 | 
| -                // the last 2 parameters are ignored
 | 
| -                const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
 | 
| -
 | 
| -                if (glyph.fWidth) {
 | 
| -                    SkPoint tmsLoc;
 | 
| -                    tmsProc(pos, &tmsLoc);
 | 
| -
 | 
| -                    Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf);
 | 
| -                    Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf);
 | 
| -                    this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
 | 
| -                                                    glyph.getSubXFixed(),
 | 
| -                                                    glyph.getSubYFixed(),
 | 
| -                                                    GrGlyph::kCoverage_MaskStyle),
 | 
| -                                      Sk48Dot16FloorToInt(fx),
 | 
| -                                      Sk48Dot16FloorToInt(fy),
 | 
| -                                      fontScaler);
 | 
| -                }
 | 
| -                pos += scalarsPerPosition;
 | 
| -            }
 | 
| -        } else {
 | 
| -            while (text < stop) {
 | 
| -                // the last 2 parameters are ignored
 | 
| -                const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
 | 
| -
 | 
| -                if (glyph.fWidth) {
 | 
| -                    SkPoint tmsLoc;
 | 
| -                    tmsProc(pos, &tmsLoc);
 | 
| -
 | 
| -                    SkPoint alignLoc;
 | 
| -                    alignProc(tmsLoc, glyph, &alignLoc);
 | 
| -
 | 
| -                    Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf);
 | 
| -                    Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf);
 | 
| -                    this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
 | 
| -                                                    glyph.getSubXFixed(),
 | 
| -                                                    glyph.getSubYFixed(),
 | 
| -                                                    GrGlyph::kCoverage_MaskStyle),
 | 
| -                                      Sk48Dot16FloorToInt(fx),
 | 
| -                                      Sk48Dot16FloorToInt(fy),
 | 
| -                                      fontScaler);
 | 
| -                }
 | 
| -                pos += scalarsPerPosition;
 | 
| -            }
 | 
| -        }
 | 
| -    }
 | 
| -
 | 
| -    this->finish();
 | 
| -}
 | 
| -
 | 
| -static void* alloc_vertices(GrDrawTarget* drawTarget,
 | 
| -                            int numVertices,
 | 
| -                            GrMaskFormat maskFormat) {
 | 
| -    if (numVertices <= 0) {
 | 
| -        return NULL;
 | 
| -    }
 | 
| -
 | 
| -    // set up attributes
 | 
| -    void* vertices = NULL;
 | 
| -    bool success = drawTarget->reserveVertexAndIndexSpace(numVertices,
 | 
| -                                                          get_vertex_stride(maskFormat),
 | 
| -                                                          0,
 | 
| -                                                          &vertices,
 | 
| -                                                          NULL);
 | 
| -    GrAlwaysAssert(success);
 | 
| -    return vertices;
 | 
| -}
 | 
| -
 | 
| -inline bool GrBitmapTextContext::uploadGlyph(GrGlyph* glyph, GrFontScaler* scaler) {
 | 
| -    if (!fStrike->glyphTooLargeForAtlas(glyph)) {
 | 
| -        if (fStrike->addGlyphToAtlas(glyph, scaler)) {
 | 
| -            return true;
 | 
| -        }
 | 
| -
 | 
| -        // try to clear out an unused plot before we flush
 | 
| -        if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
 | 
| -            fStrike->addGlyphToAtlas(glyph, scaler)) {
 | 
| -            return true;
 | 
| -        }
 | 
| -
 | 
| -        if (c_DumpFontCache) {
 | 
| -#ifdef SK_DEVELOPER
 | 
| -            fContext->getFontCache()->dump();
 | 
| -#endif
 | 
| -        }
 | 
| -
 | 
| -        // before we purge the cache, we must flush any accumulated draws
 | 
| -        this->flush();
 | 
| -        fContext->flush();
 | 
| -
 | 
| -        // we should have an unused plot now
 | 
| -        if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
 | 
| -            fStrike->addGlyphToAtlas(glyph, scaler)) {
 | 
| -            return true;
 | 
| -        }
 | 
| -
 | 
| -        // we should never get here
 | 
| -        SkASSERT(false);
 | 
| -    }
 | 
| -
 | 
| -    return false;
 | 
| -}
 | 
| -
 | 
| -void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed,
 | 
| -                                      int vx, int vy,
 | 
| -                                      GrFontScaler* scaler) {
 | 
| -    if (NULL == fDrawTarget) {
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    if (NULL == fStrike) {
 | 
| -        fStrike = fContext->getFontCache()->getStrike(scaler);
 | 
| -    }
 | 
| -
 | 
| -    GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
 | 
| -    if (NULL == glyph || glyph->fBounds.isEmpty()) {
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    int x = vx + glyph->fBounds.fLeft;
 | 
| -    int y = vy + glyph->fBounds.fTop;
 | 
| -
 | 
| -    // keep them as ints until we've done the clip-test
 | 
| -    int width = glyph->fBounds.width();
 | 
| -    int height = glyph->fBounds.height();
 | 
| -
 | 
| -    // check if we clipped out
 | 
| -    if (fClipRect.quickReject(x, y, x + width, y + height)) {
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    // If the glyph is too large we fall back to paths
 | 
| -    if (NULL == glyph->fPlot && !uploadGlyph(glyph, scaler)) {
 | 
| -        if (NULL == glyph->fPath) {
 | 
| -            SkPath* path = SkNEW(SkPath);
 | 
| -            if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
 | 
| -                // flag the glyph as being dead?
 | 
| -                delete path;
 | 
| -                return;
 | 
| -            }
 | 
| -            glyph->fPath = path;
 | 
| -        }
 | 
| -
 | 
| -        // flush any accumulated draws before drawing this glyph as a path.
 | 
| -        this->flush();
 | 
| -
 | 
| -        SkMatrix translate;
 | 
| -        translate.setTranslate(SkIntToScalar(vx), SkIntToScalar(vy));
 | 
| -        SkPath tmpPath(*glyph->fPath);
 | 
| -        tmpPath.transform(translate);
 | 
| -        GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
 | 
| -        fContext->drawPath(fRenderTarget, fClip, fPaint, SkMatrix::I(), tmpPath, strokeInfo);
 | 
| -
 | 
| -        // remove this glyph from the vertices we need to allocate
 | 
| -        fTotalVertexCount -= kVerticesPerGlyph;
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    SkASSERT(glyph->fPlot);
 | 
| -    GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
 | 
| -    glyph->fPlot->setDrawToken(drawToken);
 | 
| -
 | 
| -    // the current texture/maskformat must match what the glyph needs
 | 
| -    GrTexture* texture = glyph->fPlot->texture();
 | 
| -    SkASSERT(texture);
 | 
| -
 | 
| -    if (fCurrTexture != texture || fCurrVertex + kVerticesPerGlyph > fAllocVertexCount) {
 | 
| -        this->flush();
 | 
| -        fCurrTexture = texture;
 | 
| -        fCurrTexture->ref();
 | 
| -        fCurrMaskFormat = glyph->fMaskFormat;
 | 
| -    }
 | 
| -
 | 
| -    if (NULL == fVertices) {
 | 
| -        int maxQuadVertices = kVerticesPerGlyph * fContext->getQuadIndexBuffer()->maxQuads();
 | 
| -        fAllocVertexCount = SkMin32(fTotalVertexCount, maxQuadVertices);
 | 
| -        fVertices = alloc_vertices(fDrawTarget, fAllocVertexCount, fCurrMaskFormat);
 | 
| -    }
 | 
| -
 | 
| -    SkRect r;
 | 
| -    r.fLeft = SkIntToScalar(x);
 | 
| -    r.fTop = SkIntToScalar(y);
 | 
| -    r.fRight = r.fLeft + SkIntToScalar(width);
 | 
| -    r.fBottom = r.fTop + SkIntToScalar(height);
 | 
| -
 | 
| -    fVertexBounds.joinNonEmptyArg(r);
 | 
| -
 | 
| -    int u0 = glyph->fAtlasLocation.fX;
 | 
| -    int v0 = glyph->fAtlasLocation.fY;
 | 
| -    int u1 = u0 + width;
 | 
| -    int v1 = v0 + height;
 | 
| -
 | 
| -    size_t vertSize = get_vertex_stride(fCurrMaskFormat);
 | 
| -    intptr_t vertex = reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex;
 | 
| -
 | 
| -    // V0
 | 
| -    SkPoint* position = reinterpret_cast<SkPoint*>(vertex);
 | 
| -    position->set(r.fLeft, r.fTop);
 | 
| -    if (kA8_GrMaskFormat == fCurrMaskFormat) {
 | 
| -        SkColor* color = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
 | 
| -        *color = fPaint.getColor();
 | 
| -    }
 | 
| -    SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + vertSize -
 | 
| -                                                              sizeof(SkIPoint16));
 | 
| -    textureCoords->set(u0, v0);
 | 
| -    vertex += vertSize;
 | 
| -
 | 
| -    // V1
 | 
| -    position = reinterpret_cast<SkPoint*>(vertex);
 | 
| -    position->set(r.fLeft, r.fBottom);
 | 
| -    if (kA8_GrMaskFormat == fCurrMaskFormat) {
 | 
| -        SkColor* color = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
 | 
| -        *color = fPaint.getColor();
 | 
| -    }
 | 
| -    textureCoords = reinterpret_cast<SkIPoint16*>(vertex + vertSize  - sizeof(SkIPoint16));
 | 
| -    textureCoords->set(u0, v1);
 | 
| -    vertex += vertSize;
 | 
| -
 | 
| -    // V2
 | 
| -    position = reinterpret_cast<SkPoint*>(vertex);
 | 
| -    position->set(r.fRight, r.fBottom);
 | 
| -    if (kA8_GrMaskFormat == fCurrMaskFormat) {
 | 
| -        SkColor* color = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
 | 
| -        *color = fPaint.getColor();
 | 
| -    }
 | 
| -    textureCoords = reinterpret_cast<SkIPoint16*>(vertex + vertSize  - sizeof(SkIPoint16));
 | 
| -    textureCoords->set(u1, v1);
 | 
| -    vertex += vertSize;
 | 
| -
 | 
| -    // V3
 | 
| -    position = reinterpret_cast<SkPoint*>(vertex);
 | 
| -    position->set(r.fRight, r.fTop);
 | 
| -    if (kA8_GrMaskFormat == fCurrMaskFormat) {
 | 
| -        SkColor* color = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint));
 | 
| -        *color = fPaint.getColor();
 | 
| -    }
 | 
| -    textureCoords = reinterpret_cast<SkIPoint16*>(vertex + vertSize  - sizeof(SkIPoint16));
 | 
| -    textureCoords->set(u1, v0);
 | 
| -
 | 
| -    fCurrVertex += 4;
 | 
| -}
 | 
| -
 | 
| -void GrBitmapTextContext::flush() {
 | 
| -    if (NULL == fDrawTarget) {
 | 
| -        return;
 | 
| -    }
 | 
| -
 | 
| -    if (fCurrVertex > 0) {
 | 
| -        GrPipelineBuilder pipelineBuilder;
 | 
| -        pipelineBuilder.setFromPaint(fPaint, fRenderTarget, fClip);
 | 
| -
 | 
| -        // setup our sampler state for our text texture/atlas
 | 
| -        SkASSERT(SkIsAlign4(fCurrVertex));
 | 
| -        SkASSERT(fCurrTexture);
 | 
| -
 | 
| -        SkASSERT(fStrike);
 | 
| -        GrColor color = fPaint.getColor();
 | 
| -        switch (fCurrMaskFormat) {
 | 
| -                // Color bitmap text
 | 
| -            case kARGB_GrMaskFormat: {
 | 
| -                int a = fSkPaint.getAlpha();
 | 
| -                color = SkColorSetARGB(a, a, a, a);
 | 
| -                break;
 | 
| -            }
 | 
| -                // LCD text
 | 
| -            case kA565_GrMaskFormat: {
 | 
| -                // TODO: move supportsRGBCoverage check to setupCoverageEffect and only add LCD
 | 
| -                // processor if the xp can support it. For now we will simply assume that if
 | 
| -                // fUseLCDText is true, then we have a known color output.
 | 
| -                const GrXPFactory* xpFactory = pipelineBuilder.getXPFactory();
 | 
| -                if (!xpFactory->supportsRGBCoverage(0, kRGBA_GrColorComponentFlags)) {
 | 
| -                    SkDebugf("LCD Text will not draw correctly.\n");
 | 
| -                }
 | 
| -                break;
 | 
| -            }
 | 
| -                // Grayscale/BW text
 | 
| -            case kA8_GrMaskFormat:
 | 
| -                break;
 | 
| -            default:
 | 
| -                SkFAIL("Unexpected mask format.");
 | 
| -        }
 | 
| -
 | 
| -        GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
 | 
| -        uint32_t textureUniqueID = fCurrTexture->getUniqueID();
 | 
| -        if (textureUniqueID != fEffectTextureUniqueID ||
 | 
| -            fCachedGeometryProcessor->color() != color ||
 | 
| -            !fCachedGeometryProcessor->localMatrix().cheapEqualTo(fLocalMatrix)) {
 | 
| -            // This will be ignored in the non A8 case
 | 
| -            bool opaqueVertexColors = GrColorIsOpaque(fPaint.getColor());
 | 
| -            fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(color,
 | 
| -                                                                       fCurrTexture,
 | 
| -                                                                       params,
 | 
| -                                                                       fCurrMaskFormat,
 | 
| -                                                                       opaqueVertexColors,
 | 
| -                                                                       fLocalMatrix));
 | 
| -            fEffectTextureUniqueID = textureUniqueID;
 | 
| -        }
 | 
| -
 | 
| -        int nGlyphs = fCurrVertex / kVerticesPerGlyph;
 | 
| -        fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
 | 
| -        fDrawTarget->drawIndexedInstances(&pipelineBuilder,
 | 
| -                                          fCachedGeometryProcessor.get(),
 | 
| -                                          kTriangles_GrPrimitiveType,
 | 
| -                                          nGlyphs,
 | 
| -                                          kVerticesPerGlyph,
 | 
| -                                          kIndicesPerGlyph,
 | 
| -                                          &fVertexBounds);
 | 
| -
 | 
| -        fDrawTarget->resetVertexSource();
 | 
| -        fVertices = NULL;
 | 
| -        fAllocVertexCount = 0;
 | 
| -        // reset to be those that are left
 | 
| -        fTotalVertexCount -= fCurrVertex;
 | 
| -        fCurrVertex = 0;
 | 
| -        fVertexBounds.setLargestInverted();
 | 
| -        SkSafeSetNull(fCurrTexture);
 | 
| -    }
 | 
| -}
 | 
| -
 | 
| -inline void GrBitmapTextContext::finish() {
 | 
| -    this->flush();
 | 
| -    fTotalVertexCount = 0;
 | 
| -
 | 
| -    GrTextContext::finish();
 | 
| -}
 | 
| 
 |