📄 freetype2fontrendering.cpp
字号:
// ___ ___ ___ ___ ___ // /\__\ ___ /\__\ /\ \ /\__\ /\ \. // /::| | /\ \ /::| | /::\ \ /:/ / /::\ \. // /:|:| | \:\ \ /:|:| | /:/\:\ \ /:/ / /:/\:\ \. // /:/|:|__|__ /::\__\ /:/|:| |__ /:/ \:\ \ /:/ / /::\~\:\ \. // /:/ |::::\__\ __/:/\/__/ /:/ |:| /\__\ /:/__/_\:\__\ /:/__/ /:/\:\ \:\__\.// \/__/~~/:/ / /\/:/ / \/__|:|/:/ / \:\ /\ \/__/ \:\ \ \:\~\:\ \/__/// /:/ / \::/__/ |:/:/ / \:\ \:\__\ \:\ \ \:\ \:\__\. // /:/ / \:\__\ |::/ / \:\/:/ / \:\ \ \:\ \/__/ // /:/ / \/__/ /:/ / \::/ / \:\__\ \:\__\. // \/__/ \/__/ \/__/ \/__/ \/__/ // // =============================================================================// Minimalist OpenGL Environment// =============================================================================//// This file is part of Minimalist OpenGL Environment (MinGLE)//// Version: 0.2.0// Author: Balazs Domonkos// Filename: src/fontrendering/include/FreeType2FontRendering.cpp// Creation Date: January 25th 2008// Revision Date: January 25th 2008////// The Minimalist OpenGL Environment is free software: you can// redistribute it and/or modify it under the terms of the GNU// General Public License as published by the Free Software// Foundation, either version 3 of the License, or (at your// option) any later version.//// The Minimalist OpenGL Environment is distributed in the hope// that it will be useful, but WITHOUT ANY WARRANTY; without// even the implied warranty of MERCHANTABILITY or FITNESS FOR// A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License// along with Minimalist OpenGL Environment. If not, see // <http://www.gnu.org/licenses/>. See the COPYING file included // with this distribution file for license details.///// @file FreeType2FontRendering.cpp/// FreeType2 font rendering implementation// Header that contains the declaration#include <FreeType2FontRendering.h>// MinGLE headers#include <Exception.h>#include <System.h>#include <MathUtils.h>#include <Atlas.h>// System headers#include <math.h>namespace MinGLE {// Dynamic library loader functionextern "C"void loadDynLib(void) { // Create and register FreeType2 font rendering implementation FontRendering::registerImplementation(FreeType2FontRendering::IMPLEMENTATION_NAME, new FreeType2FontRendering()); FontRendering::registerFunctionality(FileFormatFunctionality("ttf", FileFormatFunctionality::READ), FreeType2FontRendering::IMPLEMENTATION_NAME);}// Dynamic library unloader functionextern "C" void unloadDynLib(void) { // Nothing to do}// =============================================================================// For font loading Ogre3D code was used (http://ogre3d.org, class Ogre::Font)FreeType2Font::FreeType2Font(const FT_Byte *memoryBuffer, int bufferLength, unsigned height, unsigned width, long faceIndex, unsigned firstCharacter, unsigned lastCharacter, GLenum format, GLenum type, ImageScaleMode imageScaleMode) :RasterFont(height, width, faceIndex, firstCharacter, lastCharacter, format, type, imageScaleMode){ // Create font face object FT_Face face; // Load a font face from a font file FT_Error error = FT_New_Memory_Face( FreeType2FontRendering::getLibraryHandle(), memoryBuffer, bufferLength, faceIndex, // face_index &face); if(error == FT_Err_Unknown_File_Format) Except("FreeType2Font::FreeType2Font", "Unknown file format"); else if(error) Except("FreeType2Font::FreeType2Font", "Unknown error"); // Set font size in pixel Assert(!FT_Set_Pixel_Sizes( face, // handle to face object mWidth, // pixel_width mHeight), // pixel_height "FreeType2Font::FreeType2Font"); // Calculate maximum width, height and bearing int max_height = 0, max_width = 0, max_bear = 0; for(unsigned ch = mFirstCharacter; ch < mLastCharacter; ch++) { FT_Load_Char(face, ch, FT_LOAD_RENDER); if( ( 2 * ( face->glyph->bitmap.rows << 6 ) - face->glyph->metrics.horiBearingY ) > max_height ) max_height = ( 2 * ( face->glyph->bitmap.rows << 6 ) - face->glyph->metrics.horiBearingY ); if( face->glyph->metrics.horiBearingY > max_bear ) max_bear = face->glyph->metrics.horiBearingY; if( (face->glyph->advance.x >> 6 ) + ( face->glyph->metrics.horiBearingX >> 6 ) > max_width) max_width = (face->glyph->advance.x >> 6 ) + ( face->glyph->metrics.horiBearingX >> 6 ); } // Now work out how big our texture needs to be unsigned rawSize = (max_width + FONT_CHAR_SPACER) * ((max_height >> 6) + FONT_CHAR_SPACER) * (mLastCharacter - mFirstCharacter + 1); unsigned texWidth = (unsigned) ::sqrt(rawSize); // just in case the size might chop a glyph in half, add another glyph width/height texWidth += std::max(max_width, (max_height>>6)); // Now round up to nearest power of two if(mImageScaleMode == IMAGE_CREATION_SCALE || mImageScaleMode == IMAGE_SCALE_TRY_NOSCALE && System::getGLVersion().major < 2) texWidth = MathUtils::convertToPowerOf2(texWidth, MathUtils::UPSCALE); // Creating rectangular texture with power of 2 sizes to save memory unsigned texHeight = texWidth; while(texHeight*texWidth>>1 > rawSize) texHeight >>= 1; // Create image atlas mImageAtlas = new ImageAtlas<int>(texWidth, texHeight, mFormat, mType); // Width of the image in bytes unsigned data_width = mImageAtlas->getImage()->getWidth() * mBytesPerPixel; // Reset content (blue, transparent) mImageAtlas->getImage()->clear(0.0, 0.0, 1.0, 0.0); unsigned char *imageData = (unsigned char *) mImageAtlas->getImage()->getData(); // Create characters for(unsigned ch = mFirstCharacter, l = 0, m = 0, n = 0; ch <= mLastCharacter; ch++) { // Load character into the slot Assert(!FT_Load_Char(face, ch, FT_LOAD_RENDER), "FreeType2Font::FreeType2Font"); // a small shortcut FT_GlyphSlot slot = face->glyph; FT_Int advance = (slot->advance.x >> 6) + (slot->metrics.horiBearingX >> 6); unsigned char* buffer = slot->bitmap.buffer; // Skip character if not exists in the font file if(!buffer) continue; int y_bearnig = (max_bear >> 6) - (slot->metrics.horiBearingY >> 6); for(int j=0; j<slot->bitmap.rows; j++) { int row = j + m + y_bearnig; unsigned char* pDest = &imageData[(row * data_width) + l * mBytesPerPixel]; for(int k = 0; k < slot->bitmap.width; k++) { // Use the same greyscale pixel for all color components for(register unsigned colCh=0; colCh<mBytesPerPixel-1; colCh++) *pDest++= *buffer; // Always use the greyscale value for alpha *pDest++= *buffer++; } } // Define coordinates for this region ImageAtlas<int>::CoordSet2D coordSet = { l, // u1 m, // v1 l + (slot->advance.x >> 6), // u2 m + (max_height >> 6) // v2 }; mImageAtlas->addCoordSet(ch, &coordSet); // Advance a column l += (advance + FONT_CHAR_SPACER); // If at end of row if(mImageAtlas->getImage()->getWidth() - 1 < l + (advance)) { m += ( max_height >> 6 ) + FONT_CHAR_SPACER; l = n = 0; } }}// =============================================================================const std::string FreeType2FontRendering::IMPLEMENTATION_NAME = "freetype2";FT_Library FreeType2FontRendering::mLibraryHandle;FreeType2FontRendering::FreeType2FontRendering() { Assert(!FT_Init_FreeType(&mLibraryHandle), "FreeType2FontRendering::FreeType2FontRendering");}FreeType2FontRendering::~FreeType2FontRendering() { Assert(!FT_Done_FreeType(mLibraryHandle), "FreeType2FontRendering::~FreeType2FontRendering");}FT_Library FreeType2FontRendering::getLibraryHandle() { return mLibraryHandle;}Font *FreeType2FontRendering::_createFont(const std::string& filename, VirtualFileSystem *vfs, size_t height, size_t width, long faceIndex, size_t firstCharacter, size_t lastCharacter, GLenum format, GLenum type, RasterFont::ImageScaleMode imageScaleMode) { // Load the font from the file system into the memory int bufferLength; FT_Byte *memoryBuffer = (FT_Byte *) vfs->readFile(filename, bufferLength); // Load font from memory Font *font = new FreeType2Font(memoryBuffer, bufferLength, height, width, faceIndex, firstCharacter, lastCharacter, format, type, imageScaleMode); // Deallocate buffer delete [] memoryBuffer; return font;}void FreeType2FontRendering::_saveFont(Font *font, const std::string& filename, VirtualFileSystem *vfs) { Except("FreeType2FontRendering::_saveFont", "Fonts cannot be saved using the MinGLE FreeType2 font library.");} } // namespace MinGLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -