/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "OpenGLRenderer"

#include <SkUtils.h>

#include <cutils/properties.h>

#include <utils/Log.h>

#include "Caches.h"
#include "Debug.h"
#include "FontRenderer.h"
#include "Caches.h"

namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////

#define DEFAULT_TEXT_CACHE_WIDTH 1024
#define DEFAULT_TEXT_CACHE_HEIGHT 256
#define MAX_TEXT_CACHE_WIDTH 2048
#define TEXTURE_BORDER_SIZE 2

#define AUTO_KERN(prev, next) (((next) - (prev) + 32) >> 6 << 16)

///////////////////////////////////////////////////////////////////////////////
// CacheTextureLine
///////////////////////////////////////////////////////////////////////////////

bool CacheTextureLine::fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
    if (glyph.fHeight + TEXTURE_BORDER_SIZE > mMaxHeight) {
        return false;
    }

    if (mCurrentCol + glyph.fWidth + TEXTURE_BORDER_SIZE < mMaxWidth) {
        *retOriginX = mCurrentCol + 1;
        *retOriginY = mCurrentRow + 1;
        mCurrentCol += glyph.fWidth + TEXTURE_BORDER_SIZE;
        mDirty = true;
        return true;
    }

    return false;
}

///////////////////////////////////////////////////////////////////////////////
// Font
///////////////////////////////////////////////////////////////////////////////

Font::Font(FontRenderer* state, uint32_t fontId, float fontSize,
        int flags, uint32_t italicStyle, uint32_t scaleX,
        SkPaint::Style style, uint32_t strokeWidth) :
        mState(state), mFontId(fontId), mFontSize(fontSize),
        mFlags(flags), mItalicStyle(italicStyle), mScaleX(scaleX),
        mStyle(style), mStrokeWidth(mStrokeWidth) {
}


Font::~Font() {
    for (uint32_t ct = 0; ct < mState->mActiveFonts.size(); ct++) {
        if (mState->mActiveFonts[ct] == this) {
            mState->mActiveFonts.removeAt(ct);
            break;
        }
    }

    for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
        delete mCachedGlyphs.valueAt(i);
    }
}

void Font::invalidateTextureCache(CacheTextureLine *cacheLine) {
    for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
        CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueAt(i);
        if (cacheLine == NULL || cachedGlyph->mCachedTextureLine == cacheLine) {
            cachedGlyph->mIsValid = false;
        }
    }
}

void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
        uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
    int nPenX = x + glyph->mBitmapLeft;
    int nPenY = y + glyph->mBitmapTop;

    int width = (int) glyph->mBitmapWidth;
    int height = (int) glyph->mBitmapHeight;

    if (bounds->bottom > nPenY) {
        bounds->bottom = nPenY;
    }
    if (bounds->left > nPenX) {
        bounds->left = nPenX;
    }
    if (bounds->right < nPenX + width) {
        bounds->right = nPenX + width;
    }
    if (bounds->top < nPenY + height) {
        bounds->top = nPenY + height;
    }
}

void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
        uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
    int nPenX = x + glyph->mBitmapLeft;
    int nPenY = y + glyph->mBitmapTop + glyph->mBitmapHeight;

    float u1 = glyph->mBitmapMinU;
    float u2 = glyph->mBitmapMaxU;
    float v1 = glyph->mBitmapMinV;
    float v2 = glyph->mBitmapMaxV;

    int width = (int) glyph->mBitmapWidth;
    int height = (int) glyph->mBitmapHeight;

    mState->appendMeshQuad(nPenX, nPenY, u1, v2,
            nPenX + width, nPenY, u2, v2,
            nPenX + width, nPenY - height, u2, v1,
            nPenX, nPenY - height, u1, v1, glyph->mCachedTextureLine->mCacheTexture);
}

void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y,
        uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
    int nPenX = x + glyph->mBitmapLeft;
    int nPenY = y + glyph->mBitmapTop;

    uint32_t endX = glyph->mStartX + glyph->mBitmapWidth;
    uint32_t endY = glyph->mStartY + glyph->mBitmapHeight;

    CacheTexture *cacheTexture = glyph->mCachedTextureLine->mCacheTexture;
    uint32_t cacheWidth = cacheTexture->mWidth;
    const uint8_t* cacheBuffer = cacheTexture->mTexture;

    uint32_t cacheX = 0, cacheY = 0;
    int32_t bX = 0, bY = 0;
    for (cacheX = glyph->mStartX, bX = nPenX; cacheX < endX; cacheX++, bX++) {
        for (cacheY = glyph->mStartY, bY = nPenY; cacheY < endY; cacheY++, bY++) {
#if DEBUG_FONT_RENDERER
            if (bX < 0 || bY < 0 || bX >= (int32_t) bitmapW || bY >= (int32_t) bitmapH) {
                ALOGE("Skipping invalid index");
                continue;
            }
#endif
            uint8_t tempCol = cacheBuffer[cacheY * cacheWidth + cacheX];
            bitmap[bY * bitmapW + bX] = tempCol;
        }
    }
}

void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
        SkPathMeasure& measure, SkPoint* position, SkVector* tangent) {
    const float halfWidth = glyph->mBitmapWidth * 0.5f;
    const float height = glyph->mBitmapHeight;

    vOffset += glyph->mBitmapTop + height;

    SkPoint destination[4];
    measure.getPosTan(x + hOffset +  glyph->mBitmapLeft + halfWidth, position, tangent);

    // Move along the tangent and offset by the normal
    destination[0].set(-tangent->fX * halfWidth - tangent->fY * vOffset,
            -tangent->fY * halfWidth + tangent->fX * vOffset);
    destination[1].set(tangent->fX * halfWidth - tangent->fY * vOffset,
            tangent->fY * halfWidth + tangent->fX * vOffset);
    destination[2].set(destination[1].fX + tangent->fY * height,
            destination[1].fY - tangent->fX * height);
    destination[3].set(destination[0].fX + tangent->fY * height,
            destination[0].fY - tangent->fX * height);

    const float u1 = glyph->mBitmapMinU;
    const float u2 = glyph->mBitmapMaxU;
    const float v1 = glyph->mBitmapMinV;
    const float v2 = glyph->mBitmapMaxV;

    mState->appendRotatedMeshQuad(
            position->fX + destination[0].fX,
            position->fY + destination[0].fY, u1, v2,
            position->fX + destination[1].fX,
            position->fY + destination[1].fY, u2, v2,
            position->fX + destination[2].fX,
            position->fY + destination[2].fY, u2, v1,
            position->fX + destination[3].fX,
            position->fY + destination[3].fY, u1, v1,
            glyph->mCachedTextureLine->mCacheTexture);
}

CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit) {
    CachedGlyphInfo* cachedGlyph = NULL;
    ssize_t index = mCachedGlyphs.indexOfKey(textUnit);
    if (index >= 0) {
        cachedGlyph = mCachedGlyphs.valueAt(index);
    } else {
        cachedGlyph = cacheGlyph(paint, textUnit);
    }

    // Is the glyph still in texture cache?
    if (!cachedGlyph->mIsValid) {
        const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit);
        updateGlyphCache(paint, skiaGlyph, cachedGlyph);
    }

    return cachedGlyph;
}

void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
        int numGlyphs, int x, int y, uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
    if (bitmap != NULL && bitmapW > 0 && bitmapH > 0) {
        render(paint, text, start, len, numGlyphs, x, y, BITMAP, bitmap,
                bitmapW, bitmapH, NULL, NULL);
    } else {
        render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL,
                0, 0, NULL, NULL);
    }
}

void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
            int numGlyphs, int x, int y, const float* positions) {
    render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL,
            0, 0, NULL, positions);
}

void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
        int numGlyphs, SkPath* path, float hOffset, float vOffset) {
    if (numGlyphs == 0 || text == NULL || len == 0) {
        return;
    }

    text += start;

    int glyphsCount = 0;
    SkFixed prevRsbDelta = 0;

    float penX = 0.0f;

    SkPoint position;
    SkVector tangent;

    SkPathMeasure measure(*path, false);
    float pathLength = SkScalarToFloat(measure.getLength());

    if (paint->getTextAlign() != SkPaint::kLeft_Align) {
        float textWidth = SkScalarToFloat(paint->measureText(text, len));
        float pathOffset = pathLength;
        if (paint->getTextAlign() == SkPaint::kCenter_Align) {
            textWidth *= 0.5f;
            pathOffset *= 0.5f;
        }
        penX += pathOffset - textWidth;
    }

    while (glyphsCount < numGlyphs && penX < pathLength) {
        glyph_t glyph = GET_GLYPH(text);

        if (IS_END_OF_STRING(glyph)) {
            break;
        }

        CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
        penX += SkFixedToFloat(AUTO_KERN(prevRsbDelta, cachedGlyph->mLsbDelta));
        prevRsbDelta = cachedGlyph->mRsbDelta;

        if (cachedGlyph->mIsValid) {
            drawCachedGlyph(cachedGlyph, penX, hOffset, vOffset, measure, &position, &tangent);
        }

        penX += SkFixedToFloat(cachedGlyph->mAdvanceX);

        glyphsCount++;
    }
}

void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
        int numGlyphs, Rect *bounds) {
    if (bounds == NULL) {
        ALOGE("No return rectangle provided to measure text");
        return;
    }
    bounds->set(1e6, -1e6, -1e6, 1e6);
    render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, NULL);
}

void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
        int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
        uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* positions) {
    if (numGlyphs == 0 || text == NULL || len == 0) {
        return;
    }

    static RenderGlyph gRenderGlyph[] = {
            &android::uirenderer::Font::drawCachedGlyph,
            &android::uirenderer::Font::drawCachedGlyphBitmap,
            &android::uirenderer::Font::measureCachedGlyph
    };
    RenderGlyph render = gRenderGlyph[mode];

    text += start;
    int glyphsCount = 0;

    if (CC_LIKELY(positions == NULL)) {
        SkFixed prevRsbDelta = 0;

        float penX = x + 0.5f;
        int penY = y;

        while (glyphsCount < numGlyphs) {
            glyph_t glyph = GET_GLYPH(text);

            // Reached the end of the string
            if (IS_END_OF_STRING(glyph)) {
                break;
            }

            CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
            penX += SkFixedToFloat(AUTO_KERN(prevRsbDelta, cachedGlyph->mLsbDelta));
            prevRsbDelta = cachedGlyph->mRsbDelta;

            // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
            if (cachedGlyph->mIsValid) {
                (*this.*render)(cachedGlyph, (int) floorf(penX), penY,
                        bitmap, bitmapW, bitmapH, bounds, positions);
            }

            penX += SkFixedToFloat(cachedGlyph->mAdvanceX);

            glyphsCount++;
        }
    } else {
        const SkPaint::Align align = paint->getTextAlign();

        // This is for renderPosText()
        while (glyphsCount < numGlyphs) {
            glyph_t glyph = GET_GLYPH(text);

            // Reached the end of the string
            if (IS_END_OF_STRING(glyph)) {
                break;
            }

            CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);

            // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
            if (cachedGlyph->mIsValid) {
                int penX = x + positions[(glyphsCount << 1)];
                int penY = y + positions[(glyphsCount << 1) + 1];

                switch (align) {
                    case SkPaint::kRight_Align:
                        penX -= SkFixedToFloat(cachedGlyph->mAdvanceX);
                        penY -= SkFixedToFloat(cachedGlyph->mAdvanceY);
                        break;
                    case SkPaint::kCenter_Align:
                        penX -= SkFixedToFloat(cachedGlyph->mAdvanceX >> 1);
                        penY -= SkFixedToFloat(cachedGlyph->mAdvanceY >> 1);
                    default:
                        break;
                }

                (*this.*render)(cachedGlyph, penX, penY,
                        bitmap, bitmapW, bitmapH, bounds, positions);
            }

            glyphsCount++;
        }
    }
}

void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph) {
    glyph->mAdvanceX = skiaGlyph.fAdvanceX;
    glyph->mAdvanceY = skiaGlyph.fAdvanceY;
    glyph->mBitmapLeft = skiaGlyph.fLeft;
    glyph->mBitmapTop = skiaGlyph.fTop;
    glyph->mLsbDelta = skiaGlyph.fLsbDelta;
    glyph->mRsbDelta = skiaGlyph.fRsbDelta;

    uint32_t startX = 0;
    uint32_t startY = 0;

    // Get the bitmap for the glyph
    paint->findImage(skiaGlyph);
    mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY);

    if (!glyph->mIsValid) {
        return;
    }

    uint32_t endX = startX + skiaGlyph.fWidth;
    uint32_t endY = startY + skiaGlyph.fHeight;

    glyph->mStartX = startX;
    glyph->mStartY = startY;
    glyph->mBitmapWidth = skiaGlyph.fWidth;
    glyph->mBitmapHeight = skiaGlyph.fHeight;

    uint32_t cacheWidth = glyph->mCachedTextureLine->mCacheTexture->mWidth;
    uint32_t cacheHeight = glyph->mCachedTextureLine->mCacheTexture->mHeight;

    glyph->mBitmapMinU = (float) startX / (float) cacheWidth;
    glyph->mBitmapMinV = (float) startY / (float) cacheHeight;
    glyph->mBitmapMaxU = (float) endX / (float) cacheWidth;
    glyph->mBitmapMaxV = (float) endY / (float) cacheHeight;

    mState->mUploadTexture = true;
}

CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph) {
    CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
    mCachedGlyphs.add(glyph, newGlyph);

    const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph);
    newGlyph->mGlyphIndex = skiaGlyph.fID;
    newGlyph->mIsValid = false;

    updateGlyphCache(paint, skiaGlyph, newGlyph);

    return newGlyph;
}

Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize,
        int flags, uint32_t italicStyle, uint32_t scaleX,
        SkPaint::Style style, uint32_t strokeWidth) {
    Vector<Font*> &activeFonts = state->mActiveFonts;

    for (uint32_t i = 0; i < activeFonts.size(); i++) {
        Font* font = activeFonts[i];
        if (font->mFontId == fontId && font->mFontSize == fontSize &&
                font->mFlags == flags && font->mItalicStyle == italicStyle &&
                font->mScaleX == scaleX && font->mStyle == style &&
                (style == SkPaint::kFill_Style || font->mStrokeWidth == strokeWidth)) {
            return font;
        }
    }

    Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle,
            scaleX, style, strokeWidth);
    activeFonts.push(newFont);
    return newFont;
}

///////////////////////////////////////////////////////////////////////////////
// FontRenderer
///////////////////////////////////////////////////////////////////////////////

static bool sLogFontRendererCreate = true;

FontRenderer::FontRenderer() {
    if (sLogFontRendererCreate) {
        INIT_LOGD("Creating FontRenderer");
    }

    mGammaTable = NULL;
    mInitialized = false;
    mMaxNumberOfQuads = 1024;
    mCurrentQuadIndex = 0;

    mTextMeshPtr = NULL;
    mCurrentCacheTexture = NULL;
    mLastCacheTexture = NULL;
    mCacheTextureSmall = NULL;
    mCacheTexture128 = NULL;
    mCacheTexture256 = NULL;
    mCacheTexture512 = NULL;

    mLinearFiltering = false;

    mIndexBufferID = 0;

    mSmallCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
    mSmallCacheHeight = DEFAULT_TEXT_CACHE_HEIGHT;

    char property[PROPERTY_VALUE_MAX];
    if (property_get(PROPERTY_TEXT_CACHE_WIDTH, property, NULL) > 0) {
        if (sLogFontRendererCreate) {
            INIT_LOGD("  Setting text cache width to %s pixels", property);
        }
        mSmallCacheWidth = atoi(property);
    } else {
        if (sLogFontRendererCreate) {
            INIT_LOGD("  Using default text cache width of %i pixels", mSmallCacheWidth);
        }
    }

    if (property_get(PROPERTY_TEXT_CACHE_HEIGHT, property, NULL) > 0) {
        if (sLogFontRendererCreate) {
            INIT_LOGD("  Setting text cache width to %s pixels", property);
        }
        mSmallCacheHeight = atoi(property);
    } else {
        if (sLogFontRendererCreate) {
            INIT_LOGD("  Using default text cache height of %i pixels", mSmallCacheHeight);
        }
    }

    sLogFontRendererCreate = false;
}

FontRenderer::~FontRenderer() {
    for (uint32_t i = 0; i < mCacheLines.size(); i++) {
        delete mCacheLines[i];
    }
    mCacheLines.clear();

    if (mInitialized) {
        // Unbinding the buffer shouldn't be necessary but it crashes with some drivers
        Caches::getInstance().unbindIndicesBuffer();
        glDeleteBuffers(1, &mIndexBufferID);

        delete[] mTextMeshPtr;
        delete mCacheTextureSmall;
        delete mCacheTexture128;
        delete mCacheTexture256;
        delete mCacheTexture512;
    }

    Vector<Font*> fontsToDereference = mActiveFonts;
    for (uint32_t i = 0; i < fontsToDereference.size(); i++) {
        delete fontsToDereference[i];
    }
}

void FontRenderer::flushAllAndInvalidate() {
    if (mCurrentQuadIndex != 0) {
        issueDrawCommand();
        mCurrentQuadIndex = 0;
    }

    for (uint32_t i = 0; i < mActiveFonts.size(); i++) {
        mActiveFonts[i]->invalidateTextureCache();
    }

    for (uint32_t i = 0; i < mCacheLines.size(); i++) {
        mCacheLines[i]->mCurrentCol = 0;
    }
}

void FontRenderer::deallocateTextureMemory(CacheTexture *cacheTexture) {
    if (cacheTexture && cacheTexture->mTexture) {
        glDeleteTextures(1, &cacheTexture->mTextureId);
        delete[] cacheTexture->mTexture;
        cacheTexture->mTexture = NULL;
        cacheTexture->mTextureId = 0;
    }
}

void FontRenderer::flushLargeCaches() {
    if ((!mCacheTexture128 || !mCacheTexture128->mTexture) &&
            (!mCacheTexture256 || !mCacheTexture256->mTexture) &&
            (!mCacheTexture512 || !mCacheTexture512->mTexture)) {
        // Typical case; no large glyph caches allocated
        return;
    }

    for (uint32_t i = 0; i < mCacheLines.size(); i++) {
        CacheTextureLine* cacheLine = mCacheLines[i];
        if ((cacheLine->mCacheTexture == mCacheTexture128 ||
                cacheLine->mCacheTexture == mCacheTexture256 ||
                cacheLine->mCacheTexture == mCacheTexture512) &&
                cacheLine->mCacheTexture->mTexture != NULL) {
            cacheLine->mCurrentCol = 0;
            for (uint32_t i = 0; i < mActiveFonts.size(); i++) {
                mActiveFonts[i]->invalidateTextureCache(cacheLine);
            }
        }
    }

    deallocateTextureMemory(mCacheTexture128);
    deallocateTextureMemory(mCacheTexture256);
    deallocateTextureMemory(mCacheTexture512);
}

void FontRenderer::allocateTextureMemory(CacheTexture* cacheTexture) {
    int width = cacheTexture->mWidth;
    int height = cacheTexture->mHeight;

    cacheTexture->mTexture = new uint8_t[width * height];
#if DEBUG_FONT_RENDERER
    memset(cacheTexture->mTexture, 0, width * height * sizeof(uint8_t));
#endif

    if (!cacheTexture->mTextureId) {
        glGenTextures(1, &cacheTexture->mTextureId);
    }

    Caches::getInstance().activeTexture(0);
    glBindTexture(GL_TEXTURE_2D, cacheTexture->mTextureId);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    // Initialize texture dimensions
    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
            GL_ALPHA, GL_UNSIGNED_BYTE, 0);

    const GLenum filtering = cacheTexture->mLinearFiltering ? GL_LINEAR : GL_NEAREST;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
        uint32_t* retOriginX, uint32_t* retOriginY) {
    cachedGlyph->mIsValid = false;
    // If the glyph is too tall, don't cache it
    if (glyph.fHeight + TEXTURE_BORDER_SIZE > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
        ALOGE("Font size to large to fit in cache. width, height = %i, %i",
                (int) glyph.fWidth, (int) glyph.fHeight);
        return;
    }

    // Now copy the bitmap into the cache texture
    uint32_t startX = 0;
    uint32_t startY = 0;

    bool bitmapFit = false;
    CacheTextureLine *cacheLine;
    for (uint32_t i = 0; i < mCacheLines.size(); i++) {
        bitmapFit = mCacheLines[i]->fitBitmap(glyph, &startX, &startY);
        if (bitmapFit) {
            cacheLine = mCacheLines[i];
            break;
        }
    }

    // If the new glyph didn't fit, flush the state so far and invalidate everything
    if (!bitmapFit) {
        flushAllAndInvalidate();

        // Try to fit it again
        for (uint32_t i = 0; i < mCacheLines.size(); i++) {
            bitmapFit = mCacheLines[i]->fitBitmap(glyph, &startX, &startY);
            if (bitmapFit) {
                cacheLine = mCacheLines[i];
                break;
            }
        }

        // if we still don't fit, something is wrong and we shouldn't draw
        if (!bitmapFit) {
            return;
        }
    }

    cachedGlyph->mCachedTextureLine = cacheLine;

    *retOriginX = startX;
    *retOriginY = startY;

    uint32_t endX = startX + glyph.fWidth;
    uint32_t endY = startY + glyph.fHeight;

    uint32_t cacheWidth = cacheLine->mMaxWidth;

    CacheTexture* cacheTexture = cacheLine->mCacheTexture;
    if (!cacheTexture->mTexture) {
        // Large-glyph texture memory is allocated only as needed
        allocateTextureMemory(cacheTexture);
    }

    uint8_t* cacheBuffer = cacheTexture->mTexture;
    uint8_t* bitmapBuffer = (uint8_t*) glyph.fImage;
    unsigned int stride = glyph.rowBytes();

    uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
    for (cacheX = startX, bX = 0; cacheX < endX; cacheX++, bX++) {
        for (cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY++) {
            uint8_t tempCol = bitmapBuffer[bY * stride + bX];
            cacheBuffer[cacheY * cacheWidth + cacheX] = mGammaTable[tempCol];
        }
    }

    cachedGlyph->mIsValid = true;
}

CacheTexture* FontRenderer::createCacheTexture(int width, int height, bool allocate) {
    uint8_t* textureMemory = NULL;
    CacheTexture* cacheTexture = new CacheTexture(textureMemory, width, height);

    if (allocate) {
        allocateTextureMemory(cacheTexture);
    }

    return cacheTexture;
}

void FontRenderer::initTextTexture() {
    for (uint32_t i = 0; i < mCacheLines.size(); i++) {
        delete mCacheLines[i];
    }
    mCacheLines.clear();

    if (mCacheTextureSmall) {
        delete mCacheTextureSmall;
        delete mCacheTexture128;
        delete mCacheTexture256;
        delete mCacheTexture512;
    }

    // Next, use other, separate caches for large glyphs.
    uint16_t maxWidth = 0;
    if (Caches::hasInstance()) {
        maxWidth = Caches::getInstance().maxTextureSize;
    }

    if (maxWidth > MAX_TEXT_CACHE_WIDTH || maxWidth == 0) {
        maxWidth = MAX_TEXT_CACHE_WIDTH;
    }

    mCacheTextureSmall = createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, true);
    mCacheTexture128 = createCacheTexture(maxWidth, 256, false);
    mCacheTexture256 = createCacheTexture(maxWidth, 256, false);
    mCacheTexture512 = createCacheTexture(maxWidth, 512, false);
    mCurrentCacheTexture = mCacheTextureSmall;

    mUploadTexture = false;
    // Split up our default cache texture into lines of certain widths
    int nextLine = 0;
    mCacheLines.push(new CacheTextureLine(mSmallCacheWidth, 18, nextLine, 0, mCacheTextureSmall));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(mSmallCacheWidth, 26, nextLine, 0, mCacheTextureSmall));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(mSmallCacheWidth, 26, nextLine, 0, mCacheTextureSmall));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(mSmallCacheWidth, 34, nextLine, 0, mCacheTextureSmall));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(mSmallCacheWidth, 34, nextLine, 0, mCacheTextureSmall));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(mSmallCacheWidth, 42, nextLine, 0, mCacheTextureSmall));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(mSmallCacheWidth, mSmallCacheHeight - nextLine,
            nextLine, 0, mCacheTextureSmall));

    //  The first cache is split into 2 lines of height 128, the rest have just one cache line.
    mCacheLines.push(new CacheTextureLine(maxWidth, 128, 0, 0, mCacheTexture128));
    mCacheLines.push(new CacheTextureLine(maxWidth, 128, 128, 0, mCacheTexture128));
    mCacheLines.push(new CacheTextureLine(maxWidth, 256, 0, 0, mCacheTexture256));
    mCacheLines.push(new CacheTextureLine(maxWidth, 512, 0, 0, mCacheTexture512));
}

// Avoid having to reallocate memory and render quad by quad
void FontRenderer::initVertexArrayBuffers() {
    uint32_t numIndices = mMaxNumberOfQuads * 6;
    uint32_t indexBufferSizeBytes = numIndices * sizeof(uint16_t);
    uint16_t* indexBufferData = (uint16_t*) malloc(indexBufferSizeBytes);

    // Four verts, two triangles , six indices per quad
    for (uint32_t i = 0; i < mMaxNumberOfQuads; i++) {
        int i6 = i * 6;
        int i4 = i * 4;

        indexBufferData[i6 + 0] = i4 + 0;
        indexBufferData[i6 + 1] = i4 + 1;
        indexBufferData[i6 + 2] = i4 + 2;

        indexBufferData[i6 + 3] = i4 + 0;
        indexBufferData[i6 + 4] = i4 + 2;
        indexBufferData[i6 + 5] = i4 + 3;
    }

    glGenBuffers(1, &mIndexBufferID);
    Caches::getInstance().bindIndicesBuffer(mIndexBufferID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSizeBytes, indexBufferData, GL_STATIC_DRAW);

    free(indexBufferData);

    uint32_t coordSize = 2;
    uint32_t uvSize = 2;
    uint32_t vertsPerQuad = 4;
    uint32_t vertexBufferSize = mMaxNumberOfQuads * vertsPerQuad * coordSize * uvSize;
    mTextMeshPtr = new float[vertexBufferSize];
}

// We don't want to allocate anything unless we actually draw text
void FontRenderer::checkInit() {
    if (mInitialized) {
        return;
    }

    initTextTexture();
    initVertexArrayBuffers();

    mInitialized = true;
}

void FontRenderer::checkTextureUpdate() {
    if (!mUploadTexture && mLastCacheTexture == mCurrentCacheTexture) {
        return;
    }

    Caches& caches = Caches::getInstance();
    GLuint lastTextureId = 0;
    // Iterate over all the cache lines and see which ones need to be updated
    for (uint32_t i = 0; i < mCacheLines.size(); i++) {
        CacheTextureLine* cl = mCacheLines[i];
        if (cl->mDirty && cl->mCacheTexture->mTexture != NULL) {
            CacheTexture* cacheTexture = cl->mCacheTexture;
            uint32_t xOffset = 0;
            uint32_t yOffset = cl->mCurrentRow;
            uint32_t width   = cl->mMaxWidth;
            uint32_t height  = cl->mMaxHeight;
            void* textureData = cacheTexture->mTexture + (yOffset * width);

            if (cacheTexture->mTextureId != lastTextureId) {
                caches.activeTexture(0);
                glBindTexture(GL_TEXTURE_2D, cacheTexture->mTextureId);
                lastTextureId = cacheTexture->mTextureId;
            }
            glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height,
                    GL_ALPHA, GL_UNSIGNED_BYTE, textureData);

            cl->mDirty = false;
        }
    }

    caches.activeTexture(0);
    glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->mTextureId);
    if (mLinearFiltering != mCurrentCacheTexture->mLinearFiltering) {
        const GLenum filtering = mLinearFiltering ? GL_LINEAR : GL_NEAREST;
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
        mCurrentCacheTexture->mLinearFiltering = mLinearFiltering;
    }
    mLastCacheTexture = mCurrentCacheTexture;

    mUploadTexture = false;
}

void FontRenderer::issueDrawCommand() {
    checkTextureUpdate();

    Caches& caches = Caches::getInstance();
    caches.bindIndicesBuffer(mIndexBufferID);
    if (!mDrawn) {
        float* buffer = mTextMeshPtr;
        int offset = 2;

        bool force = caches.unbindMeshBuffer();
        caches.bindPositionVertexPointer(force, caches.currentProgram->position, buffer);
        caches.bindTexCoordsVertexPointer(force, caches.currentProgram->texCoords,
                buffer + offset);
    }

    glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, NULL);

    mDrawn = true;
}

void FontRenderer::appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
        float x2, float y2, float u2, float v2, float x3, float y3, float u3, float v3,
        float x4, float y4, float u4, float v4, CacheTexture* texture) {
    if (texture != mCurrentCacheTexture) {
        if (mCurrentQuadIndex != 0) {
            // First, draw everything stored already which uses the previous texture
            issueDrawCommand();
            mCurrentQuadIndex = 0;
        }
        // Now use the new texture id
        mCurrentCacheTexture = texture;
    }

    const uint32_t vertsPerQuad = 4;
    const uint32_t floatsPerVert = 4;
    float* currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;

    (*currentPos++) = x1;
    (*currentPos++) = y1;
    (*currentPos++) = u1;
    (*currentPos++) = v1;

    (*currentPos++) = x2;
    (*currentPos++) = y2;
    (*currentPos++) = u2;
    (*currentPos++) = v2;

    (*currentPos++) = x3;
    (*currentPos++) = y3;
    (*currentPos++) = u3;
    (*currentPos++) = v3;

    (*currentPos++) = x4;
    (*currentPos++) = y4;
    (*currentPos++) = u4;
    (*currentPos++) = v4;

    mCurrentQuadIndex++;
}

void FontRenderer::appendMeshQuad(float x1, float y1, float u1, float v1,
        float x2, float y2, float u2, float v2, float x3, float y3, float u3, float v3,
        float x4, float y4, float u4, float v4, CacheTexture* texture) {

    if (mClip &&
            (x1 > mClip->right || y1 < mClip->top || x2 < mClip->left || y4 > mClip->bottom)) {
        return;
    }

    appendMeshQuadNoClip(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4, texture);

    if (mBounds) {
        mBounds->left = fmin(mBounds->left, x1);
        mBounds->top = fmin(mBounds->top, y3);
        mBounds->right = fmax(mBounds->right, x3);
        mBounds->bottom = fmax(mBounds->bottom, y1);
    }

    if (mCurrentQuadIndex == mMaxNumberOfQuads) {
        issueDrawCommand();
        mCurrentQuadIndex = 0;
    }
}

void FontRenderer::appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
        float x2, float y2, float u2, float v2, float x3, float y3, float u3, float v3,
        float x4, float y4, float u4, float v4, CacheTexture* texture) {

    appendMeshQuadNoClip(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4, texture);

    if (mBounds) {
        mBounds->left = fmin(mBounds->left, fmin(x1, fmin(x2, fmin(x3, x4))));
        mBounds->top = fmin(mBounds->top, fmin(y1, fmin(y2, fmin(y3, y4))));
        mBounds->right = fmax(mBounds->right, fmax(x1, fmax(x2, fmax(x3, x4))));
        mBounds->bottom = fmax(mBounds->bottom, fmax(y1, fmax(y2, fmax(y3, y4))));
    }

    if (mCurrentQuadIndex == mMaxNumberOfQuads) {
        issueDrawCommand();
        mCurrentQuadIndex = 0;
    }
}

uint32_t FontRenderer::getRemainingCacheCapacity() {
    uint32_t remainingCapacity = 0;
    float totalPixels = 0;
    for(uint32_t i = 0; i < mCacheLines.size(); i ++) {
         remainingCapacity += (mCacheLines[i]->mMaxWidth - mCacheLines[i]->mCurrentCol);
         totalPixels += mCacheLines[i]->mMaxWidth;
    }
    remainingCapacity = (remainingCapacity * 100) / totalPixels;
    return remainingCapacity;
}

void FontRenderer::precacheLatin(SkPaint* paint) {
    // Remaining capacity is measured in %
    uint32_t remainingCapacity = getRemainingCacheCapacity();
    uint32_t precacheIndex = 0;

    // We store a string with letters in a rough frequency of occurrence
    String16 l("eisarntolcdugpmhbyfvkwzxjq EISARNTOLCDUGPMHBYFVKWZXJQ,.?!()-+@;:'0123456789");

    size_t size = l.size();
    uint16_t latin[size];
    paint->utfToGlyphs(l.string(), SkPaint::kUTF16_TextEncoding, size * sizeof(char16_t), latin);

    while (remainingCapacity > 25 && precacheIndex < size) {
        mCurrentFont->getCachedGlyph(paint, TO_GLYPH(latin[precacheIndex]));
        remainingCapacity = getRemainingCacheCapacity();
        precacheIndex++;
    }
}

void FontRenderer::setFont(SkPaint* paint, uint32_t fontId, float fontSize) {
    uint32_t currentNumFonts = mActiveFonts.size();
    int flags = 0;
    if (paint->isFakeBoldText()) {
        flags |= Font::kFakeBold;
    }

    const float skewX = paint->getTextSkewX();
    uint32_t italicStyle = *(uint32_t*) &skewX;
    const float scaleXFloat = paint->getTextScaleX();
    uint32_t scaleX = *(uint32_t*) &scaleXFloat;
    SkPaint::Style style = paint->getStyle();
    const float strokeWidthFloat = paint->getStrokeWidth();
    uint32_t strokeWidth = *(uint32_t*) &strokeWidthFloat;
    mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle,
            scaleX, style, strokeWidth);

    const float maxPrecacheFontSize = 40.0f;
    bool isNewFont = currentNumFonts != mActiveFonts.size();

    if (isNewFont && fontSize <= maxPrecacheFontSize) {
        precacheLatin(paint);
    }
}

FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text,
        uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius) {
    checkInit();

    if (!mCurrentFont) {
        DropShadow image;
        image.width = 0;
        image.height = 0;
        image.image = NULL;
        image.penX = 0;
        image.penY = 0;
        return image;
    }

    mDrawn = false;
    mClip = NULL;
    mBounds = NULL;

    Rect bounds;
    mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds);

    uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius;
    uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius;
    uint8_t* dataBuffer = new uint8_t[paddedWidth * paddedHeight];

    for (uint32_t i = 0; i < paddedWidth * paddedHeight; i++) {
        dataBuffer[i] = 0;
    }

    int penX = radius - bounds.left;
    int penY = radius - bounds.bottom;

    mCurrentFont->render(paint, text, startIndex, len, numGlyphs, penX, penY,
            dataBuffer, paddedWidth, paddedHeight);
    blurImage(dataBuffer, paddedWidth, paddedHeight, radius);

    DropShadow image;
    image.width = paddedWidth;
    image.height = paddedHeight;
    image.image = dataBuffer;
    image.penX = penX;
    image.penY = penY;

    return image;
}

void FontRenderer::initRender(const Rect* clip, Rect* bounds) {
    checkInit();

    mDrawn = false;
    mBounds = bounds;
    mClip = clip;
}

void FontRenderer::finishRender() {
    mBounds = NULL;
    mClip = NULL;

    if (mCurrentQuadIndex != 0) {
        issueDrawCommand();
        mCurrentQuadIndex = 0;
    }
}

bool FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text,
        uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, Rect* bounds) {
    if (!mCurrentFont) {
        ALOGE("No font set");
        return false;
    }

    initRender(clip, bounds);
    mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y);
    finishRender();

    return mDrawn;
}

bool FontRenderer::renderPosText(SkPaint* paint, const Rect* clip, const char *text,
        uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y,
        const float* positions, Rect* bounds) {
    if (!mCurrentFont) {
        ALOGE("No font set");
        return false;
    }

    initRender(clip, bounds);
    mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y, positions);
    finishRender();

    return mDrawn;
}

bool FontRenderer::renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text,
        uint32_t startIndex, uint32_t len, int numGlyphs, SkPath* path,
        float hOffset, float vOffset, Rect* bounds) {
    if (!mCurrentFont) {
        ALOGE("No font set");
        return false;
    }

    initRender(clip, bounds);
    mCurrentFont->render(paint, text, startIndex, len, numGlyphs, path, hOffset, vOffset);
    finishRender();

    return mDrawn;
}

void FontRenderer::computeGaussianWeights(float* weights, int32_t radius) {
    // Compute gaussian weights for the blur
    // e is the euler's number
    float e = 2.718281828459045f;
    float pi = 3.1415926535897932f;
    // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 )
    // x is of the form [-radius .. 0 .. radius]
    // and sigma varies with radius.
    // Based on some experimental radius values and sigma's
    // we approximately fit sigma = f(radius) as
    // sigma = radius * 0.3  + 0.6
    // The larger the radius gets, the more our gaussian blur
    // will resemble a box blur since with large sigma
    // the gaussian curve begins to lose its shape
    float sigma = 0.3f * (float) radius + 0.6f;

    // Now compute the coefficints
    // We will store some redundant values to save some math during
    // the blur calculations
    // precompute some values
    float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma);
    float coeff2 = - 1.0f / (2.0f * sigma * sigma);

    float normalizeFactor = 0.0f;
    for (int32_t r = -radius; r <= radius; r ++) {
        float floatR = (float) r;
        weights[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2);
        normalizeFactor += weights[r + radius];
    }

    //Now we need to normalize the weights because all our coefficients need to add up to one
    normalizeFactor = 1.0f / normalizeFactor;
    for (int32_t r = -radius; r <= radius; r ++) {
        weights[r + radius] *= normalizeFactor;
    }
}

void FontRenderer::horizontalBlur(float* weights, int32_t radius,
        const uint8_t* source, uint8_t* dest, int32_t width, int32_t height) {
    float blurredPixel = 0.0f;
    float currentPixel = 0.0f;

    for (int32_t y = 0; y < height; y ++) {

        const uint8_t* input = source + y * width;
        uint8_t* output = dest + y * width;

        for (int32_t x = 0; x < width; x ++) {
            blurredPixel = 0.0f;
            const float* gPtr = weights;
            // Optimization for non-border pixels
            if (x > radius && x < (width - radius)) {
                const uint8_t *i = input + (x - radius);
                for (int r = -radius; r <= radius; r ++) {
                    currentPixel = (float) (*i);
                    blurredPixel += currentPixel * gPtr[0];
                    gPtr++;
                    i++;
                }
            } else {
                for (int32_t r = -radius; r <= radius; r ++) {
                    // Stepping left and right away from the pixel
                    int validW = x + r;
                    if (validW < 0) {
                        validW = 0;
                    }
                    if (validW > width - 1) {
                        validW = width - 1;
                    }

                    currentPixel = (float) input[validW];
                    blurredPixel += currentPixel * gPtr[0];
                    gPtr++;
                }
            }
            *output = (uint8_t)blurredPixel;
            output ++;
        }
    }
}

void FontRenderer::verticalBlur(float* weights, int32_t radius,
        const uint8_t* source, uint8_t* dest, int32_t width, int32_t height) {
    float blurredPixel = 0.0f;
    float currentPixel = 0.0f;

    for (int32_t y = 0; y < height; y ++) {

        uint8_t* output = dest + y * width;

        for (int32_t x = 0; x < width; x ++) {
            blurredPixel = 0.0f;
            const float* gPtr = weights;
            const uint8_t* input = source + x;
            // Optimization for non-border pixels
            if (y > radius && y < (height - radius)) {
                const uint8_t *i = input + ((y - radius) * width);
                for (int32_t r = -radius; r <= radius; r ++) {
                    currentPixel = (float)(*i);
                    blurredPixel += currentPixel * gPtr[0];
                    gPtr++;
                    i += width;
                }
            } else {
                for (int32_t r = -radius; r <= radius; r ++) {
                    int validH = y + r;
                    // Clamp to zero and width
                    if (validH < 0) {
                        validH = 0;
                    }
                    if (validH > height - 1) {
                        validH = height - 1;
                    }

                    const uint8_t *i = input + validH * width;
                    currentPixel = (float) (*i);
                    blurredPixel += currentPixel * gPtr[0];
                    gPtr++;
                }
            }
            *output = (uint8_t) blurredPixel;
            output ++;
        }
    }
}


void FontRenderer::blurImage(uint8_t *image, int32_t width, int32_t height, int32_t radius) {
    float *gaussian = new float[2 * radius + 1];
    computeGaussianWeights(gaussian, radius);

    uint8_t* scratch = new uint8_t[width * height];

    horizontalBlur(gaussian, radius, image, scratch, width, height);
    verticalBlur(gaussian, radius, scratch, image, width, height);

    delete[] gaussian;
    delete[] scratch;
}

}; // namespace uirenderer
}; // namespace android
