Adonthell  0.4
win_ttf.cc
00001 /*
00002    $Id: win_ttf.cc,v 1.3 2006/09/03 20:48:08 ksterker Exp $
00003    
00004    (C) Copyright 2004 Kai Sterker
00005    Part of the Adonthell Project http://adonthell.linuxgames.com
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details
00013 */
00014 
00015 #include <ctype.h>
00016 #include "win_ttf.h"
00017 
00018 // number of references to font file
00019 u_int32 win_ttf::refcount = 0;
00020 // font file used
00021 TTF_Font *win_ttf::ttf = NULL;
00022 
00023 // ctor
00024 win_ttf::win_ttf (const char *color, const string & file) : win_font ()
00025 {
00026     switch (color[0])
00027     {
00028         case 'r':       // red
00029             Color.r = 255; Color.g = 173; Color.b = 123;
00030             break;
00031         case 'b':       // blue
00032             Color.r = 139; Color.g = 185; Color.b = 238;
00033             break;
00034         case 'g':       // green
00035             Color.r = 205; Color.g = 254; Color.b = 148;
00036             break;
00037         case 'y':       // yellow
00038             Color.r = 255; Color.g = 238; Color.b = 123;
00039             break;
00040         case 'v':       // violet
00041             Color.r = 222; Color.g = 133; Color.b = 230;
00042             break;
00043         default:        // white and all the rest
00044             Color.r = 255; Color.g = 255; Color.b = 255;
00045             break;
00046     }
00047         
00048     refcount++;
00049     
00050     if (load (file)) 
00051     {
00052         u_int16 real_height_ = TTF_FontAscent (ttf);
00053         height_ = screen::dbl_mode () ? (real_height_+3) >> 1 : real_height_+1;
00054         cursor = &operator[]('_');
00055         length_ = cursor->length ();
00056     }
00057     // fallback to old win_font implementation
00058     else win_font::load ((char *) color);
00059 }
00060 
00061 win_ttf::~win_ttf ()
00062 {
00063     refcount--;
00064     cursor = NULL;
00065     if (refcount == 0 && ttf != NULL)
00066         TTF_CloseFont (ttf);
00067 }
00068     
00069 bool win_ttf::load (const string & file)
00070 {
00071     string path;
00072 
00073     // size of font
00074     u_int32 size = screen::dbl_mode () ? 22 : 12;
00075     
00076     // load font only once 
00077     if (ttf != NULL) return true;
00078     
00079     // absolute or relative font file from config?
00080     if (file != "" && file[0] == '/')
00081     {
00082         path = file;
00083     }
00084     else 
00085     {
00086         // path where is the file
00087         path = WIN_DIRECTORY; 
00088   
00089         // add win font directory path
00090         path += WIN_FONT_DIRECTORY; 
00091 
00092         // font name from config file
00093         path += file == "" ? "avatar.ttf" : file;
00094     }
00095     
00096     // try to load font specified in cfg file
00097     ttf = TTF_OpenFont (path.c_str (), size);
00098     
00099     if (ttf == NULL)
00100     {
00101         printf ("*** error loading font '%s':\n %s\n", path.c_str (), TTF_GetError ());
00102         return false;
00103     }
00104     
00105     // make sure our font doesn't exceed a pixel size of 24/13
00106     while (TTF_FontAscent (ttf) > (screen::dbl_mode () ? 24 : 13)) {
00107         TTF_CloseFont (ttf);
00108         TTF_OpenFont (path.c_str (), --size);
00109     }
00110     
00111     return true;
00112 }
00113 
00114 bool win_ttf::in_table(u_int16 tmp)
00115 {
00116     if (win_font::in_table (tmp) == true) return true;
00117     
00118     // try to create font
00119     if (tmp > 0x80 || isprint (tmp)) {
00120         operator[](tmp);
00121         return true;
00122     }
00123     return false;
00124 }
00125 
00126 image & win_ttf::operator[](u_int16 glyph)
00127 {
00128     static u_int16 unichar[2] = { 0, 0 };
00129     unichar[0] = glyph;
00130 
00131     static SDL_Color bg = { 0x00, 0x00, 0x00, 0 };
00132     static SDL_Color white = { 0xff, 0xff, 0xff, 0 };
00133     if (win_font::in_table (glyph)) return *(glyphs[glyph]);
00134     if (ttf == NULL) return *(glyphs[' ']);
00135     
00136     SDL_Surface *s = TTF_RenderUNICODE_Shaded (ttf, unichar, Color, bg);
00137     if (s == NULL) return *(glyphs[' ']);
00138     
00139     image tmp (s, bg);
00140     image *glph = new image (tmp.length(), height_, false);
00141     glph->fillrect (0, 0, tmp.length()+1, height_+1, screen::trans_col(), NULL);
00142 
00143     s = TTF_RenderUNICODE_Solid (ttf, unichar, bg);
00144     if (s != NULL)
00145     {
00146         image shadow (s, white);
00147         shadow.draw (1, 1+height_-shadow.height(), 0, 0, shadow.length(), shadow.height(), NULL, glph);
00148     }
00149     else
00150     {
00151         fprintf (stderr, "%s\n", TTF_GetError ());
00152     }
00153     
00154     tmp.draw (0, height_-tmp.height(), 0, 0, tmp.length(), tmp.height(), NULL, glph);
00155     glyphs[glyph] = glph;
00156 
00157     return *glph;
00158 }
00159