//----------------------------------------------------------------------------- // Copyright (c) 2013 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #include "platform/platform.h" #include "platformAndroid/platformAndroid.h" #include "platformAndroid/AndroidFont.h" #include "string/Unicode.h" #include //------------------------------------------------------------------------------ // New Unicode capable font class. PlatformFont *createPlatformFont(const char *name, U32 size, U32 charset /* = TGE_ANSI_CHARSET */) { PlatformFont *retFont = new AndroidFont; if(retFont->create(name, size, charset)) return retFont; delete retFont; return NULL; } //------------------------------------------------------------------------------ void PlatformFont::enumeratePlatformFonts( Vector& fonts ) { } //------------------------------------------------------------------------------ AndroidFont::AndroidFont() { fontFileBuffer = NULL; fontFileBufferSize = 0; fontFaceCreated = false; int error = FT_Init_FreeType( &library ); if ( error ) { Con::errorf("Failed to initialize the freetype2 library"); } } //------------------------------------------------------------------------------ AndroidFont::~AndroidFont() { FT_Done_Face( face ); if (fontFileBuffer != NULL) { delete[] fontFileBuffer; fontFileBufferSize = 0; } } //------------------------------------------------------------------------------ bool AndroidFont::create( const char* name, U32 size, U32 charset ) { // Sanity! AssertFatal( name != NULL, "Cannot create a NULL font name." ); // Sanity! if ( !name ) { Con::errorf("Could not handle font name of '%s'.", name ); return false; } char fontPath[255]; activity.getFontPath(name, fontPath); int error = FT_New_Face( library, fontPath, 0, &face ); if ( error == FT_Err_Unknown_File_Format ) { fontFaceCreated = false; Con::errorf("freetype2: Font was found but format is unsupported"); } else if ( error ) { fontFaceCreated = false; Con::errorf("freetype2: Font file was not found."); } else { fontFaceCreated = true; } if (fontFaceCreated == true) { error = FT_Set_Pixel_Sizes(face, 0, size); mBaseline = (face->size->metrics.ascender + 32) >> 6; mHeight = ((face->size->metrics.ascender + -face->size->metrics.descender) + 32) >> 6; } else { mHeight = 0; mBaseline = 0; } return true; } //------------------------------------------------------------------------------ bool AndroidFont::isValidChar( const UTF8* str ) const { // since only low order characters are invalid, and since those characters // are single codeunits in UTF8, we can safely cast here. return isValidChar((UTF16)*str); } //------------------------------------------------------------------------------ bool AndroidFont::isValidChar( const UTF16 character) const { // We cut out the ASCII control chars here. Only printable characters are valid. // 0x20 == 32 == space if( character < 0x20 ) return false; return true; } //------------------------------------------------------------------------------ PlatformFont::CharInfo& AndroidFont::getCharInfo(const UTF8 *str) const { return getCharInfo( oneUTF32toUTF16(oneUTF8toUTF32(str,NULL)) ); } //------------------------------------------------------------------------------ PlatformFont::CharInfo& AndroidFont::getCharInfo(const UTF16 character) const { // Declare and clear out the CharInfo that will be returned. static PlatformFont::CharInfo characterInfo; dMemset(&characterInfo, 0, sizeof(characterInfo)); // prep values for GFont::addBitmap() characterInfo.bitmapIndex = 0; characterInfo.xOffset = 0; characterInfo.yOffset = 0; FT_GlyphSlot slot = face->glyph; int error = FT_Load_Char( face, character, FT_LOAD_RENDER ); if ( error ) { return characterInfo; } FT_Glyph_Metrics metrics = face->glyph->metrics; // Set character metrics, characterInfo.xOrigin = slot->bitmap_left; characterInfo.yOrigin = slot->bitmap_top; characterInfo.width = (metrics.width / 64); characterInfo.height = (metrics.height / 64); characterInfo.xIncrement = slot->advance.x / 64; // characterInfo.yOrigin = characterInfo.height - characterInfo.yOrigin; // Finish if character is undrawable. if ( characterInfo.width == 0 && characterInfo.height == 0 ) return characterInfo; // Clamp character minimum width. if ( characterInfo.width == 0 ) return characterInfo; if ( characterInfo.height == 0 ) return characterInfo; // Allocate a bitmap surface. const U32 bitmapSize = characterInfo.width * characterInfo.height; characterInfo.bitmapData = new U8[bitmapSize]; dMemset(characterInfo.bitmapData, 0x00, bitmapSize); //copy glyph if (slot->bitmap.buffer != NULL) { for (int i = 0; i < slot->bitmap.width; i++) { for (int j = 0; j < slot->bitmap.rows; j++) { characterInfo.bitmapData[i + (j*slot->bitmap.width)] = slot->bitmap.buffer[i + (j*slot->bitmap.width)]; } } } // Return character information. return characterInfo; }