rsFont.cpp revision c9fa30536fb41f0166153561388b7c42f7cb85a0
1d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 2d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk/* 3d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * Copyright (C) 2009 The Android Open Source Project 4d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * 5d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License"); 6d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * you may not use this file except in compliance with the License. 7d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * You may obtain a copy of the License at 8d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * 9d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * http://www.apache.org/licenses/LICENSE-2.0 10d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * 11d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software 12d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS, 13d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * See the License for the specific language governing permissions and 15d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk * limitations under the License. 16d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk */ 17d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 18d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST 19d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include "rsContext.h" 20d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#else 21d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include "rsContextHostStub.h" 22d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#endif 23d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 24d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include "rsFont.h" 25d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include "rsProgramFragment.h" 26c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk#include <cutils/properties.h> 27d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include FT_BITMAP_H 28d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 29d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include <GLES/gl.h> 30d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include <GLES/glext.h> 31d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include <GLES2/gl2.h> 32d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include <GLES2/gl2ext.h> 33d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 34d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukusing namespace android; 35d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukusing namespace android::renderscript; 36d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 37d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFont::Font(Context *rsc) : ObjectBase(rsc), mCachedGlyphs(NULL) 38d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 39a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mAllocFile = __FILE__; 40a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mAllocLine = __LINE__; 41d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mInitialized = false; 42d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mHasKerning = false; 433659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk mFace = NULL; 44d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 45d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 46d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukbool Font::init(const char *name, uint32_t fontSize, uint32_t dpi) 47d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 48d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mInitialized) { 49d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Reinitialization of fonts not supported"); 50d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 51d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 52d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 53d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk String8 fontsDir("/fonts/"); 54d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk String8 fullPath(getenv("ANDROID_ROOT")); 55d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk fullPath += fontsDir; 56d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk fullPath += name; 57d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 58a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Error error = FT_New_Face(mRSC->mStateFont.getLib(), fullPath.string(), 0, &mFace); 59d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(error) { 60d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Unable to initialize font %s", fullPath.string()); 61d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 62d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 63d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 64d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontName = name; 65d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontSize = fontSize; 66d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mDpi = dpi; 67d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 68d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk error = FT_Set_Char_Size(mFace, fontSize * 64, 0, dpi, 0); 69d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(error) { 70d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Unable to set font size on %s", fullPath.string()); 71d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 72d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 73d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 74d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mHasKerning = FT_HAS_KERNING(mFace); 75d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 76d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mInitialized = true; 77d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return true; 78d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 79d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 80d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid Font::invalidateTextureCache() 81d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 82d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCachedGlyphs.size(); i ++) { 83d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCachedGlyphs.valueAt(i)->mIsValid = false; 84d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 85d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 86d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 87d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y) 88d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 89d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk FontState *state = &mRSC->mStateFont; 90d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 91d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int nPenX = x + glyph->mBitmapLeft; 92d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight; 93d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 94d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk state->appendMeshQuad(nPenX, nPenY, 0, 95d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinU, glyph->mBitmapMaxV, 96d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 97d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nPenX + (int)glyph->mBitmapWidth, nPenY, 0, 98d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMaxU, glyph->mBitmapMaxV, 99d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 100d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nPenX + (int)glyph->mBitmapWidth, nPenY - (int)glyph->mBitmapHeight, 0, 101d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMaxU, glyph->mBitmapMinV, 102d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 103d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nPenX, nPenY - (int)glyph->mBitmapHeight, 0, 104d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinU, glyph->mBitmapMinV); 105d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 106d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 107d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid Font::renderUTF(const char *text, uint32_t len, uint32_t start, int numGlyphs, int x, int y) 108d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 109d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!mInitialized || numGlyphs == 0 || text == NULL || len == 0) { 110d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 111d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 112d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 113d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int penX = x, penY = y; 114d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int glyphsLeft = 1; 115d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(numGlyphs > 0) { 116d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyphsLeft = numGlyphs; 117d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 118d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 119d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t index = start; 120d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t nextIndex = 0; 121d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 122d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk while (glyphsLeft > 0) { 123d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 124d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int32_t utfChar = utf32_at(text, len, index, &nextIndex); 125d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 126d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Reached the end of the string or encountered 127d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(utfChar < 0) { 128d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk break; 129d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 130d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 131d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Move to the next character in the array 132d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk index = nextIndex; 133d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 13401bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk CachedGlyphInfo *cachedGlyph = getCachedUTFChar(utfChar); 135d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 136d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage 137d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(cachedGlyph->mIsValid) { 138d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk drawCachedGlyph(cachedGlyph, penX, penY); 139d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 140d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 141d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk penX += (cachedGlyph->mAdvance.x >> 6); 142d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 143d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // If we were given a specific number of glyphs, decrement 144d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(numGlyphs > 0) { 145d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyphsLeft --; 146d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 147d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 148d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 149d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 15001bcef6115dc6230b16d9d8e120e35279f46cfd5Alex SakhartchoukFont::CachedGlyphInfo* Font::getCachedUTFChar(int32_t utfChar) { 15101bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk 15201bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk CachedGlyphInfo *cachedGlyph = mCachedGlyphs.valueFor((uint32_t)utfChar); 15301bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk if(cachedGlyph == NULL) { 15401bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk cachedGlyph = cacheGlyph((uint32_t)utfChar); 15501bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk } 15601bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk // Is the glyph still in texture cache? 15701bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk if(!cachedGlyph->mIsValid) { 15801bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk updateGlyphCache(cachedGlyph); 15901bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk } 16001bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk 16101bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk return cachedGlyph; 16201bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk} 16301bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk 164d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid Font::updateGlyphCache(CachedGlyphInfo *glyph) 165d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 166a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Error error = FT_Load_Glyph( mFace, glyph->mGlyphIndex, FT_LOAD_RENDER ); 167a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(error) { 168a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk LOGE("Couldn't load glyph."); 169a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk return; 170a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 171d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 172a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mAdvance = mFace->glyph->advance; 173a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mBitmapLeft = mFace->glyph->bitmap_left; 174a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mBitmapTop = mFace->glyph->bitmap_top; 175d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 176a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Bitmap *bitmap = &mFace->glyph->bitmap; 177d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 178d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Now copy the bitmap into the cache texture 179d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t startX = 0; 180d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t startY = 0; 181d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 182d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Let the font state figure out where to put the bitmap 183d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk FontState *state = &mRSC->mStateFont; 184a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mIsValid = state->cacheBitmap(bitmap, &startX, &startY); 185d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 186d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!glyph->mIsValid) { 187d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 188d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 189d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 190a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk uint32_t endX = startX + bitmap->width; 191a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk uint32_t endY = startY + bitmap->rows; 192d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 193d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinX = startX; 194d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinY = startY; 195a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mBitmapWidth = bitmap->width; 196a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mBitmapHeight = bitmap->rows; 197d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 198d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t cacheWidth = state->getCacheTextureType()->getDimX(); 199d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t cacheHeight = state->getCacheTextureType()->getDimY(); 200d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 201d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinU = (float)startX / (float)cacheWidth; 202d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinV = (float)startY / (float)cacheHeight; 203d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMaxU = (float)endX / (float)cacheWidth; 204d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMaxV = (float)endY / (float)cacheHeight; 205d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 206d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 207d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFont::CachedGlyphInfo *Font::cacheGlyph(uint32_t glyph) 208d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 209d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk CachedGlyphInfo *newGlyph = new CachedGlyphInfo(); 210d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCachedGlyphs.add(glyph, newGlyph); 211d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 212d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk newGlyph->mGlyphIndex = FT_Get_Char_Index(mFace, glyph); 213d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk newGlyph->mIsValid = false; 214d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 215d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk updateGlyphCache(newGlyph); 216d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 217d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return newGlyph; 218d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 219d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 220d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFont * Font::create(Context *rsc, const char *name, uint32_t fontSize, uint32_t dpi) 221d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 22235b96445f8bb4536e29ace64417710ed90527a56Alex Sakhartchouk rsc->mStateFont.checkInit(); 223d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Vector<Font*> &activeFonts = rsc->mStateFont.mActiveFonts; 224d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 225d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < activeFonts.size(); i ++) { 226d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Font *ithFont = activeFonts[i]; 227d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(ithFont->mFontName == name && ithFont->mFontSize == fontSize && ithFont->mDpi == dpi) { 228d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return ithFont; 229d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 230d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 231d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 232d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Font *newFont = new Font(rsc); 233d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk bool isInitialized = newFont->init(name, fontSize, dpi); 234d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(isInitialized) { 235d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk activeFonts.push(newFont); 23601bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk rsc->mStateFont.precacheLatin(newFont); 237d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return newFont; 238d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 239d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 240d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk delete newFont; 241d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return NULL; 242d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 243d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 244d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 245d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFont::~Font() 246d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 247d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mFace) { 248d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk FT_Done_Face(mFace); 249d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 250d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 251d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for (uint32_t ct = 0; ct < mRSC->mStateFont.mActiveFonts.size(); ct++) { 252d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if (mRSC->mStateFont.mActiveFonts[ct] == this) { 253d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->mStateFont.mActiveFonts.removeAt(ct); 254d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk break; 255d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 256d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 257d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 258d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCachedGlyphs.size(); i ++) { 259d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk CachedGlyphInfo *glyph = mCachedGlyphs.valueAt(i); 260d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk delete glyph; 261d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 262d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 263d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 264d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFontState::FontState() 265d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 266d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mInitialized = false; 267d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mMaxNumberOfQuads = 1024; 268d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex = 0; 269d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC = NULL; 2703659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk mLibrary = NULL; 271ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk setFontColor(0.1f, 0.1f, 0.1f, 1.0f); 272c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk 273c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk // Get the renderer properties 274c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk char property[PROPERTY_VALUE_MAX]; 275c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk 276c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk // Get the gamma 277c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk float gamma = DEFAULT_TEXT_GAMMA; 278c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk if (property_get(PROPERTY_TEXT_GAMMA, property, NULL) > 0) { 279c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk LOGD(" Setting text gamma to %s", property); 280c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk gamma = atof(property); 281c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk } else { 282c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk LOGD(" Using default text gamma of %.2f", DEFAULT_TEXT_GAMMA); 283c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk } 284c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk 285c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk // Get the black gamma threshold 286c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk int blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD; 287c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) { 288c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk LOGD(" Setting text black gamma threshold to %s", property); 289c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk blackThreshold = atoi(property); 290c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk } else { 291c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk LOGD(" Using default text black gamma threshold of %d", 292c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD); 293c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk } 294c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mBlackThreshold = (float)(blackThreshold) / 255.0f; 295c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk 296c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk // Get the white gamma threshold 297c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk int whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD; 298c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) { 299c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk LOGD(" Setting text white gamma threshold to %s", property); 300c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk whiteThreshold = atoi(property); 301c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk } else { 302c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk LOGD(" Using default white black gamma threshold of %d", 303c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD); 304c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk } 305c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mWhiteThreshold = (float)(whiteThreshold) / 255.0f; 306c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk 307c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk // Compute the gamma tables 308c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mBlackGamma = gamma; 309c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mWhiteGamma = 1.0f / gamma; 310d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 311d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 312d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFontState::~FontState() 313d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 314d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 315d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk delete mCacheLines[i]; 316d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 317d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 318d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk rsAssert(!mActiveFonts.size()); 319d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 320d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 321a1ccecd965c07c2739f1258989526051a010bdabAlex SakhartchoukFT_Library FontState::getLib() 322d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 323d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!mLibrary) { 324a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Error error = FT_Init_FreeType(&mLibrary); 325d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(error) { 326d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Unable to initialize freetype"); 327a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk return NULL; 328d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 329d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 3303659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk 331a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk return mLibrary; 332a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk} 333d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 334a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchoukvoid FontState::init(Context *rsc) 335a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk{ 336a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mRSC = rsc; 337d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 338d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 339d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::flushAllAndInvalidate() 340d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 341d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mCurrentQuadIndex != 0) { 342d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk issueDrawCommand(); 343d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex = 0; 344d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 345d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mActiveFonts.size(); i ++) { 346d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mActiveFonts[i]->invalidateTextureCache(); 347d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 348d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 349d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines[i]->mCurrentCol = 0; 350d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 351d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 352d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 353d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukbool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) 354d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 355d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // If the glyph is too tall, don't cache it 356d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if((uint32_t)bitmap->rows > mCacheLines[mCacheLines.size()-1]->mMaxHeight) { 357d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Font size to large to fit in cache. width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows); 358d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 359d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 360d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 361d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Now copy the bitmap into the cache texture 362d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t startX = 0; 363d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t startY = 0; 364d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 365d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk bool bitmapFit = false; 366d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 367d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk bitmapFit = mCacheLines[i]->fitBitmap(bitmap, &startX, &startY); 368d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(bitmapFit) { 369d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk break; 370d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 371d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 372d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 373d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // If the new glyph didn't fit, flush the state so far and invalidate everything 374d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!bitmapFit) { 375d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk flushAllAndInvalidate(); 376d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 377d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Try to fit it again 378d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 379d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk bitmapFit = mCacheLines[i]->fitBitmap(bitmap, &startX, &startY); 380d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(bitmapFit) { 381d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk break; 382d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 383d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 384d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 385d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // if we still don't fit, something is wrong and we shouldn't draw 386d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!bitmapFit) { 387d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Bitmap doesn't fit in cache. width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows); 388d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 389d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 390d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 391d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 392d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk *retOriginX = startX; 393d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk *retOriginY = startY; 394d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 395d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t endX = startX + bitmap->width; 396d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t endY = startY + bitmap->rows; 397d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 398d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t cacheWidth = getCacheTextureType()->getDimX(); 399d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 400d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk unsigned char *cacheBuffer = (unsigned char*)mTextTexture->getPtr(); 401d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk unsigned char *bitmapBuffer = bitmap->buffer; 402d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 403d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0; 404d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(cacheX = startX, bX = 0; cacheX < endX; cacheX ++, bX ++) { 405d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(cacheY = startY, bY = 0; cacheY < endY; cacheY ++, bY ++) { 406d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk unsigned char tempCol = bitmapBuffer[bY * bitmap->width + bX]; 407d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk cacheBuffer[cacheY*cacheWidth + cacheX] = tempCol; 408d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 409d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 410d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 411d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // This will dirty the texture and the shader so next time 412d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // we draw it will upload the data 413d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextTexture->deferedUploadToTexture(mRSC, false, 0); 414383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk mFontShaderF->bindTexture(mRSC, 0, mTextTexture.get()); 415d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 416d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Some debug code 417d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk /*for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 418d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Cache Line: H: %u Empty Space: %f", 419d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines[i]->mMaxHeight, 420d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (1.0f - (float)mCacheLines[i]->mCurrentCol/(float)mCacheLines[i]->mMaxWidth)*100.0f); 421d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 422d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk }*/ 423d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 424d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return true; 425d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 426d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 427d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::initRenderState() 428d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 429e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk String8 shaderString("varying vec4 varTex0;\n"); 430e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk shaderString.append("void main() {\n"); 431e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk shaderString.append(" lowp vec4 col = UNI_Color;\n"); 432e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk shaderString.append(" col.a = texture2D(UNI_Tex0, varTex0.xy).a;\n"); 433c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk shaderString.append(" col.a = pow(col.a, UNI_Gamma);\n"); 434e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk shaderString.append(" gl_FragColor = col;\n"); 435e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk shaderString.append("}\n"); 436e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk 437e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk const Element *colorElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4); 438c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk const Element *gammaElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1); 439e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk mRSC->mStateElement.elementBuilderBegin(); 440e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk mRSC->mStateElement.elementBuilderAdd(colorElem, "Color", 1); 441c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mRSC->mStateElement.elementBuilderAdd(gammaElem, "Gamma", 1); 442e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk const Element *constInput = mRSC->mStateElement.elementBuilderCreate(mRSC); 443e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk 444e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk Type *inputType = new Type(mRSC); 445e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk inputType->setElement(constInput); 446e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk inputType->setDimX(1); 447e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk inputType->compute(); 448e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk 449e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk uint32_t tmp[4]; 450e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk tmp[0] = RS_PROGRAM_PARAM_CONSTANT; 451e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk tmp[1] = (uint32_t)inputType; 452e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT; 453e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk tmp[3] = 1; 454e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk 455e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk mFontShaderFConstant.set(new Allocation(mRSC, inputType)); 456e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(), 457e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk shaderString.length(), tmp, 4); 458d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontShaderF.set(pf); 459383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk mFontShaderF->bindAllocation(mRSC, mFontShaderFConstant.get(), 0); 460d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 461d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Sampler *sampler = new Sampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST, 462d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP); 463d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontSampler.set(sampler); 464383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk mFontShaderF->bindSampler(mRSC, 0, sampler); 465d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 466d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ProgramStore *fontStore = new ProgramStore(mRSC); 467d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore.set(fontStore); 468d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore->setDepthFunc(RS_DEPTH_FUNC_ALWAYS); 469d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore->setBlendFunc(RS_BLEND_SRC_SRC_ALPHA, RS_BLEND_DST_ONE_MINUS_SRC_ALPHA); 470d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore->setDitherEnable(false); 471d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore->setDepthMask(false); 472d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 473d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 474d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::initTextTexture() 475d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 476d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *alphaElem = Element::create(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1); 477d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 478d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // We will allocate a texture to initially hold 32 character bitmaps 479d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Type *texType = new Type(mRSC); 480d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk texType->setElement(alphaElem); 481d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk texType->setDimX(1024); 482d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk texType->setDimY(256); 483d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk texType->compute(); 484d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 485d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Allocation *cacheAlloc = new Allocation(mRSC, texType); 486d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextTexture.set(cacheAlloc); 487d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextTexture->deferedUploadToTexture(mRSC, false, 0); 488d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 489d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Split up our cache texture into lines of certain widths 490d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int nextLine = 0; 491d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(16, texType->getDimX(), nextLine, 0)); 492d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 493d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(24, texType->getDimX(), nextLine, 0)); 494d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 49501bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(24, texType->getDimX(), nextLine, 0)); 49601bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 497d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(32, texType->getDimX(), nextLine, 0)); 498d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 499d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(32, texType->getDimX(), nextLine, 0)); 500d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 501d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(40, texType->getDimX(), nextLine, 0)); 502d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 503d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(texType->getDimY() - nextLine, texType->getDimX(), nextLine, 0)); 504d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 505d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 506d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk// Avoid having to reallocate memory and render quad by quad 507d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::initVertexArrayBuffers() 508d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 509d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Now lets write index data 510d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *indexElem = Element::create(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1); 511d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Type *indexType = new Type(mRSC); 512d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t numIndicies = mMaxNumberOfQuads * 6; 513d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexType->setDimX(numIndicies); 514d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexType->setElement(indexElem); 515d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexType->compute(); 516d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 517d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Allocation *indexAlloc = new Allocation(mRSC, indexType); 518d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr(); 519d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 520d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Four verts, two triangles , six indices per quad 521d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mMaxNumberOfQuads; i ++) { 522d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int i6 = i * 6; 523d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int i4 = i * 4; 524d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 525d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 0] = i4 + 0; 526d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 1] = i4 + 1; 527d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 2] = i4 + 2; 528d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 529d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 3] = i4 + 0; 530d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 4] = i4 + 2; 531d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 5] = i4 + 3; 532d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 533d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 534d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexAlloc->deferedUploadToBufferObject(mRSC); 535d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mIndexBuffer.set(indexAlloc); 536d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 537d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3); 538d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2); 539d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 540d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *elemArray[2]; 541d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk elemArray[0] = posElem; 542d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk elemArray[1] = texElem; 543d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 544d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk String8 posName("position"); 545d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk String8 texName("texture0"); 546d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 547d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const char *nameArray[2]; 548d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nameArray[0] = posName.string(); 549d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nameArray[1] = texName.string(); 550d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t lengths[2]; 551d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk lengths[0] = posName.size(); 552d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk lengths[1] = texName.size(); 55346e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams uint32_t arraySizes[2] = {1, 1}; 554d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 55546e45548dc80e801139c9ccc2f2aa927e7f35027Jason Sams const Element *vertexDataElem = Element::create(mRSC, 2, elemArray, nameArray, lengths, arraySizes); 556d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 557d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Type *vertexDataType = new Type(mRSC); 558d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk vertexDataType->setDimX(mMaxNumberOfQuads * 4); 559d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk vertexDataType->setElement(vertexDataElem); 560d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk vertexDataType->compute(); 561d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 562d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Allocation *vertexAlloc = new Allocation(mRSC, vertexDataType); 563d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextMeshPtr = (float*)vertexAlloc->getPtr(); 564d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 565d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mVertexArray.set(vertexAlloc); 566d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 567d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 568d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk// We don't want to allocate anything unless we actually draw text 569d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::checkInit() 570d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 571d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mInitialized) { 572d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 573d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 574d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 575d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk initTextTexture(); 576d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk initRenderState(); 577d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 578d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk initVertexArrayBuffers(); 579d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 58035b96445f8bb4536e29ace64417710ed90527a56Alex Sakhartchouk // We store a string with letters in a rough frequency of occurrence 58135b96445f8bb4536e29ace64417710ed90527a56Alex Sakhartchouk mLatinPrecache = String8(" eisarntolcdugpmhbyfvkwzxjq"); 58235b96445f8bb4536e29ace64417710ed90527a56Alex Sakhartchouk mLatinPrecache += String8("EISARNTOLCDUGPMHBYFVKWZXJQ"); 58335b96445f8bb4536e29ace64417710ed90527a56Alex Sakhartchouk mLatinPrecache += String8(",.?!()-+@;:`'"); 58435b96445f8bb4536e29ace64417710ed90527a56Alex Sakhartchouk mLatinPrecache += String8("0123456789"); 58535b96445f8bb4536e29ace64417710ed90527a56Alex Sakhartchouk 586d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mInitialized = true; 587d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 588d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 589d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::issueDrawCommand() { 590d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 591d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ObjectBaseRef<const ProgramVertex> tmpV(mRSC->getVertex()); 592d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setVertex(mRSC->getDefaultProgramVertex()); 593d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 594d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk ObjectBaseRef<const ProgramRaster> tmpR(mRSC->getRaster()); 595d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk mRSC->setRaster(mRSC->getDefaultProgramRaster()); 596d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk 597d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ObjectBaseRef<const ProgramFragment> tmpF(mRSC->getFragment()); 598d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragment(mFontShaderF.get()); 599d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 600d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ObjectBaseRef<const ProgramStore> tmpPS(mRSC->getFragmentStore()); 601d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragmentStore(mFontProgramStore.get()); 602d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 603c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk if(mConstantsDirty) { 604c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mFontShaderFConstant->data(mRSC, &mConstants, sizeof(mConstants)); 605c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstantsDirty = false; 606ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk } 607ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk 608d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if (!mRSC->setupCheck()) { 609d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setVertex((ProgramVertex *)tmpV.get()); 610d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk mRSC->setRaster((ProgramRaster *)tmpR.get()); 611d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragment((ProgramFragment *)tmpF.get()); 612d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragmentStore((ProgramStore *)tmpPS.get()); 613d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 614d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 615d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 616d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float *vtx = (float*)mVertexArray->getPtr(); 617d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float *tex = vtx + 3; 618d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 619d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk VertexArray va; 620886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk va.add(GL_FLOAT, 3, 20, false, (uint32_t)vtx, "ATTRIB_position"); 621886f11ade9dde05485cb11c0d67d87f76a428f6cAlex Sakhartchouk va.add(GL_FLOAT, 2, 20, false, (uint32_t)tex, "ATTRIB_texture0"); 622d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk va.setupGL2(mRSC, &mRSC->mStateVertexArray, &mRSC->mShaderCache); 623d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 624d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mIndexBuffer->uploadCheck(mRSC); 625d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID()); 626d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, (uint16_t *)(0)); 627d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 628d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Reset the state 629d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setVertex((ProgramVertex *)tmpV.get()); 630d18c744a37441311c9b65254a35db456835adad3Alex Sakhartchouk mRSC->setRaster((ProgramRaster *)tmpR.get()); 631d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragment((ProgramFragment *)tmpF.get()); 632d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragmentStore((ProgramStore *)tmpPS.get()); 633d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 634d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 635d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::appendMeshQuad(float x1, float y1, float z1, 636d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float u1, float v1, 637d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float x2, float y2, float z2, 638d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float u2, float v2, 639d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float x3, float y3, float z3, 640d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float u3, float v3, 641d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float x4, float y4, float z4, 642d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float u4, float v4) 643d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 644d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const uint32_t vertsPerQuad = 4; 645d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const uint32_t floatsPerVert = 5; 646d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert; 647d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 648d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Cull things that are off the screen 649d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float width = (float)mRSC->getWidth(); 650d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float height = (float)mRSC->getHeight(); 651d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 652d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(x1 > width || y1 < 0.0f || x2 < 0 || y4 > height) { 653d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 654d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 655d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 656d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk /*LOGE("V0 x: %f y: %f z: %f", x1, y1, z1); 657d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("V1 x: %f y: %f z: %f", x2, y2, z2); 658d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("V2 x: %f y: %f z: %f", x3, y3, z3); 659d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("V3 x: %f y: %f z: %f", x4, y4, z4);*/ 660d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 661d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = x1; 662d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = y1; 663d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = z1; 664d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = u1; 665d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = v1; 666d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 667d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = x2; 668d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = y2; 669d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = z2; 670d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = u2; 671d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = v2; 672d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 673d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = x3; 674d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = y3; 675d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = z3; 676d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = u3; 677d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = v3; 678d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 679d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = x4; 680d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = y4; 681d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = z4; 682d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = u4; 683d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = v4; 684d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 685d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex ++; 686d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 687d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mCurrentQuadIndex == mMaxNumberOfQuads) { 688d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk issueDrawCommand(); 689d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex = 0; 690d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 691d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 692d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 69301bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchoukuint32_t FontState::getRemainingCacheCapacity() { 69401bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk uint32_t remainingCapacity = 0; 69535b96445f8bb4536e29ace64417710ed90527a56Alex Sakhartchouk uint32_t totalPixels = 0; 69601bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 69701bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk remainingCapacity += (mCacheLines[i]->mMaxWidth - mCacheLines[i]->mCurrentCol); 69801bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk totalPixels += mCacheLines[i]->mMaxWidth; 69901bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk } 70001bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk remainingCapacity = (remainingCapacity * 100) / totalPixels; 70101bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk return remainingCapacity; 70201bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk} 70301bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk 70401bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchoukvoid FontState::precacheLatin(Font *font) { 70501bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk // Remaining capacity is measured in % 70601bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk uint32_t remainingCapacity = getRemainingCacheCapacity(); 70701bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk uint32_t precacheIdx = 0; 70801bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk while(remainingCapacity > 25 && precacheIdx < mLatinPrecache.size()) { 70901bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk font->getCachedUTFChar((int32_t)mLatinPrecache[precacheIdx]); 71001bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk remainingCapacity = getRemainingCacheCapacity(); 71101bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk precacheIdx ++; 71201bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk } 71301bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk} 71401bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk 71501bcef6115dc6230b16d9d8e120e35279f46cfd5Alex Sakhartchouk 716d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::renderText(const char *text, uint32_t len, uint32_t startIndex, int numGlyphs, int x, int y) 717d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 718d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk checkInit(); 719d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 720d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Render code here 721d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Font *currentFont = mRSC->getFont(); 722a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(!currentFont) { 723a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(!mDefault.get()) { 724a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mDefault.set(Font::create(mRSC, "DroidSans.ttf", 16, 96)); 725a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 726a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk currentFont = mDefault.get(); 727a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 7283659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk if(!currentFont) { 7293659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk LOGE("Unable to initialize any fonts"); 7303659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk return; 7313659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk } 7323659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk 733d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk currentFont->renderUTF(text, len, startIndex, numGlyphs, x, y); 734d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 735d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mCurrentQuadIndex != 0) { 736d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk issueDrawCommand(); 737d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex = 0; 738d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 739d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 740d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 741d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::renderText(const char *text, int x, int y) 742d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 743d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t textLen = strlen(text); 744d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk renderText(text, textLen, 0, -1, x, y); 745d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 746d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 747d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::renderText(Allocation *alloc, int x, int y) 748d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 749d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!alloc) { 750d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 751d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 752d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 753d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const char *text = (const char *)alloc->getPtr(); 754d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t allocSize = alloc->getType()->getSizeBytes(); 755d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk renderText(text, allocSize, 0, -1, x, y); 756d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 757d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 758d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::renderText(Allocation *alloc, uint32_t start, int len, int x, int y) 759d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 760d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!alloc) { 761d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 762d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 763d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 764d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const char *text = (const char *)alloc->getPtr(); 765d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t allocSize = alloc->getType()->getSizeBytes(); 766d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk renderText(text, allocSize, start, len, x, y); 767d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 768d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 7699fc9f0375a92fe22fecb3782b18a5c6060a07290Alex Sakhartchoukvoid FontState::setFontColor(float r, float g, float b, float a) { 770c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstants.mFontColor[0] = r; 771c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstants.mFontColor[1] = g; 772c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstants.mFontColor[2] = b; 773c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstants.mFontColor[3] = a; 774c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk 775c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstants.mGamma = 1.0f; 776c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk const int luminance = (r * 2.0f + g * 5.0f + b) / 8.0f; 777c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk if (luminance <= mBlackThreshold) { 778c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstants.mGamma = mBlackGamma; 779c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk } else if (luminance >= mWhiteThreshold) { 780c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstants.mGamma = mWhiteGamma; 781c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk } 782c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk mConstantsDirty = true; 7839fc9f0375a92fe22fecb3782b18a5c6060a07290Alex Sakhartchouk} 7849fc9f0375a92fe22fecb3782b18a5c6060a07290Alex Sakhartchouk 785ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchoukvoid FontState::getFontColor(float *r, float *g, float *b, float *a) const { 786c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk *r = mConstants.mFontColor[0]; 787c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk *g = mConstants.mFontColor[1]; 788c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk *b = mConstants.mFontColor[2]; 789c9fa30536fb41f0166153561388b7c42f7cb85a0Alex Sakhartchouk *a = mConstants.mFontColor[3]; 790ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk} 791ca5a454e022caec6c6d3cbb404cc09ea095ba97aAlex Sakhartchouk 792d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::deinit(Context *rsc) 793d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 794a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mInitialized = false; 795a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk 79601b7d2995f9cbd33a9ccdf861fe959743a4b9954Stephen Hines mFontShaderFConstant.clear(); 79701b7d2995f9cbd33a9ccdf861fe959743a4b9954Stephen Hines 798a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mIndexBuffer.clear(); 799a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mVertexArray.clear(); 800a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk 801a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mFontShaderF.clear(); 802a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mFontSampler.clear(); 803a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mFontProgramStore.clear(); 804a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk 805a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mTextTexture.clear(); 806a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 807a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk delete mCacheLines[i]; 808d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 809a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mCacheLines.clear(); 810d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 811d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mDefault.clear(); 812a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk 8133659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk Vector<Font*> fontsToDereference = mActiveFonts; 8143659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk for(uint32_t i = 0; i < fontsToDereference.size(); i ++) { 8153659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk fontsToDereference[i]->zeroUserRef(); 8163659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk } 8173659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk 818a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(mLibrary) { 819a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Done_FreeType( mLibrary ); 8203659d94d345c333bf98070dbe7b6daee233225a9Alex Sakhartchouk mLibrary = NULL; 821a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 822d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 823d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 824d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouknamespace android { 825d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouknamespace renderscript { 826d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 827d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukRsFont rsi_FontCreateFromFile(Context *rsc, char const *name, uint32_t fontSize, uint32_t dpi) 828d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 829a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk Font *newFont = Font::create(rsc, name, fontSize, dpi); 830a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(newFont) { 831a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk newFont->incUserRef(); 832a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 833a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk return newFont; 834d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 835d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 836d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} // renderscript 837d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} // android 838