/* * Copyright (C) 2002,2003,2004 Daniel Heck * * 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 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * $Id: font.cc,v 1.4 2004/04/20 19:15:29 dheck Exp $ */ #include "font.hh" #include "geom.hh" #include "video.hh" #include #include #include // for auto_ptr #include #include "../config.h" using namespace px; using namespace std; int Font::get_width(const char *str) { int w=0; for (const char *p = str; *p; ++p) w += get_width(*p); return w; } // // Bitmap fonts // namespace { class InvalidFont {}; class BitmapFont : public Font { vector char_rects; vector advance; Surface *surface; public: BitmapFont(Surface *s, const char *descr); ~BitmapFont() { delete surface; } int get_lineskip() { return surface->height() + 3; } int get_width(char c); int get_height(); Surface *render(const char *str); void render(const GC &gc, int x, int y, const char *str); }; } BitmapFont::BitmapFont(Surface *s, const char *descr) : char_rects(256), advance(256), surface(s) { // Read and interpret the font description file. // expected line format: // charno xpos width xadvance FILE *fp=fopen(descr, "rt"); if (!fp) return ; //throw InvalidFont(); int c; int x=0, w=0, adv=0; while (fscanf(fp, "%d %d %d %d\n", &c, &x, &w, &adv) != EOF) { char_rects[c].x = x; char_rects[c].w = w; char_rects[c].y = 0; char_rects[c].h = s->height(); advance[c] = adv; } } int BitmapFont::get_width(char c) { return advance[int(c)]; } int BitmapFont::get_height() { return surface->height(); } Surface * BitmapFont::render(const char *str) { Surface *s = MakeSurface(Font::get_width(str), get_height(), 16); s->set_color_key(0,0,0); render (GC(s), 0, 0, str); return s; } void BitmapFont::render(const GC &gc, int x, int y, const char *str) { for (const char *p=str; *p; ++p) { blit(gc, x, y, surface, char_rects[int(*p)]); x += get_width(*p); } } Font * px::LoadBitmapFont(const char * imgname, const char * descrname) { if (Surface *s = LoadImage(imgname)) return new BitmapFont(s, descrname); return 0; } #ifndef HAVE_SDLTTF Font *px::LoadTTF (const char * /*filename*/, int /*ptsize*/, int, int, int) { return 0; } #else /* if defined (HAVE_SDLTTF) */ // // TrueType fonts (using SDL_ttf if available) // #include "SDL_ttf.h" namespace { class TrueTypeFont : public Font { // Variables TTF_Font *font; SDL_Color fgcolor; // Inhibit copying TrueTypeFont (const TrueTypeFont &); TrueTypeFont &operator= (const TrueTypeFont &); public: TrueTypeFont (TTF_Font *font_, int r, int g, int b); ~TrueTypeFont(); // Font interface int get_lineskip(); int get_height(); int get_width (char c); int get_width (const char *str); Surface *render (const char *str); void render (const GC &gc, int x, int y, const char *str); }; } TrueTypeFont::TrueTypeFont (TTF_Font *font_, int r, int g, int b) : font (font_) { fgcolor.r = r; fgcolor.g = g; fgcolor.b = b; } TrueTypeFont::~TrueTypeFont() { TTF_CloseFont (font); } int TrueTypeFont::get_lineskip() { return TTF_FontLineSkip (font); } int TrueTypeFont::get_height() { return TTF_FontHeight(font); } int TrueTypeFont::get_width(char c) { int minx, maxx, miny, maxy, advance; TTF_GlyphMetrics(font, c, &minx, &maxx, &miny, &maxy, &advance); return advance; } Surface *TrueTypeFont::render (const char *str) { SDL_Surface *s = 0; SDL_Color bgcolor = { 0, 0, 0, 0 }; s = TTF_RenderUTF8_Shaded (font, str, fgcolor, bgcolor); if (s) { SDL_SetColorKey (s, SDL_SRCCOLORKEY,0); return Surface::make_surface (s); } return MakeSurface(0, get_height(), 16); } void TrueTypeFont::render (const GC &gc, int x, int y, const char *str) { std::auto_ptr s (render (str)); if (s.get()) blit (gc, x, y, s.get()); } int TrueTypeFont::get_width(const char *str) { int w,h; TTF_SizeUTF8 (font, str, &w, &h); return w; } Font *px::LoadTTF (const char *filename, int ptsize, int r, int g, int b) { if (TTF_Init()) { // Error initializing TTF engine } TTF_Font *font = TTF_OpenFont (filename, ptsize); return (font) ? new TrueTypeFont (font, r, g, b) : 0; } #endif