
/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */



#include "GrTextContext.h"
#include "GrAtlas.h"
#include "GrContext.h"
#include "GrTextStrike.h"
#include "GrTextStrike_impl.h"
#include "GrFontScaler.h"
#include "GrIndexBuffer.h"
#include "GrGpuVertex.h"
#include "GrDrawTarget.h"

enum {
    kGlyphMaskStage = GrPaint::kTotalStages,
};

void GrTextContext::flushGlyphs() {
    if (fCurrVertex > 0) {
        GrDrawTarget::AutoStateRestore asr(fDrawTarget);
        GrDrawState* drawState = fDrawTarget->drawState();
        // setup our sampler state for our text texture/atlas
        GrSamplerState::Filter filter;
        if (fExtMatrix.isIdentity()) {
            filter = GrSamplerState::kNearest_Filter;
        } else {
            filter = GrSamplerState::kBilinear_Filter;
        }
        drawState->sampler(kGlyphMaskStage)->reset(
            GrSamplerState::kRepeat_WrapMode,filter);

        GrAssert(GrIsALIGN4(fCurrVertex));
        int nIndices = fCurrVertex + (fCurrVertex >> 1);
        GrAssert(fCurrTexture);
        drawState->setTexture(kGlyphMaskStage, fCurrTexture);

        if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
            if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff ||
                kISA_BlendCoeff != fPaint.fDstBlendCoeff ||
                fPaint.hasTexture()) {
                GrPrintf("LCD Text will not draw correctly.\n");
            }
            // setup blend so that we get mask * paintColor + (1-mask)*dstColor
            drawState->setBlendConstant(fPaint.fColor);
            drawState->setBlendFunc(kConstC_BlendCoeff, kISC_BlendCoeff);
            // don't modulate by the paint's color in the frag since we're
            // already doing it via the blend const.
            drawState->setColor(0xffffffff);
        } else {
            // set back to normal in case we took LCD path previously.
            drawState->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff);
            drawState->setColor(fPaint.fColor);
        }

        fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());

        fDrawTarget->drawIndexed(kTriangles_PrimitiveType,
                                 0, 0, fCurrVertex, nIndices);
        fDrawTarget->resetVertexSource();
        fVertices = NULL;
        fMaxVertices = 0;
        fCurrVertex = 0;
        fCurrTexture->unref();
        fCurrTexture = NULL;
    }
}

GrTextContext::GrTextContext(GrContext* context,
                             const GrPaint& paint,
                             const GrMatrix* extMatrix) : fPaint(paint) {
    fContext = context;
    fStrike = NULL;

    fCurrTexture = NULL;
    fCurrVertex = 0;

    if (NULL != extMatrix) {
        fExtMatrix = *extMatrix;
    } else {
        fExtMatrix = GrMatrix::I();
    }
    if (context->getClip().hasConservativeBounds()) {
        if (!fExtMatrix.isIdentity()) {
            GrMatrix inverse;
            GrRect r = context->getClip().getConservativeBounds();
            if (fExtMatrix.invert(&inverse)) {
                inverse.mapRect(&r);
                r.roundOut(&fClipRect);
            }
        } else {
            context->getClip().getConservativeBounds().roundOut(&fClipRect);
        }
    } else {
        fClipRect.setLargest();
    }

    // save the context's original matrix off and restore in destructor
    // this must be done before getTextTarget.
    fOrigViewMatrix = fContext->getMatrix();
    fContext->setMatrix(fExtMatrix);

    /*
     We need to call preConcatMatrix with our viewmatrix's inverse, for each
     texture and mask in the paint. However, computing the inverse can be 
     expensive, and its possible we may not have any textures or masks, so these
     two loops are written such that we only compute the inverse (once) if we
     need it. We do this on our copy of the paint rather than directly on the 
     draw target because we re-provide the paint to the context when we have
     to flush our glyphs or draw a glyph as a path midstream.
    */
    bool invVMComputed = false;
    GrMatrix invVM;
    for (int t = 0; t < GrPaint::kMaxTextures; ++t) {
        if (NULL != fPaint.getTexture(t)) {
            if (invVMComputed || fOrigViewMatrix.invert(&invVM)) {
                invVMComputed = true;
                fPaint.textureSampler(t)->preConcatMatrix(invVM);
            }
        }
    }
    for (int m = 0; m < GrPaint::kMaxMasks; ++m) {
        if (NULL != fPaint.getMask(m)) {
            if (invVMComputed || fOrigViewMatrix.invert(&invVM)) {
                invVMComputed = true;
                fPaint.maskSampler(m)->preConcatMatrix(invVM);
            }
        }
    }

    fDrawTarget = fContext->getTextTarget(fPaint);

    fVertices = NULL;
    fMaxVertices = 0;

    fVertexLayout = 
        GrDrawTarget::kTextFormat_VertexLayoutBit |
        GrDrawTarget::StageTexCoordVertexLayoutBit(kGlyphMaskStage, 0);

    int stageMask = paint.getActiveStageMask();
    if (stageMask) {
        for (int i = 0; i < GrPaint::kTotalStages; ++i) {
            if ((1 << i) & stageMask) {
                fVertexLayout |= 
                    GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i);
                GrAssert(i != kGlyphMaskStage);
            }
        }
    }
}

GrTextContext::~GrTextContext() {
    this->flushGlyphs();
    fContext->setMatrix(fOrigViewMatrix);
}

void GrTextContext::flush() {
    this->flushGlyphs();
}

static inline void setRectFan(GrGpuTextVertex v[4], int l, int t, int r, int b,
                              int stride) {
    v[0 * stride].setI(l, t);
    v[1 * stride].setI(l, b);
    v[2 * stride].setI(r, b);
    v[3 * stride].setI(r, t);
}

void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
                                    GrFixed vx, GrFixed vy,
                                    GrFontScaler* scaler) {
    if (NULL == fStrike) {
        fStrike = fContext->getFontCache()->getStrike(scaler);
    }

    GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
    if (NULL == glyph || glyph->fBounds.isEmpty()) {
        return;
    }

    vx += GrIntToFixed(glyph->fBounds.fLeft);
    vy += GrIntToFixed(glyph->fBounds.fTop);

    // keep them as ints until we've done the clip-test
    GrFixed width = glyph->fBounds.width();
    GrFixed height = glyph->fBounds.height();

    // check if we clipped out
    if (true || NULL == glyph->fAtlas) {
        int x = vx >> 16;
        int y = vy >> 16;
        if (fClipRect.quickReject(x, y, x + width, y + height)) {
//            Gr_clz(3);    // so we can set a break-point in the debugger
            return;
        }
    }

    if (NULL == glyph->fAtlas) {
        if (fStrike->getGlyphAtlas(glyph, scaler)) {
            goto HAS_ATLAS;
        }

        // before we purge the cache, we must flush any accumulated draws
        this->flushGlyphs();
        fContext->flushText();

        // try to purge
        fContext->getFontCache()->purgeExceptFor(fStrike);
        if (fStrike->getGlyphAtlas(glyph, scaler)) {
            goto HAS_ATLAS;
        }

        if (NULL == glyph->fPath) {
            GrPath* path = new GrPath;
            if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
                // flag the glyph as being dead?
                delete path;
                return;
            }
            glyph->fPath = path;
        }

        GrPoint translate;
        translate.set(GrFixedToScalar(vx - GrIntToFixed(glyph->fBounds.fLeft)),
                      GrFixedToScalar(vy - GrIntToFixed(glyph->fBounds.fTop)));
        fContext->drawPath(fPaint, *glyph->fPath, kWinding_PathFill,
                           &translate);
        return;
    }

HAS_ATLAS:
    GrAssert(glyph->fAtlas);

    // now promote them to fixed
    width = GrIntToFixed(width);
    height = GrIntToFixed(height);

    GrTexture* texture = glyph->fAtlas->texture();
    GrAssert(texture);

    if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
        this->flushGlyphs();
        fCurrTexture = texture;
        fCurrTexture->ref();
    }

    if (NULL == fVertices) {
        // If we need to reserve vertices allow the draw target to suggest
        // a number of verts to reserve and whether to perform a flush.
        fMaxVertices = kMinRequestedVerts;
        bool flush = fDrawTarget->geometryHints(fVertexLayout,
                                               &fMaxVertices,
                                               NULL);
        if (flush) {
            this->flushGlyphs();
            fContext->flushText();
            fDrawTarget = fContext->getTextTarget(fPaint);
            fMaxVertices = kDefaultRequestedVerts;
            // ignore return, no point in flushing again.
            fDrawTarget->geometryHints(fVertexLayout,
                                       &fMaxVertices,
                                       NULL);
        }

        int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
        if (fMaxVertices < kMinRequestedVerts) {
            fMaxVertices = kDefaultRequestedVerts;
        } else if (fMaxVertices > maxQuadVertices) {
            // don't exceed the limit of the index buffer
            fMaxVertices = maxQuadVertices;
        }
        bool success = fDrawTarget->reserveVertexSpace(fVertexLayout, 
                                                   fMaxVertices,
                                                   GrTCast<void**>(&fVertices));
        GrAlwaysAssert(success);
    }

    GrFixed tx = GrIntToFixed(glyph->fAtlasLocation.fX);
    GrFixed ty = GrIntToFixed(glyph->fAtlasLocation.fY);

#if GR_GL_TEXT_TEXTURE_NORMALIZED
    int x = vx >> 16;
    int y = vy >> 16;
    int w = width >> 16;
    int h = height >> 16;

    setRectFan(&fVertices[2*fCurrVertex], x, y, x + w, y + h, 2);
    setRectFan(&fVertices[2*fCurrVertex+1],
               texture->normalizeFixedX(tx),
               texture->normalizeFixedY(ty),
               texture->normalizeFixedX(tx + width),
               texture->normalizeFixedY(ty + height),
               2);
#else
    fVertices[2*fCurrVertex].setXRectFan(vx, vy, vx + width, vy + height,
                                        2 * sizeof(GrGpuTextVertex));
    fVertices[2*fCurrVertex+1].setXRectFan(texture->normalizeFixedX(tx),
                                          texture->normalizeFixedY(ty),
                                          texture->normalizeFixedX(tx + width),
                                          texture->normalizeFixedY(ty + height),
                                          2 * sizeof(GrGpuTextVertex));
#endif
    fCurrVertex += 4;
}


