rsFont.cpp revision a1ccecd965c07c2739f1258989526051a010bdab
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" 26d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include FT_BITMAP_H 27d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 28d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include <GLES/gl.h> 29d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include <GLES/glext.h> 30d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include <GLES2/gl2.h> 31d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk#include <GLES2/gl2ext.h> 32d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 33d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukusing namespace android; 34d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukusing namespace android::renderscript; 35d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 36d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFont::Font(Context *rsc) : ObjectBase(rsc), mCachedGlyphs(NULL) 37d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 38a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mAllocFile = __FILE__; 39a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mAllocLine = __LINE__; 40d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mInitialized = false; 41d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mHasKerning = false; 42d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 43d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 44d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukbool Font::init(const char *name, uint32_t fontSize, uint32_t dpi) 45d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 46d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mInitialized) { 47d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Reinitialization of fonts not supported"); 48d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 49d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 50d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 51d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk String8 fontsDir("/fonts/"); 52d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk String8 fullPath(getenv("ANDROID_ROOT")); 53d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk fullPath += fontsDir; 54d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk fullPath += name; 55d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 56a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Error error = FT_New_Face(mRSC->mStateFont.getLib(), fullPath.string(), 0, &mFace); 57d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(error) { 58d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Unable to initialize font %s", fullPath.string()); 59d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 60d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 61d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 62d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontName = name; 63d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontSize = fontSize; 64d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mDpi = dpi; 65d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 66d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk //LOGE("Font initialized: %s", fullPath.string()); 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 134d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk CachedGlyphInfo *cachedGlyph = mCachedGlyphs.valueFor((uint32_t)utfChar); 135d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 136d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(cachedGlyph == NULL) { 137d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk cachedGlyph = cacheGlyph((uint32_t)utfChar); 138d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 139d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Is the glyph still in texture cache? 140d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!cachedGlyph->mIsValid) { 141d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk updateGlyphCache(cachedGlyph); 142d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 143d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 144d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage 145d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(cachedGlyph->mIsValid) { 146d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk drawCachedGlyph(cachedGlyph, penX, penY); 147d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 148d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 149d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk penX += (cachedGlyph->mAdvance.x >> 6); 150d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 151d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // If we were given a specific number of glyphs, decrement 152d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(numGlyphs > 0) { 153d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyphsLeft --; 154d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 155d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 156d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 157d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 158d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid Font::updateGlyphCache(CachedGlyphInfo *glyph) 159d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 160a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Error error = FT_Load_Glyph( mFace, glyph->mGlyphIndex, FT_LOAD_RENDER ); 161a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(error) { 162a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk LOGE("Couldn't load glyph."); 163a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk return; 164a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 165d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 166a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mAdvance = mFace->glyph->advance; 167a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mBitmapLeft = mFace->glyph->bitmap_left; 168a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mBitmapTop = mFace->glyph->bitmap_top; 169d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 170a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Bitmap *bitmap = &mFace->glyph->bitmap; 171d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 172d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Now copy the bitmap into the cache texture 173d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t startX = 0; 174d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t startY = 0; 175d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 176d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Let the font state figure out where to put the bitmap 177d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk FontState *state = &mRSC->mStateFont; 178a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mIsValid = state->cacheBitmap(bitmap, &startX, &startY); 179d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 180d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!glyph->mIsValid) { 181d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 182d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 183d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 184a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk uint32_t endX = startX + bitmap->width; 185a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk uint32_t endY = startY + bitmap->rows; 186d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 187d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinX = startX; 188d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinY = startY; 189a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mBitmapWidth = bitmap->width; 190a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk glyph->mBitmapHeight = bitmap->rows; 191d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 192d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t cacheWidth = state->getCacheTextureType()->getDimX(); 193d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t cacheHeight = state->getCacheTextureType()->getDimY(); 194d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 195d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinU = (float)startX / (float)cacheWidth; 196d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMinV = (float)startY / (float)cacheHeight; 197d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMaxU = (float)endX / (float)cacheWidth; 198d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glyph->mBitmapMaxV = (float)endY / (float)cacheHeight; 199d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 200d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 201d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFont::CachedGlyphInfo *Font::cacheGlyph(uint32_t glyph) 202d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 203d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk CachedGlyphInfo *newGlyph = new CachedGlyphInfo(); 204d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCachedGlyphs.add(glyph, newGlyph); 205d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 206d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk newGlyph->mGlyphIndex = FT_Get_Char_Index(mFace, glyph); 207d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk newGlyph->mIsValid = false; 208d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 209d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk //LOGE("Glyph = %c, face index: %u", (unsigned char)glyph, newGlyph->mGlyphIndex); 210d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 211d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk updateGlyphCache(newGlyph); 212d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 213d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return newGlyph; 214d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 215d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 216d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFont * Font::create(Context *rsc, const char *name, uint32_t fontSize, uint32_t dpi) 217d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 218d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Vector<Font*> &activeFonts = rsc->mStateFont.mActiveFonts; 219d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 220d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < activeFonts.size(); i ++) { 221d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Font *ithFont = activeFonts[i]; 222d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(ithFont->mFontName == name && ithFont->mFontSize == fontSize && ithFont->mDpi == dpi) { 223d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return ithFont; 224d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 225d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 226d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 227d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Font *newFont = new Font(rsc); 228d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk bool isInitialized = newFont->init(name, fontSize, dpi); 229d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(isInitialized) { 230d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk activeFonts.push(newFont); 231d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return newFont; 232d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 233d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 234d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk delete newFont; 235d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return NULL; 236d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 237d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 238d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 239d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFont::~Font() 240d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 241d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mFace) { 242d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk FT_Done_Face(mFace); 243d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 244d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 245d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for (uint32_t ct = 0; ct < mRSC->mStateFont.mActiveFonts.size(); ct++) { 246d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if (mRSC->mStateFont.mActiveFonts[ct] == this) { 247d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->mStateFont.mActiveFonts.removeAt(ct); 248d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk break; 249d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 250d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 251d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 252d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCachedGlyphs.size(); i ++) { 253d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk CachedGlyphInfo *glyph = mCachedGlyphs.valueAt(i); 254d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk delete glyph; 255d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 256d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 257d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 258d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFontState::FontState() 259d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 260d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mInitialized = false; 261d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mMaxNumberOfQuads = 1024; 262d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex = 0; 263d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC = NULL; 264d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 265d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 266d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukFontState::~FontState() 267d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 268d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 269d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk delete mCacheLines[i]; 270d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 271d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 272d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk rsAssert(!mActiveFonts.size()); 273d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 274d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 275a1ccecd965c07c2739f1258989526051a010bdabAlex SakhartchoukFT_Library FontState::getLib() 276d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 277d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!mLibrary) { 278a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Error error = FT_Init_FreeType(&mLibrary); 279d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(error) { 280d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Unable to initialize freetype"); 281a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk return NULL; 282d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 283d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 284a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk return mLibrary; 285a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk} 286d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 287a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchoukvoid FontState::init(Context *rsc) 288a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk{ 289a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk //getLib(); 290d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 291a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mRSC = rsc; 292d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 293d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 294d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::flushAllAndInvalidate() 295d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 296d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mCurrentQuadIndex != 0) { 297d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk issueDrawCommand(); 298d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex = 0; 299d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 300d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mActiveFonts.size(); i ++) { 301d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mActiveFonts[i]->invalidateTextureCache(); 302d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 303d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 304d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines[i]->mCurrentCol = 0; 305d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 306d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 307d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 308d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukbool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) 309d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 310d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // If the glyph is too tall, don't cache it 311d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if((uint32_t)bitmap->rows > mCacheLines[mCacheLines.size()-1]->mMaxHeight) { 312d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Font size to large to fit in cache. width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows); 313d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 314d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 315d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 316d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Now copy the bitmap into the cache texture 317d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t startX = 0; 318d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t startY = 0; 319d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 320d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk bool bitmapFit = false; 321d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 322d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk bitmapFit = mCacheLines[i]->fitBitmap(bitmap, &startX, &startY); 323d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(bitmapFit) { 324d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk break; 325d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 326d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 327d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 328d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // If the new glyph didn't fit, flush the state so far and invalidate everything 329d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!bitmapFit) { 330d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk flushAllAndInvalidate(); 331d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 332d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Try to fit it again 333d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 334d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk bitmapFit = mCacheLines[i]->fitBitmap(bitmap, &startX, &startY); 335d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(bitmapFit) { 336d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk break; 337d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 338d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 339d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 340d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // if we still don't fit, something is wrong and we shouldn't draw 341d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!bitmapFit) { 342d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Bitmap doesn't fit in cache. width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows); 343d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return false; 344d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 345d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 346d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 347d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk *retOriginX = startX; 348d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk *retOriginY = startY; 349d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 350d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t endX = startX + bitmap->width; 351d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t endY = startY + bitmap->rows; 352d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 353d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk //LOGE("Bitmap width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows); 354d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 355d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t cacheWidth = getCacheTextureType()->getDimX(); 356d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 357d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk unsigned char *cacheBuffer = (unsigned char*)mTextTexture->getPtr(); 358d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk unsigned char *bitmapBuffer = bitmap->buffer; 359d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 360d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0; 361d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(cacheX = startX, bX = 0; cacheX < endX; cacheX ++, bX ++) { 362d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(cacheY = startY, bY = 0; cacheY < endY; cacheY ++, bY ++) { 363d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk unsigned char tempCol = bitmapBuffer[bY * bitmap->width + bX]; 364d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk cacheBuffer[cacheY*cacheWidth + cacheX] = tempCol; 365d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 366d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 367d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 368d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // This will dirty the texture and the shader so next time 369d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // we draw it will upload the data 370d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextTexture->deferedUploadToTexture(mRSC, false, 0); 371d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontShaderF->bindTexture(0, mTextTexture.get()); 372d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 373d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Some debug code 374d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk /*for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 375d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("Cache Line: H: %u Empty Space: %f", 376d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines[i]->mMaxHeight, 377d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (1.0f - (float)mCacheLines[i]->mCurrentCol/(float)mCacheLines[i]->mMaxWidth)*100.0f); 378d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 379d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk }*/ 380d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 381d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return true; 382d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 383d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 384d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::initRenderState() 385d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 386d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t tmp[5] = { 387d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk RS_TEX_ENV_MODE_REPLACE, 1, 388d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk RS_TEX_ENV_MODE_NONE, 0, 389d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 0 390d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk }; 391d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ProgramFragment *pf = new ProgramFragment(mRSC, tmp, 5); 392d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontShaderF.set(pf); 393d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontShaderF->init(mRSC); 394d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 395d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Sampler *sampler = new Sampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST, 396d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP); 397d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontSampler.set(sampler); 398d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontShaderF->bindSampler(0, sampler); 399d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 400d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ProgramStore *fontStore = new ProgramStore(mRSC); 401d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore.set(fontStore); 402d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore->setDepthFunc(RS_DEPTH_FUNC_ALWAYS); 403d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore->setBlendFunc(RS_BLEND_SRC_SRC_ALPHA, RS_BLEND_DST_ONE_MINUS_SRC_ALPHA); 404d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore->setDitherEnable(false); 405d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mFontProgramStore->setDepthMask(false); 406d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 407d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 408d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::initTextTexture() 409d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 410d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *alphaElem = Element::create(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1); 411d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 412d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // We will allocate a texture to initially hold 32 character bitmaps 413d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Type *texType = new Type(mRSC); 414d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk texType->setElement(alphaElem); 415d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk texType->setDimX(1024); 416d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk texType->setDimY(256); 417d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk texType->compute(); 418d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 419d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Allocation *cacheAlloc = new Allocation(mRSC, texType); 420d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextTexture.set(cacheAlloc); 421d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextTexture->deferedUploadToTexture(mRSC, false, 0); 422d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 423d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Split up our cache texture into lines of certain widths 424d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int nextLine = 0; 425d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(16, texType->getDimX(), nextLine, 0)); 426d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 427d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(24, texType->getDimX(), nextLine, 0)); 428d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 429d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(32, texType->getDimX(), nextLine, 0)); 430d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 431d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(32, texType->getDimX(), nextLine, 0)); 432d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 433d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(40, texType->getDimX(), nextLine, 0)); 434d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 435d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(texType->getDimY() - nextLine, texType->getDimX(), nextLine, 0)); 436d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 437d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 438d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk// Avoid having to reallocate memory and render quad by quad 439d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::initVertexArrayBuffers() 440d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 441d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Now lets write index data 442d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *indexElem = Element::create(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1); 443d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Type *indexType = new Type(mRSC); 444d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint32_t numIndicies = mMaxNumberOfQuads * 6; 445d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexType->setDimX(numIndicies); 446d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexType->setElement(indexElem); 447d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexType->compute(); 448d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 449d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Allocation *indexAlloc = new Allocation(mRSC, indexType); 450d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr(); 451d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 452d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Four verts, two triangles , six indices per quad 453d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mMaxNumberOfQuads; i ++) { 454d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int i6 = i * 6; 455d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk int i4 = i * 4; 456d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 457d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 0] = i4 + 0; 458d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 1] = i4 + 1; 459d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 2] = i4 + 2; 460d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 461d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 3] = i4 + 0; 462d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 4] = i4 + 2; 463d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexPtr[i6 + 5] = i4 + 3; 464d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 465d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 466d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk indexAlloc->deferedUploadToBufferObject(mRSC); 467d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mIndexBuffer.set(indexAlloc); 468d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 469d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3); 470d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2); 471d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 472d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *elemArray[2]; 473d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk elemArray[0] = posElem; 474d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk elemArray[1] = texElem; 475d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 476d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk String8 posName("position"); 477d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk String8 texName("texture0"); 478d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 479d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const char *nameArray[2]; 480d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nameArray[0] = posName.string(); 481d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk nameArray[1] = texName.string(); 482d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t lengths[2]; 483d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk lengths[0] = posName.size(); 484d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk lengths[1] = texName.size(); 485d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 486d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const Element *vertexDataElem = Element::create(mRSC, 2, elemArray, nameArray, lengths); 487d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 488d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Type *vertexDataType = new Type(mRSC); 489d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk vertexDataType->setDimX(mMaxNumberOfQuads * 4); 490d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk vertexDataType->setElement(vertexDataElem); 491d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk vertexDataType->compute(); 492d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 493d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Allocation *vertexAlloc = new Allocation(mRSC, vertexDataType); 494d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextMeshPtr = (float*)vertexAlloc->getPtr(); 495d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 496d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mVertexArray.set(vertexAlloc); 497d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 498d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 499d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk// We don't want to allocate anything unless we actually draw text 500d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::checkInit() 501d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 502d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mInitialized) { 503d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 504d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 505d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 506d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk initTextTexture(); 507d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk initRenderState(); 508d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 509d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk initVertexArrayBuffers(); 510d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 511d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk /*mTextMeshRefs = new ObjectBaseRef<SimpleMesh>[mNumMeshes]; 512d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 513d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk for(uint32_t i = 0; i < mNumMeshes; i ++){ 514d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk SimpleMesh *textMesh = createTextMesh(); 515d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mTextMeshRefs[i].set(textMesh); 516d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk }*/ 517d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 518d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mInitialized = true; 519d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 520d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 521d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::issueDrawCommand() { 522d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 523d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ObjectBaseRef<const ProgramVertex> tmpV(mRSC->getVertex()); 524d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setVertex(mRSC->getDefaultProgramVertex()); 525d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 526d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ObjectBaseRef<const ProgramFragment> tmpF(mRSC->getFragment()); 527d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragment(mFontShaderF.get()); 528d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 529d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk ObjectBaseRef<const ProgramStore> tmpPS(mRSC->getFragmentStore()); 530d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragmentStore(mFontProgramStore.get()); 531d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 532d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if (!mRSC->setupCheck()) { 533d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setVertex((ProgramVertex *)tmpV.get()); 534d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragment((ProgramFragment *)tmpF.get()); 535d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragmentStore((ProgramStore *)tmpPS.get()); 536d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 537d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 538d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 539d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float *vtx = (float*)mVertexArray->getPtr(); 540d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float *tex = vtx + 3; 541d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 542d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk VertexArray va; 543d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk va.add(GL_FLOAT, 3, 20, false, (uint32_t)vtx, "position"); 544d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk va.add(GL_FLOAT, 2, 20, false, (uint32_t)tex, "texture0"); 545d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk va.setupGL2(mRSC, &mRSC->mStateVertexArray, &mRSC->mShaderCache); 546d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 547d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mIndexBuffer->uploadCheck(mRSC); 548d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID()); 549d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, (uint16_t *)(0)); 550d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 551d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Reset the state 552d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setVertex((ProgramVertex *)tmpV.get()); 553d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragment((ProgramFragment *)tmpF.get()); 554d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mRSC->setFragmentStore((ProgramStore *)tmpPS.get()); 555d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 556d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 557d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::appendMeshQuad(float x1, float y1, float z1, 558d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float u1, float v1, 559d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float x2, float y2, float z2, 560d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float u2, float v2, 561d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float x3, float y3, float z3, 562d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float u3, float v3, 563d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float x4, float y4, float z4, 564d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float u4, float v4) 565d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 566d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const uint32_t vertsPerQuad = 4; 567d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const uint32_t floatsPerVert = 5; 568d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert; 569d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 570d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Cull things that are off the screen 571d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float width = (float)mRSC->getWidth(); 572d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk float height = (float)mRSC->getHeight(); 573d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 574d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(x1 > width || y1 < 0.0f || x2 < 0 || y4 > height) { 575d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 576d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 577d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 578d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk /*LOGE("V0 x: %f y: %f z: %f", x1, y1, z1); 579d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("V1 x: %f y: %f z: %f", x2, y2, z2); 580d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("V2 x: %f y: %f z: %f", x3, y3, z3); 581d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk LOGE("V3 x: %f y: %f z: %f", x4, y4, z4);*/ 582d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 583d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = x1; 584d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = y1; 585d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = z1; 586d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = u1; 587d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = v1; 588d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 589d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = x2; 590d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = y2; 591d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = z2; 592d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = u2; 593d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = v2; 594d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 595d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = x3; 596d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = y3; 597d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = z3; 598d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = u3; 599d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = v3; 600d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 601d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = x4; 602d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = y4; 603d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = z4; 604d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = u4; 605d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk (*currentPos++) = v4; 606d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 607d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex ++; 608d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 609d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mCurrentQuadIndex == mMaxNumberOfQuads) { 610d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk issueDrawCommand(); 611d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex = 0; 612d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 613d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 614d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 615d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::renderText(const char *text, uint32_t len, uint32_t startIndex, int numGlyphs, int x, int y) 616d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 617d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk checkInit(); 618d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 619a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk //String8 text8(text); 620d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 621d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk // Render code here 622d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk Font *currentFont = mRSC->getFont(); 623a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(!currentFont) { 624a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(!mDefault.get()) { 625a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mDefault.set(Font::create(mRSC, "DroidSans.ttf", 16, 96)); 626a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 627a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk currentFont = mDefault.get(); 628a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 629d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk currentFont->renderUTF(text, len, startIndex, numGlyphs, x, y); 630d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 631d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(mCurrentQuadIndex != 0) { 632d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk issueDrawCommand(); 633d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mCurrentQuadIndex = 0; 634d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 635d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 636d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 637d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::renderText(const char *text, int x, int y) 638d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 639d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t textLen = strlen(text); 640d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk renderText(text, textLen, 0, -1, x, y); 641d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 642d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 643d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::renderText(Allocation *alloc, int x, int y) 644d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 645d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!alloc) { 646d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 647d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 648d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 649d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const char *text = (const char *)alloc->getPtr(); 650d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t allocSize = alloc->getType()->getSizeBytes(); 651d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk renderText(text, allocSize, 0, -1, x, y); 652d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 653d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 654d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::renderText(Allocation *alloc, uint32_t start, int len, int x, int y) 655d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 656d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk if(!alloc) { 657d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk return; 658d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 659d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 660d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk const char *text = (const char *)alloc->getPtr(); 661d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk size_t allocSize = alloc->getType()->getSizeBytes(); 662d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk renderText(text, allocSize, start, len, x, y); 663d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 664d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 665d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchoukvoid FontState::deinit(Context *rsc) 666d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 667a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mInitialized = false; 668a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk 669a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mIndexBuffer.clear(); 670a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mVertexArray.clear(); 671a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk 672a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mFontShaderF.clear(); 673a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mFontSampler.clear(); 674a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mFontProgramStore.clear(); 675a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk 676a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mTextTexture.clear(); 677a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 678a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk delete mCacheLines[i]; 679d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk } 680a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk mCacheLines.clear(); 681d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 682d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk mDefault.clear(); 683a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk 684a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(mLibrary) { 685a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk FT_Done_FreeType( mLibrary ); 686a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 687d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 688d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 689d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouknamespace android { 690d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouknamespace renderscript { 691d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 692d3e0ad43dc758c409fc23d1893dab67b18520c24Alex SakhartchoukRsFont rsi_FontCreateFromFile(Context *rsc, char const *name, uint32_t fontSize, uint32_t dpi) 693d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk{ 694a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk Font *newFont = Font::create(rsc, name, fontSize, dpi); 695a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk if(newFont) { 696a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk newFont->incUserRef(); 697a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk } 698a1ccecd965c07c2739f1258989526051a010bdabAlex Sakhartchouk return newFont; 699d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} 700d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk 701d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} // renderscript 702d3e0ad43dc758c409fc23d1893dab67b18520c24Alex Sakhartchouk} // android 703