subimagefont.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 #include <string>
00024 
00025 // Platform specific includes
00026 #include "util/base/fife_stdint.h"
00027 
00028 // 3rd party library includes
00029 #include <SDL.h>
00030 
00031 // FIFE includes
00032 // These includes are split up in two parts, separated by one empty line
00033 // First block: files included from the FIFE root src directory
00034 // Second block: files included from the same folder
00035 #include "util/base/exception.h"
00036 #include "util/log/logger.h"
00037 #include "util/structures/rect.h"
00038 #include "util/utf8/utf8.h"
00039 #include "video/image.h"
00040 #include "video/imagemanager.h"
00041 #include "video/renderbackend.h"
00042 
00043 #include "subimagefont.h"
00044 
00045 namespace FIFE {
00046     static Logger _log(LM_GUI);
00047 
00048     SubImageFont::SubImageFont(const std::string& filename, const std::string& glyphs)
00049         : ImageFontBase() {
00050 
00051         FL_LOG(_log, LMsg("guichan_image_font, loading ") << filename << " glyphs " << glyphs);
00052 
00053 //prock - 504
00054         ImagePtr img = ImageManager::instance()->load(filename);
00055         int32_t image_id = img->getHandle();
00056         SDL_Surface* surface = img->getSurface();
00057         m_colorkey = RenderBackend::instance()->getColorKey();
00058 
00059         if( !surface ) {
00060             throw CannotOpenFile(filename);
00061         }
00062 
00063         // Make sure we get 32bit RGB
00064         // and copy the Pixelbuffers surface
00065         SDL_Surface *tmp = SDL_CreateRGBSurface(SDL_SWSURFACE,
00066             surface->w,surface->h,32,
00067             RMASK, GMASK, BMASK ,NULLMASK);
00068 
00069         SDL_BlitSurface(surface,0,tmp,0);
00070         surface = tmp;
00071 
00072         // Prepare the data for extracting the glyphs.
00073         uint32_t *pixels = reinterpret_cast<uint32_t*>(surface->pixels);
00074 
00075         int32_t x, w;
00076         x = 0; w=0;
00077 
00078         SDL_Rect src;
00079 
00080         src.h = surface->h;
00081         src.y = 0;
00082         
00083         uint32_t separator = pixels[0];
00084         uint32_t colorkey = SDL_MapRGB(surface->format, m_colorkey.r, m_colorkey.g, m_colorkey.b);
00085 
00086         // if colorkey feature is not enabled then manually find the color key in the font
00087         if (!RenderBackend::instance()->isColorKeyEnabled()) {
00088             while(x < surface->w && pixels[x] == separator) {
00089                 ++x;
00090             }
00091             
00092             colorkey = pixels[x];
00093         }
00094         
00095         // Disable alpha blending, so that we use color keying
00096         SDL_SetAlpha(surface,0,255);
00097         SDL_SetColorKey(surface,SDL_SRCCOLORKEY,colorkey);
00098 
00099         FL_DBG(_log, LMsg("image_font")
00100             << " glyph separator is " 
00101             << pprint(reinterpret_cast<void*>(separator))
00102             << " transparent color is " 
00103             << pprint(reinterpret_cast<void*>(colorkey)));
00104 
00105         // Finally extract all glyphs
00106         std::string::const_iterator text_it = glyphs.begin();
00107         while(text_it != glyphs.end()) {
00108             w=0;
00109             while(x < surface->w && pixels[x] == separator)
00110                 ++x;
00111             if( x == surface->w )
00112                 break;
00113 
00114             while(x + w < surface->w && pixels[x + w] != separator)
00115                 ++w;
00116 
00117             src.x = x;
00118             src.w = w;
00119 
00120             tmp = SDL_CreateRGBSurface(SDL_SWSURFACE,
00121                     w,surface->h,32,
00122                     RMASK, GMASK, BMASK ,NULLMASK);
00123 
00124             SDL_FillRect(tmp,0,colorkey);
00125             SDL_BlitSurface(surface,&src,tmp,0);
00126 
00127             // Disable alpha blending, so that we use colorkeying
00128             SDL_SetAlpha(tmp,0,255);
00129             SDL_SetColorKey(tmp,SDL_SRCCOLORKEY,colorkey);
00130 
00131 
00132             uint32_t codepoint = utf8::next(text_it, glyphs.end());
00133             m_glyphs[ codepoint ].surface = tmp;
00134 
00135             x += w;
00136         }
00137 
00138         // Set placeholder glyph
00139         // This should actually work ith utf8.
00140         if( m_glyphs.find('?') != m_glyphs.end() ) {
00141             m_placeholder = m_glyphs['?'];
00142         } else {
00143             m_placeholder.surface = 0;
00144         }
00145 
00146         mHeight = surface->h;
00147         SDL_FreeSurface(surface);
00148     }
00149 
00150 
00151 }
00152