
/*
 * Copyright (C) 2009 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.
 */

#include "rsContext.h"
#include "rs.h"
#include "rsFont.h"
#include "rsProgramFragment.h"
#include "rsMesh.h"
#ifdef __ANDROID__
#include <cutils/properties.h>
#endif

#ifndef ANDROID_RS_SERIALIZE
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_BITMAP_H
#endif //ANDROID_RS_SERIALIZE

namespace android {
namespace renderscript {

Font::Font(Context *rsc) : ObjectBase(rsc), mCachedGlyphs(NULL) {
    mInitialized = false;
    mHasKerning = false;
    mFace = nullptr;
}

bool Font::init(const char *name, float fontSize, uint32_t dpi, const void *data, uint32_t dataLen) {
#ifndef ANDROID_RS_SERIALIZE
    if (mInitialized) {
        ALOGE("Reinitialization of fonts not supported");
        return false;
    }

    FT_Error error = 0;
    if (data != nullptr && dataLen > 0) {
        error = FT_New_Memory_Face(mRSC->mStateFont.getLib(), (const FT_Byte*)data, dataLen, 0, &mFace);
    } else {
        error = FT_New_Face(mRSC->mStateFont.getLib(), name, 0, &mFace);
    }

    if (error) {
        ALOGE("Unable to initialize font %s", name);
        return false;
    }

    mFontName = rsuCopyString(name);
    mFontSize = fontSize;
    mDpi = dpi;

    error = FT_Set_Char_Size(mFace, (FT_F26Dot6)(fontSize * 64.0f), 0, dpi, 0);
    if (error) {
        ALOGE("Unable to set font size on %s", name);
        return false;
    }

    mHasKerning = FT_HAS_KERNING(mFace);

    mInitialized = true;
#endif //ANDROID_RS_SERIALIZE
    return true;
}

void Font::preDestroy() const {
    for (uint32_t ct = 0; ct < mRSC->mStateFont.mActiveFonts.size(); ct++) {
        if (mRSC->mStateFont.mActiveFonts[ct] == this) {
            mRSC->mStateFont.mActiveFonts.removeAt(ct);
            break;
        }
    }
}

void Font::invalidateTextureCache() {
    for (uint32_t i = 0; i < mCachedGlyphs.size(); i ++) {
        mCachedGlyphs.valueAt(i)->mIsValid = false;
    }
}

void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y) {
    FontState *state = &mRSC->mStateFont;

    int32_t nPenX = x + glyph->mBitmapLeft;
    int32_t nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight;

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

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

    state->appendMeshQuad(nPenX, nPenY, 0, u1, v2,
                          nPenX + width, nPenY, 0, u2, v2,
                          nPenX + width, nPenY - height, 0, u2, v1,
                          nPenX, nPenY - height, 0, u1, v1);
}

void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int32_t x, int32_t y,
                           uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH) {
    int32_t nPenX = x + glyph->mBitmapLeft;
    int32_t nPenY = y + glyph->mBitmapTop;

    uint32_t endX = glyph->mBitmapMinX + glyph->mBitmapWidth;
    uint32_t endY = glyph->mBitmapMinY + glyph->mBitmapHeight;

    FontState *state = &mRSC->mStateFont;
    uint32_t cacheWidth = state->getCacheTextureType()->getDimX();
    const uint8_t* cacheBuffer = state->mCacheBuffer;

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

void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y, Rect *bounds) {
    int32_t nPenX = x + glyph->mBitmapLeft;
    int32_t nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight;

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

    // 0, 0 is top left, so bottom is a positive number
    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::renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
                     uint32_t start, int32_t numGlyphs,
                     RenderMode mode, Rect *bounds,
                     uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
    if (!mInitialized || numGlyphs == 0 || text == nullptr || len == 0) {
        return;
    }

    if (mode == Font::MEASURE) {
        if (bounds == nullptr) {
            ALOGE("No return rectangle provided to measure text");
            return;
        }
        // Reset min and max of the bounding box to something large
        bounds->set(1e6, -1e6, 1e6, -1e6);
    }

    int32_t penX = x, penY = y;
    int32_t glyphsLeft = 1;
    if (numGlyphs > 0) {
        glyphsLeft = numGlyphs;
    }

    size_t index = start;
    size_t nextIndex = 0;

    while (glyphsLeft > 0) {

        int32_t utfChar = utf32_from_utf8_at(text, len, index, &nextIndex);

        // Reached the end of the string or encountered
        if (utfChar < 0) {
            break;
        }

        // Move to the next character in the array
        index = nextIndex;

        CachedGlyphInfo *cachedGlyph = getCachedUTFChar(utfChar);

        // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
        if (cachedGlyph->mIsValid) {
            switch (mode) {
            case FRAMEBUFFER:
                drawCachedGlyph(cachedGlyph, penX, penY);
                break;
            case BITMAP:
                drawCachedGlyph(cachedGlyph, penX, penY, bitmap, bitmapW, bitmapH);
                break;
            case MEASURE:
                measureCachedGlyph(cachedGlyph, penX, penY, bounds);
                break;
            }
        }

        penX += (cachedGlyph->mAdvanceX >> 6);

        // If we were given a specific number of glyphs, decrement
        if (numGlyphs > 0) {
            glyphsLeft --;
        }
    }
}

Font::CachedGlyphInfo* Font::getCachedUTFChar(int32_t utfChar) {

    CachedGlyphInfo *cachedGlyph = mCachedGlyphs.valueFor((uint32_t)utfChar);
    if (cachedGlyph == nullptr) {
        cachedGlyph = cacheGlyph((uint32_t)utfChar);
    }
    // Is the glyph still in texture cache?
    if (!cachedGlyph->mIsValid) {
        updateGlyphCache(cachedGlyph);
    }

    return cachedGlyph;
}

void Font::updateGlyphCache(CachedGlyphInfo *glyph) {
#ifndef ANDROID_RS_SERIALIZE
    FT_Error error = FT_Load_Glyph( mFace, glyph->mGlyphIndex, FT_LOAD_RENDER );
    if (error) {
        ALOGE("Couldn't load glyph.");
        return;
    }

    glyph->mAdvanceX = mFace->glyph->advance.x;
    glyph->mAdvanceY = mFace->glyph->advance.y;
    glyph->mBitmapLeft = mFace->glyph->bitmap_left;
    glyph->mBitmapTop = mFace->glyph->bitmap_top;

    FT_Bitmap *bitmap = &mFace->glyph->bitmap;

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

    // Let the font state figure out where to put the bitmap
    FontState *state = &mRSC->mStateFont;
    glyph->mIsValid = state->cacheBitmap(bitmap, &startX, &startY);

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

    uint32_t endX = startX + bitmap->width;
    uint32_t endY = startY + bitmap->rows;

    glyph->mBitmapMinX = startX;
    glyph->mBitmapMinY = startY;
    glyph->mBitmapWidth = bitmap->width;
    glyph->mBitmapHeight = bitmap->rows;

    uint32_t cacheWidth = state->getCacheTextureType()->getDimX();
    uint32_t cacheHeight = state->getCacheTextureType()->getDimY();

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

Font::CachedGlyphInfo *Font::cacheGlyph(uint32_t glyph) {
    CachedGlyphInfo *newGlyph = new CachedGlyphInfo();
    mCachedGlyphs.add(glyph, newGlyph);
#ifndef ANDROID_RS_SERIALIZE
    newGlyph->mGlyphIndex = FT_Get_Char_Index(mFace, glyph);
    newGlyph->mIsValid = false;
#endif //ANDROID_RS_SERIALIZE
    updateGlyphCache(newGlyph);

    return newGlyph;
}

Font * Font::create(Context *rsc, const char *name, float fontSize, uint32_t dpi,
                    const void *data, uint32_t dataLen) {
    rsc->mStateFont.checkInit();
    Vector<Font*> &activeFonts = rsc->mStateFont.mActiveFonts;

    for (uint32_t i = 0; i < activeFonts.size(); i ++) {
        Font *ithFont = activeFonts[i];
        if (ithFont->mFontName == name && ithFont->mFontSize == fontSize && ithFont->mDpi == dpi) {
            return ithFont;
        }
    }

    Font *newFont = new Font(rsc);
    bool isInitialized = newFont->init(name, fontSize, dpi, data, dataLen);
    if (isInitialized) {
        activeFonts.push(newFont);
        rsc->mStateFont.precacheLatin(newFont);
        return newFont;
    }

    ObjectBase::checkDelete(newFont);
    return nullptr;
}

Font::~Font() {
#ifndef ANDROID_RS_SERIALIZE
    if (mFace) {
        FT_Done_Face(mFace);
    }
#endif

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

FontState::FontState() {
    mInitialized = false;
    mMaxNumberOfQuads = 1024;
    mCurrentQuadIndex = 0;
    mRSC = nullptr;
#ifndef ANDROID_RS_SERIALIZE
    mLibrary = nullptr;
#endif //ANDROID_RS_SERIALIZE

    float gamma = DEFAULT_TEXT_GAMMA;
    int32_t blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
    int32_t whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;

#ifdef __ANDROID__
    // Get the renderer properties
    char property[PROPERTY_VALUE_MAX];

    // Get the gamma
    if (property_get(PROPERTY_TEXT_GAMMA, property, nullptr) > 0) {
        gamma = atof(property);
    }

    // Get the black gamma threshold
    if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, nullptr) > 0) {
        blackThreshold = atoi(property);
    }

    // Get the white gamma threshold
    if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, nullptr) > 0) {
        whiteThreshold = atoi(property);
    }
#endif

    mBlackThreshold = (float)(blackThreshold) / 255.0f;
    mWhiteThreshold = (float)(whiteThreshold) / 255.0f;

    // Compute the gamma tables
    mBlackGamma = gamma;
    mWhiteGamma = 1.0f / gamma;

    setFontColor(0.1f, 0.1f, 0.1f, 1.0f);
}

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

    rsAssert(!mActiveFonts.size());
}
#ifndef ANDROID_RS_SERIALIZE
FT_Library FontState::getLib() {
    if (!mLibrary) {
        FT_Error error = FT_Init_FreeType(&mLibrary);
        if (error) {
            ALOGE("Unable to initialize freetype");
            return nullptr;
        }
    }

    return mLibrary;
}
#endif //ANDROID_RS_SERIALIZE


void FontState::init(Context *rsc) {
    mRSC = rsc;
}

void FontState::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;
    }
}

#ifndef ANDROID_RS_SERIALIZE
bool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) {
    // If the glyph is too tall, don't cache it
    if ((uint32_t)bitmap->rows > mCacheLines[mCacheLines.size()-1]->mMaxHeight) {
        ALOGE("Font size to large to fit in cache. width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows);
        return false;
    }

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

    bool bitmapFit = false;
    for (uint32_t i = 0; i < mCacheLines.size(); i ++) {
        bitmapFit = mCacheLines[i]->fitBitmap(bitmap, &startX, &startY);
        if (bitmapFit) {
            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(bitmap, &startX, &startY);
            if (bitmapFit) {
                break;
            }
        }

        // if we still don't fit, something is wrong and we shouldn't draw
        if (!bitmapFit) {
            ALOGE("Bitmap doesn't fit in cache. width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows);
            return false;
        }
    }

    *retOriginX = startX;
    *retOriginY = startY;

    uint32_t endX = startX + bitmap->width;
    uint32_t endY = startY + bitmap->rows;

    uint32_t cacheWidth = getCacheTextureType()->getDimX();

    uint8_t *cacheBuffer = mCacheBuffer;
    uint8_t *bitmapBuffer = bitmap->buffer;

    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 * bitmap->width + bX];
            cacheBuffer[cacheY*cacheWidth + cacheX] = tempCol;
        }
    }

    // This will dirty the texture and the shader so next time
    // we draw it will upload the data

    mRSC->mHal.funcs.allocation.data2D(mRSC, mTextTexture.get(), 0, 0, 0,
        RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, mCacheWidth, mCacheHeight,
        mCacheBuffer, mCacheWidth*mCacheHeight, mCacheWidth);

    mFontShaderF->bindTexture(mRSC, 0, mTextTexture.get());

    // Some debug code
    /*for (uint32_t i = 0; i < mCacheLines.size(); i ++) {
        ALOGE("Cache Line: H: %u Empty Space: %f",
             mCacheLines[i]->mMaxHeight,
              (1.0f - (float)mCacheLines[i]->mCurrentCol/(float)mCacheLines[i]->mMaxWidth)*100.0f);

    }*/

    return true;
}
#endif //ANDROID_RS_SERIALIZE

void FontState::initRenderState() {
    const char *shaderString = "varying vec2 varTex0;\n"
                               "void main() {\n"
                               "  lowp vec4 col = UNI_Color;\n"
                               "  col.a = texture2D(UNI_Tex0, varTex0.xy).a;\n"
                               "  col.a = pow(col.a, UNI_Gamma);\n"
                               "  gl_FragColor = col;\n"
                               "}\n";

    const char *textureNames[] = { "Tex0" };
    const size_t textureNamesLengths[] = { 4 };
    size_t numTextures = sizeof(textureNamesLengths)/sizeof(*textureNamesLengths);

    ObjectBaseRef<const Element> colorElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32,
                                                                RS_KIND_USER, false, 4);
    ObjectBaseRef<const Element> gammaElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32,
                                                                RS_KIND_USER, false, 1);

    const char *ebn1[] = { "Color", "Gamma" };
    const Element *ebe1[] = {colorElem.get(), gammaElem.get()};
    ObjectBaseRef<const Element> constInput = Element::create(mRSC, 2, ebe1, ebn1);
    ObjectBaseRef<Type> inputType = Type::getTypeRef(mRSC, constInput.get(), 1);

    uintptr_t tmp[4];
    tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
    tmp[1] = (uintptr_t)inputType.get();
    tmp[2] = RS_PROGRAM_PARAM_TEXTURE_TYPE;
    tmp[3] = RS_TEXTURE_2D;

    mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType.get(),
                                                          RS_ALLOCATION_USAGE_SCRIPT |
                                                          RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS));
    ProgramFragment *pf = new ProgramFragment(mRSC, shaderString, strlen(shaderString),
                                              textureNames, numTextures, textureNamesLengths,
                                              tmp, 4);
    mFontShaderF.set(pf);
    mFontShaderF->bindAllocation(mRSC, mFontShaderFConstant.get(), 0);

    mFontSampler.set(Sampler::getSampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
                                         RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP,
                                         RS_SAMPLER_CLAMP).get());
    mFontShaderF->bindSampler(mRSC, 0, mFontSampler.get());

    mFontProgramStore.set(ProgramStore::getProgramStore(mRSC, true, true, true, true,
                                                        false, false,
                                                        RS_BLEND_SRC_SRC_ALPHA,
                                                        RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
                                                        RS_DEPTH_FUNC_ALWAYS).get());
    mFontProgramStore->init();
}

void FontState::initTextTexture() {
    ObjectBaseRef<const Element> alphaElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_8,
                                                                RS_KIND_PIXEL_A, true, 1);

    // We will allocate a texture to initially hold 32 character bitmaps
    mCacheHeight = 256;
    mCacheWidth = 1024;
    ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), mCacheWidth, mCacheHeight);

    mCacheBuffer = new uint8_t[mCacheWidth * mCacheHeight];


    Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType.get(),
                                RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE);
    mTextTexture.set(cacheAlloc);

    // Split up our cache texture into lines of certain widths
    int32_t nextLine = 0;
    mCacheLines.push(new CacheTextureLine(16, texType->getDimX(), nextLine, 0));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(24, texType->getDimX(), nextLine, 0));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(24, texType->getDimX(), nextLine, 0));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(32, texType->getDimX(), nextLine, 0));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(32, texType->getDimX(), nextLine, 0));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(40, texType->getDimX(), nextLine, 0));
    nextLine += mCacheLines.top()->mMaxHeight;
    mCacheLines.push(new CacheTextureLine(texType->getDimY() - nextLine, texType->getDimX(), nextLine, 0));
}

// Avoid having to reallocate memory and render quad by quad
void FontState::initVertexArrayBuffers() {
    // Now lets write index data
    ObjectBaseRef<const Element> indexElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
    ObjectBaseRef<Type> indexType = Type::getTypeRef(mRSC, indexElem.get(), mMaxNumberOfQuads * 6);

    Allocation *indexAlloc = Allocation::createAllocation(mRSC, indexType.get(),
                                                          RS_ALLOCATION_USAGE_SCRIPT |
                                                          RS_ALLOCATION_USAGE_GRAPHICS_VERTEX);
    uint16_t *indexPtr = (uint16_t*)mRSC->mHal.funcs.allocation.lock1D(mRSC, indexAlloc);

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

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

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

    indexAlloc->sendDirty(mRSC);

    ObjectBaseRef<const Element> posElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
    ObjectBaseRef<const Element> texElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);

    const char *ebn1[] = { "position", "texture0" };
    const Element *ebe1[] = {posElem.get(), texElem.get()};
    ObjectBaseRef<const Element> vertexDataElem = Element::create(mRSC, 2, ebe1, ebn1);

    ObjectBaseRef<Type> vertexDataType = Type::getTypeRef(mRSC, vertexDataElem.get(), mMaxNumberOfQuads * 4);

    Allocation *vertexAlloc = Allocation::createAllocation(mRSC, vertexDataType.get(),
                                                           RS_ALLOCATION_USAGE_SCRIPT);
    mTextMeshPtr = (float*)mRSC->mHal.funcs.allocation.lock1D(mRSC, vertexAlloc);

    mMesh.set(new Mesh(mRSC, 1, 1));
    mMesh->setVertexBuffer(vertexAlloc, 0);
    mMesh->setPrimitive(indexAlloc, RS_PRIMITIVE_TRIANGLE, 0);
    mMesh->init();
    mRSC->mHal.funcs.allocation.unlock1D(mRSC, indexAlloc);
    mRSC->mHal.funcs.allocation.unlock1D(mRSC, vertexAlloc);
}

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

    initTextTexture();
    initRenderState();

    initVertexArrayBuffers();

    // We store a string with letters in a rough frequency of occurrence
    mLatinPrecache = " eisarntolcdugpmhbyfvkwzxjq"
                     "EISARNTOLCDUGPMHBYFVKWZXJQ"
                     ",.?!()-+@;:`'0123456789";
    mInitialized = true;
}

void FontState::issueDrawCommand() {
    Context::PushState ps(mRSC);

    mRSC->setProgramVertex(mRSC->getDefaultProgramVertex());
    mRSC->setProgramRaster(mRSC->getDefaultProgramRaster());
    mRSC->setProgramFragment(mFontShaderF.get());
    mRSC->setProgramStore(mFontProgramStore.get());

    if (mConstantsDirty) {
        mFontShaderFConstant->data(mRSC, 0, 0, 1, &mConstants, sizeof(mConstants));
        mConstantsDirty = false;
    }

    if (!mRSC->setupCheck()) {
        return;
    }

    mMesh->renderPrimitiveRange(mRSC, 0, 0, mCurrentQuadIndex * 6);
}

void FontState::appendMeshQuad(float x1, float y1, float z1,
                               float u1, float v1,
                               float x2, float y2, float z2,
                               float u2, float v2,
                               float x3, float y3, float z3,
                               float u3, float v3,
                               float x4, float y4, float z4,
                               float u4, float v4) {
    const uint32_t vertsPerQuad = 4;
    const uint32_t floatsPerVert = 6;
    float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;

    if (x1 > mSurfaceWidth || y1 < 0.0f || x2 < 0 || y4 > mSurfaceHeight) {
        return;
    }

    /*LOGE("V0 x: %f y: %f z: %f", x1, y1, z1);
    ALOGE("V1 x: %f y: %f z: %f", x2, y2, z2);
    ALOGE("V2 x: %f y: %f z: %f", x3, y3, z3);
    ALOGE("V3 x: %f y: %f z: %f", x4, y4, z4);*/

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

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

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

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

    mCurrentQuadIndex ++;

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

uint32_t FontState::getRemainingCacheCapacity() {
    uint32_t remainingCapacity = 0;
    uint32_t 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 FontState::precacheLatin(Font *font) {
    // Remaining capacity is measured in %
    uint32_t remainingCapacity = getRemainingCacheCapacity();
    uint32_t precacheIdx = 0;
    const size_t l = strlen(mLatinPrecache);
    while ((remainingCapacity > 25) && (precacheIdx < l)) {
        font->getCachedUTFChar((int32_t)mLatinPrecache[precacheIdx]);
        remainingCapacity = getRemainingCacheCapacity();
        precacheIdx ++;
    }
}


void FontState::renderText(const char *text, uint32_t len, int32_t x, int32_t y,
                           uint32_t startIndex, int32_t numGlyphs,
                           Font::RenderMode mode,
                           Font::Rect *bounds,
                           uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH) {
    checkInit();

    // Render code here
    Font *currentFont = mRSC->getFont();
    if (!currentFont) {
        if (!mDefault.get()) {
            char fullPath[1024];
            const char * root = getenv("ANDROID_ROOT");
            rsAssert(strlen(root) < 256);
            strcpy(fullPath, root);
            strcat(fullPath, "/fonts/Roboto-Regular.ttf");
            mDefault.set(Font::create(mRSC, fullPath, 8, mRSC->getDPI()));
        }
        currentFont = mDefault.get();
    }
    if (!currentFont) {
        ALOGE("Unable to initialize any fonts");
        return;
    }

    // Cull things that are off the screen
    mSurfaceWidth = (float)mRSC->getCurrentSurfaceWidth();
    mSurfaceHeight = (float)mRSC->getCurrentSurfaceHeight();

    currentFont->renderUTF(text, len, x, y, startIndex, numGlyphs,
                           mode, bounds, bitmap, bitmapW, bitmapH);

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

void FontState::measureText(const char *text, uint32_t len, Font::Rect *bounds) {
    renderText(text, len, 0, 0, 0, -1, Font::MEASURE, bounds);
    bounds->bottom = - bounds->bottom;
    bounds->top = - bounds->top;
}

void FontState::setFontColor(float r, float g, float b, float a) {
    mConstants.mFontColor[0] = r;
    mConstants.mFontColor[1] = g;
    mConstants.mFontColor[2] = b;
    mConstants.mFontColor[3] = a;

    mConstants.mGamma = 1.0f;
    const float luminance = (r * 2.0f + g * 5.0f + b) / 8.0f;
    if (luminance <= mBlackThreshold) {
        mConstants.mGamma = mBlackGamma;
    } else if (luminance >= mWhiteThreshold) {
        mConstants.mGamma = mWhiteGamma;
    }

    mConstantsDirty = true;
}

void FontState::getFontColor(float *r, float *g, float *b, float *a) const {
    *r = mConstants.mFontColor[0];
    *g = mConstants.mFontColor[1];
    *b = mConstants.mFontColor[2];
    *a = mConstants.mFontColor[3];
}

void FontState::deinit(Context *rsc) {
    mInitialized = false;

    mFontShaderFConstant.clear();

    mMesh.clear();

    mFontShaderF.clear();
    mFontSampler.clear();
    mFontProgramStore.clear();

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

    mDefault.clear();
#ifndef ANDROID_RS_SERIALIZE
    if (mLibrary) {
        FT_Done_FreeType( mLibrary );
        mLibrary = nullptr;
    }
#endif //ANDROID_RS_SERIALIZE
}

#ifndef ANDROID_RS_SERIALIZE
bool FontState::CacheTextureLine::fitBitmap(FT_Bitmap_ *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) {
    if ((uint32_t)bitmap->rows > mMaxHeight) {
        return false;
    }

    if (mCurrentCol + (uint32_t)bitmap->width < mMaxWidth) {
        *retOriginX = mCurrentCol;
        *retOriginY = mCurrentRow;
        mCurrentCol += bitmap->width;
        mDirty = true;
       return true;
    }

    return false;
}
#endif //ANDROID_RS_SERIALIZE

RsFont rsi_FontCreateFromFile(Context *rsc,
                              char const *name, size_t name_length,
                              float fontSize, uint32_t dpi) {
    Font *newFont = Font::create(rsc, name, fontSize, dpi);
    if (newFont) {
        newFont->incUserRef();
    }
    return newFont;
}

RsFont rsi_FontCreateFromMemory(Context *rsc,
                                char const *name, size_t name_length,
                                float fontSize, uint32_t dpi,
                                const void *data, size_t data_length) {
    Font *newFont = Font::create(rsc, name, fontSize, dpi, data, data_length);
    if (newFont) {
        newFont->incUserRef();
    }
    return newFont;
}

} // namespace renderscript
} // namespace android
