/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program 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 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS #include "font.h" #ifdef HAVE_SDL_IMAGE_H #include #else #include #endif #include "default_font.xpm" #include "debug.h" #include "compiler.h" ObjectListDefinition(Font); Font::Font() : data(Font::defaultFontData) { this->init(); } /** * @brief constructs a Font out of a TTF-FIle * @param fontFile the File to load the font from * @param fontSize the Size of the Font in Pixels */ Font::Font(const std::string& fontFile, unsigned int renderSize) : data(Font::defaultFontData) { this->init(); if (!fontFile.empty()) this->loadFontFromTTF(fontFile, renderSize); } /** * @brief constructs a Font out of an ImageFile * @param imageFile the ImageFile to load the Font From. */ Font::Font(const std::string& imageFile) : data(Font::defaultFontData) { this->init(); this->setName(imageFile); // this->setSize(fontSize); SDL_Surface* image = NULL; if (!imageFile.empty()) image = IMG_Load(imageFile.c_str()); else return; if (image != NULL) { this->loadFontFromSDL_Surface(image); SDL_FreeSurface(image); } else PRINTF(1)("loading from surface %s failed: %s\n", imageFile.c_str(), IMG_GetError()); } /** * @brief constructs a Font * @param xpmArray the xpm-ARRAY to load the font from */ Font::Font(char** xpmArray) : data(Font::defaultFontData) { this->init(); this->setName("XPM-array-font"); // this->setSize(fontSize); SDL_Surface* image = NULL; if (xpmArray != NULL) image = IMG_ReadXPMFromArray(xpmArray); if (image != NULL) { this->loadFontFromSDL_Surface(image); SDL_FreeSurface(image); } else PRINTF(1)("Loading from XPM-array failed: %s\n", IMG_GetError()); } Font::Font(const Font& font) { this->init(); *this = font; } /** * @brief destructs a font * * this releases the memory a font uses to be opened. * deletes the glLists, and the TTF-handler, if present. */ Font::~Font() { } Font& Font::operator=(const Font& font) { Material::operator=(font); this->data = font.data; this->setTexture(this->data->textureData()); return *this; }; /** * @brief initializes a Font (with default values) */ void Font::init() { this->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); this->registerObject(this, Font::_objectList); if (Font::defaultFontData.isNull()) { Font::initDefaultFont(); this->data = Font::defaultFontData; } } FontData::Pointer Font::defaultFontData(NULL); /** * @brief initializes the default font */ void Font::initDefaultFont() { // temporarily create a Font. Font::defaultFontData = FontData::Pointer(new FontData); // apply the Data. Font::defaultFontData = Font(font_xpm).data; } /** * @brief sets The Font. * @param fontFile The file containing the font. * @returns true if loaded, false if something went wrong, or if a font was loaded before. */ bool Font::loadFontFromTTF(const std::string& fontFile, unsigned int renderSize) { this->data = FontData::Pointer (new FontData()); bool retVal = this->data->loadFontFromTTF(fontFile, renderSize); if (!retVal) this->data = Font::defaultFontData; this->setTexture(this->data->textureData()); return retVal; } /** * @brief loads a font From an XPM-array. * @param xpmArray the array of the XPM to load the font from. */ bool Font::loadFontFromSDL_Surface(SDL_Surface* surface) { this->data = FontData::Pointer (new FontData()); bool retVal = this->data->loadFontFromSDL_Surface(surface); if (!retVal) this->data = Font::defaultFontData; this->setTexture(this->data->textureData()); return retVal; } /** * @brief sets a specific data->renderStyle * @param data->renderStyle the Style to render: a string (char-array) containing: * i: italic, b: bold, u, underline */ void Font::setStyle(const std::string& renderStyle) { /// FIXME //this->data->setStyle(renderStyle); } void Font::setTexture(const TextureData::Pointer& texDataPointer) { this->setDiffuseMap(texDataPointer); } /** * @brief creates and exports an Image, that has all the characters * stored in a Array (as an image) * @param fileName the File to write the image into. */ void Font::createAsciiImage(const std::string& ttfFile, const std::string& fileName, unsigned int size) { TTF_Font* fontTTF = TTF_OpenFont(ttfFile.c_str(), size); if (fontTTF == NULL) return; int height = TTF_FontHeight(fontTTF); // // Surface definition. SDL_Rect tmpRect; // this represents a Rectangle for blitting. SDL_Surface* tmpSurf = SDL_CreateRGBSurface(SDL_SWSURFACE, height*size, height*size, 32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif ); tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h; SDL_SetClipRect(tmpSurf, &tmpRect); int posX, posY; // all the interessting Glyphs for (posY = 0; posY < 16; posY++) { for (posX = 0; posX < 16; posX++) { SDL_Surface* glyphSurf = NULL; SDL_Color white = {255, 255, 255}; glyphSurf = TTF_RenderGlyph_Blended(fontTTF, posX+size*posY, white); if( glyphSurf != NULL ) { tmpRect.x = height*posX; tmpRect.y = height*posY; SDL_SetAlpha(glyphSurf, 0, 0); SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect); SDL_FreeSurface(glyphSurf); } } } SDL_SaveBMP(tmpSurf, fileName.c_str()); SDL_FreeSurface(tmpSurf); TTF_CloseFont(fontTTF); } /** * @brief a simple function to get some interesting information about this class */ void Font::debug() const { Material::debug(); //PRINT(0)("TEST %p and %p\n", this->data.get(), this->data->textureData().get()); // print the loaded font's style /* int style = TTF_STYLE_NORMAL; if (likely(this->data->fontTTF != NULL)) style = TTF_GetFontStyle(this->data->fontTTF); PRINTF(0)("The font style is:"); if(style==TTF_STYLE_NORMAL) PRINTF(0)(" normal"); else { if(style&TTF_STYLE_BOLD) PRINTF(0)(" bold"); if(style&TTF_STYLE_ITALIC) PRINTF(0)(" italic"); if(style&TTF_STYLE_UNDERLINE) PRINTF(0)(" underline");*/ // } PRINTF(0)("\n"); }