rsFont.cpp revision 071508d9f3d1c004cd9ef8d5329949e7a8a949c8
19b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 29b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk/* 39b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * Copyright (C) 2009 The Android Open Source Project 49b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * 59b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License"); 69b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * you may not use this file except in compliance with the License. 79b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * You may obtain a copy of the License at 89b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * 99b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * http://www.apache.org/licenses/LICENSE-2.0 109b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * 119b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software 129b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS, 139b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * See the License for the specific language governing permissions and 159b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk * limitations under the License. 169b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk */ 179b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 189b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#ifndef ANDROID_RS_BUILD_FOR_HOST 199b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include "rsContext.h" 209b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#else 219b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include "rsContextHostStub.h" 229b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#endif 239b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 249b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include "rsFont.h" 259b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include "rsProgramFragment.h" 269b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include FT_BITMAP_H 279b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 289b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include <GLES/gl.h> 299b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include <GLES/glext.h> 309b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include <GLES2/gl2.h> 319b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk#include <GLES2/gl2ext.h> 329b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 339b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukusing namespace android; 349b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukusing namespace android::renderscript; 359b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 369b949fce39f0f39ce9275b71d7c347210775e7a8Alex SakhartchoukFont::Font(Context *rsc) : ObjectBase(rsc), mCachedGlyphs(NULL) 379b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 38071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mAllocFile = __FILE__; 39071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mAllocLine = __LINE__; 409b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mInitialized = false; 419b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mHasKerning = false; 429b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 439b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 449b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukbool Font::init(const char *name, uint32_t fontSize, uint32_t dpi) 459b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 469b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(mInitialized) { 479b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("Reinitialization of fonts not supported"); 489b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return false; 499b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 509b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 519b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk String8 fontsDir("/fonts/"); 529b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk String8 fullPath(getenv("ANDROID_ROOT")); 539b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk fullPath += fontsDir; 549b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk fullPath += name; 559b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 56071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk FT_Error error = FT_New_Face(mRSC->mStateFont.getLib(), fullPath.string(), 0, &mFace); 579b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(error) { 589b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("Unable to initialize font %s", fullPath.string()); 599b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return false; 609b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 619b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 629b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontName = name; 639b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontSize = fontSize; 649b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mDpi = dpi; 659b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 669b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk //LOGE("Font initialized: %s", fullPath.string()); 679b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 689b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk error = FT_Set_Char_Size(mFace, fontSize * 64, 0, dpi, 0); 699b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(error) { 709b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("Unable to set font size on %s", fullPath.string()); 719b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return false; 729b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 739b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 749b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mHasKerning = FT_HAS_KERNING(mFace); 759b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 769b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mInitialized = true; 779b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return true; 789b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 809b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid Font::invalidateTextureCache() 819b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 829b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mCachedGlyphs.size(); i ++) { 839b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCachedGlyphs.valueAt(i)->mIsValid = false; 849b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 859b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 869b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 879b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y) 889b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 899b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk FontState *state = &mRSC->mStateFont; 909b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 919b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk int nPenX = x + glyph->mBitmapLeft; 929b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk int nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight; 939b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 949b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk state->appendMeshQuad(nPenX, nPenY, 0, 959b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMinU, glyph->mBitmapMaxV, 969b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 979b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nPenX + (int)glyph->mBitmapWidth, nPenY, 0, 989b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMaxU, glyph->mBitmapMaxV, 999b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1009b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nPenX + (int)glyph->mBitmapWidth, nPenY - (int)glyph->mBitmapHeight, 0, 1019b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMaxU, glyph->mBitmapMinV, 1029b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1039b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nPenX, nPenY - (int)glyph->mBitmapHeight, 0, 1049b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMinU, glyph->mBitmapMinV); 1059b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 1069b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1079b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid Font::renderUTF(const char *text, uint32_t len, uint32_t start, int numGlyphs, int x, int y) 1089b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 1099b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(!mInitialized || numGlyphs == 0 || text == NULL || len == 0) { 1109b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return; 1119b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1129b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1139b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk int penX = x, penY = y; 1149b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk int glyphsLeft = 1; 1159b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(numGlyphs > 0) { 1169b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyphsLeft = numGlyphs; 1179b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1189b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1199b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk size_t index = start; 1209b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk size_t nextIndex = 0; 1219b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1229b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk while (glyphsLeft > 0) { 1239b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1249b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk int32_t utfChar = utf32_at(text, len, index, &nextIndex); 1259b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1269b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Reached the end of the string or encountered 1279b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(utfChar < 0) { 1289b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk break; 1299b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1309b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1319b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Move to the next character in the array 1329b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk index = nextIndex; 1339b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1349b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk CachedGlyphInfo *cachedGlyph = mCachedGlyphs.valueFor((uint32_t)utfChar); 1359b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1369b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(cachedGlyph == NULL) { 1379b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk cachedGlyph = cacheGlyph((uint32_t)utfChar); 1389b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1399b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Is the glyph still in texture cache? 1409b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(!cachedGlyph->mIsValid) { 1419b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk updateGlyphCache(cachedGlyph); 1429b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1439b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1449b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage 1459b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(cachedGlyph->mIsValid) { 1469b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk drawCachedGlyph(cachedGlyph, penX, penY); 1479b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1489b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1499b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk penX += (cachedGlyph->mAdvance.x >> 6); 1509b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1519b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // If we were given a specific number of glyphs, decrement 1529b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(numGlyphs > 0) { 1539b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyphsLeft --; 1549b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1559b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1569b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 1579b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1589b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid Font::updateGlyphCache(CachedGlyphInfo *glyph) 1599b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 160071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk FT_Error error = FT_Load_Glyph( mFace, glyph->mGlyphIndex, FT_LOAD_RENDER ); 161071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk if(error) { 162071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk LOGE("Couldn't load glyph."); 163071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk return; 164071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk } 1659b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 166071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk glyph->mAdvance = mFace->glyph->advance; 167071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk glyph->mBitmapLeft = mFace->glyph->bitmap_left; 168071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk glyph->mBitmapTop = mFace->glyph->bitmap_top; 1699b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 170071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk FT_Bitmap *bitmap = &mFace->glyph->bitmap; 1719b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1729b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Now copy the bitmap into the cache texture 1739b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t startX = 0; 1749b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t startY = 0; 1759b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1769b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Let the font state figure out where to put the bitmap 1779b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk FontState *state = &mRSC->mStateFont; 178071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk glyph->mIsValid = state->cacheBitmap(bitmap, &startX, &startY); 1799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1809b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(!glyph->mIsValid) { 1819b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return; 1829b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 1839b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 184071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk uint32_t endX = startX + bitmap->width; 185071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk uint32_t endY = startY + bitmap->rows; 1869b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1879b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMinX = startX; 1889b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMinY = startY; 189071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk glyph->mBitmapWidth = bitmap->width; 190071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk glyph->mBitmapHeight = bitmap->rows; 1919b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1929b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t cacheWidth = state->getCacheTextureType()->getDimX(); 1939b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t cacheHeight = state->getCacheTextureType()->getDimY(); 1949b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 1959b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMinU = (float)startX / (float)cacheWidth; 1969b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMinV = (float)startY / (float)cacheHeight; 1979b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMaxU = (float)endX / (float)cacheWidth; 1989b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glyph->mBitmapMaxV = (float)endY / (float)cacheHeight; 1999b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 2009b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2019b949fce39f0f39ce9275b71d7c347210775e7a8Alex SakhartchoukFont::CachedGlyphInfo *Font::cacheGlyph(uint32_t glyph) 2029b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 2039b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk CachedGlyphInfo *newGlyph = new CachedGlyphInfo(); 2049b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCachedGlyphs.add(glyph, newGlyph); 2059b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2069b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk newGlyph->mGlyphIndex = FT_Get_Char_Index(mFace, glyph); 2079b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk newGlyph->mIsValid = false; 2089b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2099b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk //LOGE("Glyph = %c, face index: %u", (unsigned char)glyph, newGlyph->mGlyphIndex); 2109b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2119b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk updateGlyphCache(newGlyph); 2129b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2139b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return newGlyph; 2149b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 2159b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2169b949fce39f0f39ce9275b71d7c347210775e7a8Alex SakhartchoukFont * Font::create(Context *rsc, const char *name, uint32_t fontSize, uint32_t dpi) 2179b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 2189b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Vector<Font*> &activeFonts = rsc->mStateFont.mActiveFonts; 2199b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2209b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < activeFonts.size(); i ++) { 2219b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Font *ithFont = activeFonts[i]; 2229b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(ithFont->mFontName == name && ithFont->mFontSize == fontSize && ithFont->mDpi == dpi) { 2239b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return ithFont; 2249b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2259b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2269b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2279b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Font *newFont = new Font(rsc); 2289b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk bool isInitialized = newFont->init(name, fontSize, dpi); 2299b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(isInitialized) { 2309b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk activeFonts.push(newFont); 2319b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return newFont; 2329b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2339b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2349b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk delete newFont; 2359b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return NULL; 2369b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2379b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 2389b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2399b949fce39f0f39ce9275b71d7c347210775e7a8Alex SakhartchoukFont::~Font() 2409b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 2419b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(mFace) { 2429b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk FT_Done_Face(mFace); 2439b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2449b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2459b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for (uint32_t ct = 0; ct < mRSC->mStateFont.mActiveFonts.size(); ct++) { 2469b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if (mRSC->mStateFont.mActiveFonts[ct] == this) { 2479b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->mStateFont.mActiveFonts.removeAt(ct); 2489b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk break; 2499b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2509b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2519b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2529b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mCachedGlyphs.size(); i ++) { 2539b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk CachedGlyphInfo *glyph = mCachedGlyphs.valueAt(i); 2549b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk delete glyph; 2559b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2569b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 2579b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2589b949fce39f0f39ce9275b71d7c347210775e7a8Alex SakhartchoukFontState::FontState() 2599b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 2609b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mInitialized = false; 2619b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mMaxNumberOfQuads = 1024; 2629b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCurrentQuadIndex = 0; 2639b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC = NULL; 2649b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 2659b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2669b949fce39f0f39ce9275b71d7c347210775e7a8Alex SakhartchoukFontState::~FontState() 2679b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 2689b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 2699b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk delete mCacheLines[i]; 2709b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2719b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2729b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk rsAssert(!mActiveFonts.size()); 2739b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 2749b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 275071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex SakhartchoukFT_Library FontState::getLib() 2769b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 2779b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(!mLibrary) { 278071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk FT_Error error = FT_Init_FreeType(&mLibrary); 2799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(error) { 2809b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("Unable to initialize freetype"); 281071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk return NULL; 2829b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 2839b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 284071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk return mLibrary; 285071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk} 2869b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 287071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchoukvoid FontState::init(Context *rsc) 288071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk{ 289071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk //getLib(); 2909b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 291071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mRSC = rsc; 2929b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 2939b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 2949b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::flushAllAndInvalidate() 2959b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 2969b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(mCurrentQuadIndex != 0) { 2979b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk issueDrawCommand(); 2989b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCurrentQuadIndex = 0; 2999b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3009b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mActiveFonts.size(); i ++) { 3019b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mActiveFonts[i]->invalidateTextureCache(); 3029b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3039b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 3049b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCacheLines[i]->mCurrentCol = 0; 3059b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3069b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 3079b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3089b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukbool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) 3099b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 3109b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // If the glyph is too tall, don't cache it 3119b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if((uint32_t)bitmap->rows > mCacheLines[mCacheLines.size()-1]->mMaxHeight) { 3129b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("Font size to large to fit in cache. width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows); 3139b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return false; 3149b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3159b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3169b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Now copy the bitmap into the cache texture 3179b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t startX = 0; 3189b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t startY = 0; 3199b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3209b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk bool bitmapFit = false; 3219b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 3229b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk bitmapFit = mCacheLines[i]->fitBitmap(bitmap, &startX, &startY); 3239b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(bitmapFit) { 3249b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk break; 3259b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3269b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3279b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3289b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // If the new glyph didn't fit, flush the state so far and invalidate everything 3299b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(!bitmapFit) { 3309b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk flushAllAndInvalidate(); 3319b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3329b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Try to fit it again 3339b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 3349b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk bitmapFit = mCacheLines[i]->fitBitmap(bitmap, &startX, &startY); 3359b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(bitmapFit) { 3369b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk break; 3379b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3389b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3399b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3409b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // if we still don't fit, something is wrong and we shouldn't draw 3419b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(!bitmapFit) { 3429b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("Bitmap doesn't fit in cache. width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows); 3439b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return false; 3449b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3459b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3469b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3479b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk *retOriginX = startX; 3489b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk *retOriginY = startY; 3499b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3509b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t endX = startX + bitmap->width; 3519b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t endY = startY + bitmap->rows; 3529b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3539b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk //LOGE("Bitmap width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows); 3549b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3559b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t cacheWidth = getCacheTextureType()->getDimX(); 3569b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3579b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk unsigned char *cacheBuffer = (unsigned char*)mTextTexture->getPtr(); 3589b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk unsigned char *bitmapBuffer = bitmap->buffer; 3599b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3609b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0; 3619b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(cacheX = startX, bX = 0; cacheX < endX; cacheX ++, bX ++) { 3629b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(cacheY = startY, bY = 0; cacheY < endY; cacheY ++, bY ++) { 3639b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk unsigned char tempCol = bitmapBuffer[bY * bitmap->width + bX]; 3649b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk cacheBuffer[cacheY*cacheWidth + cacheX] = tempCol; 3659b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3669b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 3679b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3689b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // This will dirty the texture and the shader so next time 3699b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // we draw it will upload the data 3709b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mTextTexture->deferedUploadToTexture(mRSC, false, 0); 3719b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontShaderF->bindTexture(0, mTextTexture.get()); 3729b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3739b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Some debug code 3749b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk /*for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 3759b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("Cache Line: H: %u Empty Space: %f", 3769b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCacheLines[i]->mMaxHeight, 3779b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (1.0f - (float)mCacheLines[i]->mCurrentCol/(float)mCacheLines[i]->mMaxWidth)*100.0f); 3789b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk }*/ 3809b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3819b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return true; 3829b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 3839b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3849b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::initRenderState() 3859b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 3869b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t tmp[5] = { 3879b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk RS_TEX_ENV_MODE_REPLACE, 1, 3889b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk RS_TEX_ENV_MODE_NONE, 0, 3899b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 0 3909b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk }; 3919b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk ProgramFragment *pf = new ProgramFragment(mRSC, tmp, 5); 3929b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontShaderF.set(pf); 3939b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontShaderF->init(mRSC); 3949b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 3959b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Sampler *sampler = new Sampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST, 3969b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP); 3979b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontSampler.set(sampler); 3989b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontShaderF->bindSampler(0, sampler); 3999b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4009b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk ProgramStore *fontStore = new ProgramStore(mRSC); 4019b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontProgramStore.set(fontStore); 4029b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontProgramStore->setDepthFunc(RS_DEPTH_FUNC_ALWAYS); 4039b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontProgramStore->setBlendFunc(RS_BLEND_SRC_SRC_ALPHA, RS_BLEND_DST_ONE_MINUS_SRC_ALPHA); 4049b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontProgramStore->setDitherEnable(false); 4059b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mFontProgramStore->setDepthMask(false); 4069b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 4079b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4089b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::initTextTexture() 4099b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 4109b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const Element *alphaElem = Element::create(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1); 4119b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4129b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // We will allocate a texture to initially hold 32 character bitmaps 4139b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Type *texType = new Type(mRSC); 4149b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk texType->setElement(alphaElem); 4159b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk texType->setDimX(1024); 4169b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk texType->setDimY(256); 4179b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk texType->compute(); 4189b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4199b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Allocation *cacheAlloc = new Allocation(mRSC, texType); 4209b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mTextTexture.set(cacheAlloc); 4219b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mTextTexture->deferedUploadToTexture(mRSC, false, 0); 4229b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4239b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Split up our cache texture into lines of certain widths 4249b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk int nextLine = 0; 4259b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(16, texType->getDimX(), nextLine, 0)); 4269b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 4279b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(24, texType->getDimX(), nextLine, 0)); 4289b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 4299b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(32, texType->getDimX(), nextLine, 0)); 4309b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 4319b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(32, texType->getDimX(), nextLine, 0)); 4329b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 4339b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(40, texType->getDimX(), nextLine, 0)); 4349b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nextLine += mCacheLines.top()->mMaxHeight; 4359b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCacheLines.push(new CacheTextureLine(texType->getDimY() - nextLine, texType->getDimX(), nextLine, 0)); 4369b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 4379b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4389b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk// Avoid having to reallocate memory and render quad by quad 4399b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::initVertexArrayBuffers() 4409b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 4419b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Now lets write index data 4429b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const Element *indexElem = Element::create(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1); 4439b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Type *indexType = new Type(mRSC); 4449b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint32_t numIndicies = mMaxNumberOfQuads * 6; 4459b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexType->setDimX(numIndicies); 4469b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexType->setElement(indexElem); 4479b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexType->compute(); 4489b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4499b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Allocation *indexAlloc = new Allocation(mRSC, indexType); 4509b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr(); 4519b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4529b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Four verts, two triangles , six indices per quad 4539b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mMaxNumberOfQuads; i ++) { 4549b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk int i6 = i * 6; 4559b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk int i4 = i * 4; 4569b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4579b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexPtr[i6 + 0] = i4 + 0; 4589b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexPtr[i6 + 1] = i4 + 1; 4599b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexPtr[i6 + 2] = i4 + 2; 4609b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4619b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexPtr[i6 + 3] = i4 + 0; 4629b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexPtr[i6 + 4] = i4 + 2; 4639b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexPtr[i6 + 5] = i4 + 3; 4649b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 4659b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4669b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk indexAlloc->deferedUploadToBufferObject(mRSC); 4679b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mIndexBuffer.set(indexAlloc); 4689b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4699b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3); 4709b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2); 4719b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4729b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const Element *elemArray[2]; 4739b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk elemArray[0] = posElem; 4749b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk elemArray[1] = texElem; 4759b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4769b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk String8 posName("position"); 4779b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk String8 texName("texture0"); 4789b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const char *nameArray[2]; 4809b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nameArray[0] = posName.string(); 4819b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk nameArray[1] = texName.string(); 4829b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk size_t lengths[2]; 4839b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk lengths[0] = posName.size(); 4849b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk lengths[1] = texName.size(); 4859b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4869b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const Element *vertexDataElem = Element::create(mRSC, 2, elemArray, nameArray, lengths); 4879b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4889b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Type *vertexDataType = new Type(mRSC); 4899b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk vertexDataType->setDimX(mMaxNumberOfQuads * 4); 4909b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk vertexDataType->setElement(vertexDataElem); 4919b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk vertexDataType->compute(); 4929b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4939b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Allocation *vertexAlloc = new Allocation(mRSC, vertexDataType); 4949b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mTextMeshPtr = (float*)vertexAlloc->getPtr(); 4959b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4969b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mVertexArray.set(vertexAlloc); 4979b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 4989b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 4999b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk// We don't want to allocate anything unless we actually draw text 5009b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::checkInit() 5019b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 5029b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(mInitialized) { 5039b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return; 5049b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 5059b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5069b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk initTextTexture(); 5079b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk initRenderState(); 5089b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5099b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk initVertexArrayBuffers(); 5109b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5119b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk /*mTextMeshRefs = new ObjectBaseRef<SimpleMesh>[mNumMeshes]; 5129b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5139b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk for(uint32_t i = 0; i < mNumMeshes; i ++){ 5149b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk SimpleMesh *textMesh = createTextMesh(); 5159b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mTextMeshRefs[i].set(textMesh); 5169b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk }*/ 5179b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5189b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mInitialized = true; 5199b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 5209b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5219b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::issueDrawCommand() { 5229b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5239b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk ObjectBaseRef<const ProgramVertex> tmpV(mRSC->getVertex()); 5249b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setVertex(mRSC->getDefaultProgramVertex()); 5259b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5269b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk ObjectBaseRef<const ProgramFragment> tmpF(mRSC->getFragment()); 5279b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setFragment(mFontShaderF.get()); 5289b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5299b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk ObjectBaseRef<const ProgramStore> tmpPS(mRSC->getFragmentStore()); 5309b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setFragmentStore(mFontProgramStore.get()); 5319b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5329b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if (!mRSC->setupCheck()) { 5339b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setVertex((ProgramVertex *)tmpV.get()); 5349b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setFragment((ProgramFragment *)tmpF.get()); 5359b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setFragmentStore((ProgramStore *)tmpPS.get()); 5369b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return; 5379b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 5389b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5399b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float *vtx = (float*)mVertexArray->getPtr(); 5409b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float *tex = vtx + 3; 5419b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5429b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk VertexArray va; 5439b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk va.add(GL_FLOAT, 3, 20, false, (uint32_t)vtx, "position"); 5449b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk va.add(GL_FLOAT, 2, 20, false, (uint32_t)tex, "texture0"); 5459b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk va.setupGL2(mRSC, &mRSC->mStateVertexArray, &mRSC->mShaderCache); 5469b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5479b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mIndexBuffer->uploadCheck(mRSC); 5489b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->getBufferObjectID()); 5499b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, (uint16_t *)(0)); 5509b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5519b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Reset the state 5529b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setVertex((ProgramVertex *)tmpV.get()); 5539b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setFragment((ProgramFragment *)tmpF.get()); 5549b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mRSC->setFragmentStore((ProgramStore *)tmpPS.get()); 5559b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 5569b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5579b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::appendMeshQuad(float x1, float y1, float z1, 5589b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float u1, float v1, 5599b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float x2, float y2, float z2, 5609b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float u2, float v2, 5619b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float x3, float y3, float z3, 5629b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float u3, float v3, 5639b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float x4, float y4, float z4, 5649b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float u4, float v4) 5659b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 5669b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const uint32_t vertsPerQuad = 4; 5679b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const uint32_t floatsPerVert = 5; 5689b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert; 5699b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5709b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Cull things that are off the screen 5719b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float width = (float)mRSC->getWidth(); 5729b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk float height = (float)mRSC->getHeight(); 5739b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5749b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(x1 > width || y1 < 0.0f || x2 < 0 || y4 > height) { 5759b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return; 5769b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 5779b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5789b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk /*LOGE("V0 x: %f y: %f z: %f", x1, y1, z1); 5799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("V1 x: %f y: %f z: %f", x2, y2, z2); 5809b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("V2 x: %f y: %f z: %f", x3, y3, z3); 5819b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk LOGE("V3 x: %f y: %f z: %f", x4, y4, z4);*/ 5829b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5839b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = x1; 5849b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = y1; 5859b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = z1; 5869b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = u1; 5879b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = v1; 5889b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5899b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = x2; 5909b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = y2; 5919b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = z2; 5929b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = u2; 5939b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = v2; 5949b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 5959b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = x3; 5969b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = y3; 5979b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = z3; 5989b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = u3; 5999b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = v3; 6009b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6019b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = x4; 6029b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = y4; 6039b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = z4; 6049b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = u4; 6059b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk (*currentPos++) = v4; 6069b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6079b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCurrentQuadIndex ++; 6089b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6099b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(mCurrentQuadIndex == mMaxNumberOfQuads) { 6109b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk issueDrawCommand(); 6119b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCurrentQuadIndex = 0; 6129b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 6139b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 6149b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6159b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::renderText(const char *text, uint32_t len, uint32_t startIndex, int numGlyphs, int x, int y) 6169b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 6179b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk checkInit(); 6189b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 619071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk //String8 text8(text); 6209b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6219b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk // Render code here 6229b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk Font *currentFont = mRSC->getFont(); 623071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk if(!currentFont) { 624071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk if(!mDefault.get()) { 625071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mDefault.set(Font::create(mRSC, "DroidSans.ttf", 16, 96)); 626071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk } 627071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk currentFont = mDefault.get(); 628071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk } 6299b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk currentFont->renderUTF(text, len, startIndex, numGlyphs, x, y); 6309b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6319b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(mCurrentQuadIndex != 0) { 6329b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk issueDrawCommand(); 6339b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mCurrentQuadIndex = 0; 6349b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 6359b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 6369b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6379b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::renderText(const char *text, int x, int y) 6389b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 6399b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk size_t textLen = strlen(text); 6409b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk renderText(text, textLen, 0, -1, x, y); 6419b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 6429b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6439b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::renderText(Allocation *alloc, int x, int y) 6449b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 6459b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(!alloc) { 6469b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return; 6479b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 6489b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6499b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const char *text = (const char *)alloc->getPtr(); 6509b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk size_t allocSize = alloc->getType()->getSizeBytes(); 6519b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk renderText(text, allocSize, 0, -1, x, y); 6529b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 6539b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6549b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::renderText(Allocation *alloc, uint32_t start, int len, int x, int y) 6559b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 6569b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk if(!alloc) { 6579b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk return; 6589b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 6599b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6609b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk const char *text = (const char *)alloc->getPtr(); 6619b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk size_t allocSize = alloc->getType()->getSizeBytes(); 6629b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk renderText(text, allocSize, start, len, x, y); 6639b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 6649b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6659b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchoukvoid FontState::deinit(Context *rsc) 6669b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 667071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mInitialized = false; 668071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk 669071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mIndexBuffer.clear(); 670071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mVertexArray.clear(); 671071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk 672071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mFontShaderF.clear(); 673071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mFontSampler.clear(); 674071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mFontProgramStore.clear(); 675071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk 676071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mTextTexture.clear(); 677071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk for(uint32_t i = 0; i < mCacheLines.size(); i ++) { 678071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk delete mCacheLines[i]; 6799b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk } 680071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk mCacheLines.clear(); 6819b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6829b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk mDefault.clear(); 683071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk 684071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk if(mLibrary) { 685071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk FT_Done_FreeType( mLibrary ); 686071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk } 6879b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 6889b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6899b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouknamespace android { 6909b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouknamespace renderscript { 6919b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 6929b949fce39f0f39ce9275b71d7c347210775e7a8Alex SakhartchoukRsFont rsi_FontCreateFromFile(Context *rsc, char const *name, uint32_t fontSize, uint32_t dpi) 6939b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk{ 694071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk Font *newFont = Font::create(rsc, name, fontSize, dpi); 695071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk if(newFont) { 696071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk newFont->incUserRef(); 697071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk } 698071508d9f3d1c004cd9ef8d5329949e7a8a949c8Alex Sakhartchouk return newFont; 6999b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} 7009b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk 7019b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} // renderscript 7029b949fce39f0f39ce9275b71d7c347210775e7a8Alex Sakhartchouk} // android 703