• Main Page
  • Namespaces
  • Classes
  • Files
  • File List

font.cpp

Go to the documentation of this file.
00001 #include "font.h"
00002 #include "application.h"
00003 #include <gctypes.h>
00004 #include <ogc/gx_struct.h>
00005 #include <ogc/cache.h>
00006 #include <vector>
00007 #include <map>
00008 #include <string.h>
00009 #include <malloc.h>
00010 
00011 namespace wit {
00012 
00072 FontSymbol::FontSymbol() : data(0), texWidth(0), texHeight(0), leftBearing(0), charWidth(0)
00073 {
00074     // initializers only
00075 }
00076 
00077 struct FontPrivate {
00078     bool registered;
00079     std::vector<FontSymbol> symbols;
00080     unsigned char wordSpacing;
00081 };
00082 
00083 struct FontRegistry {
00084     FontRegistry(const std::string& name) : name(name), next(0) {}
00085     std::string name;
00086     FontPrivate* normal;
00087     FontPrivate* bold;
00088     FontPrivate* italic;
00089     FontPrivate* boldItalic;
00090     FontRegistry* next;
00091 };
00092 
00093 static FontRegistry* wit_font_registry = 0;
00094 
00095 static FontRegistry* wit_find_font(const std::string& name)
00096 {
00097     FontRegistry* r = wit_font_registry;
00098     while(r) {
00099         if(r->name == name) return r;
00100         r = r->next;
00101     }
00102     return 0;
00103 }
00104 
00129 Font::Font() : d(new FontPrivate)
00130 {
00131     d->registered = false;
00132     d->symbols.resize(94);
00133 }
00134 
00142 Font::Font(const std::string& fontName, bool bold, bool italic) : d(0)
00143 {
00144     FontRegistry* r = wit_find_font(fontName);
00145     if(r) {
00146         if(!bold && !italic)
00147             d = r->normal;
00148         else if(bold && !italic)
00149             d = r->bold;
00150         else if(!bold && italic)
00151             d = r->italic;
00152         else
00153             d = r->boldItalic;
00154     }
00155 }
00156 
00160 Font::~Font()
00161 {
00162     if(d && !d->registered)
00163         delete d;
00164 }
00165 
00171 bool Font::isValid() const
00172 {
00173     return d;
00174 }
00175 
00183 void Font::setChar(unsigned char symbol, int texWidth, int texHeight, char* data, int leftBearing, int width)
00184 {
00185     if(!d || symbol < 33 || symbol > 126) return;
00186     int length = texWidth * texHeight;
00187     symbol -= 33;
00188     FontSymbol s;
00189     s.texWidth = texWidth;
00190     s.texHeight = texHeight;
00191     s.data = (char*)memalign(32, length);
00192     memcpy(s.data, data, length);
00193     s.leftBearing = leftBearing;
00194     s.charWidth = width;
00195     d->symbols[symbol] = s;
00196     DCFlushRange(s.data, length);
00197 }
00198 
00203 FontSymbol Font::charData(unsigned char symbol) const
00204 {
00205     if(!d || symbol < 33 || ((unsigned int)symbol - 33) >= d->symbols.size()) return FontSymbol();
00206     return d->symbols[symbol - 33];
00207 }
00208 
00213 void Font::registerFont(const std::string& fontName, bool bold, bool italic, int wordSpacing)
00214 {
00215     if(!d || d->registered) return;
00216 
00217     d->registered = true;
00218 
00219     FontRegistry* r = wit_find_font(fontName);
00220     if(!r) {
00221         r = new FontRegistry(fontName);
00222         r->normal = 0;
00223         r->bold = 0;
00224         r->italic = 0;
00225         r->boldItalic = 0;
00226         r->next = wit_font_registry;
00227         wit_font_registry = r;
00228     }
00229 
00230     d->wordSpacing = wordSpacing;
00231 
00232     if(!bold && !italic)
00233         r->normal = d;
00234     else if(bold && !italic)
00235         r->bold = d;
00236     else if(!bold && italic)
00237         r->italic = d;
00238     else
00239         r->boldItalic = d;
00240 }
00241 
00245 float Font::draw(float x, float y, const std::string& text, const GXColor& color)
00246 {
00247     if(!d || !d->registered) return x;
00248 
00249     // TODO: add font rendering to Renderer to allow transformations and easier text widgets
00250 
00251     Mtx44 perspective;
00252     guOrtho(perspective, 0, wit::Application::instance()->screenHeight(), 0, wit::Application::instance()->screenWidth(), 0, 300);
00253     GX_LoadProjectionMtx(perspective, GX_ORTHOGRAPHIC);
00254     
00255     GX_SetNumChans(1);
00256     GX_SetNumTexGens(1);
00257     GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
00258     GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
00259     GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
00260 
00261     GX_ClearVtxDesc();
00262     GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
00263     GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
00264     GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
00265 
00266     int ct = text.size();
00267     GXTexObj texObj;
00268     for(int i = 0; i < ct; i++) {
00269         if(text[i] < 33) {
00270             x += d->wordSpacing;
00271             continue;
00272         }
00273         FontSymbol s = charData(text[i]);
00274         if(!s.data) continue;
00275         x += int(s.leftBearing);
00276 
00277         GX_InitTexObj(&texObj, s.data, s.texWidth, s.texHeight, GX_TF_IA4, GX_CLAMP, GX_CLAMP, GX_FALSE);
00278         GX_LoadTexObj(&texObj, GX_TEXMAP0);
00279         GX_InvalidateTexAll();
00280 
00281         GX_Begin(GX_QUADS, GX_VTXFMT7, 4); // TODO: pass all quads at once
00282         GX_Position2f32(x, y);
00283         GX_Color4u8(color.r, color.g, color.b, color.a);
00284         GX_TexCoord2f32(0, 0);
00285         GX_Position2f32(x + s.texWidth, y);
00286         GX_Color4u8(color.r, color.g, color.b, color.a);
00287         GX_TexCoord2f32(1, 0);
00288         GX_Position2f32(x + s.texWidth, y + s.texHeight);
00289         GX_Color4u8(color.r, color.g, color.b, color.a);
00290         GX_TexCoord2f32(1, 1);
00291         GX_Position2f32(x, y + s.texHeight);
00292         GX_Color4u8(color.r, color.g, color.b, color.a);
00293         GX_TexCoord2f32(0, 1);
00294         GX_End();
00295         x += int(s.charWidth) - int(s.leftBearing);
00296     }
00297 
00298     return x;
00299 }
00300 
00301 }

Generated on Sat Sep 3 2011 10:25:00 for wit by  doxygen 1.7.2