Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

overlay.cpp

Go to the documentation of this file.
00001 // overlay.cpp
00002 //
00003 // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <cstdarg>
00011 #include <cstdio>
00012 #include <celutil/utf8.h>
00013 #include "gl.h"
00014 #include "vecgl.h"
00015 #include "overlay.h"
00016 
00017 using namespace std;
00018 
00019 
00020 Overlay::Overlay() :
00021     ostream(&sbuf),
00022     windowWidth(1),
00023     windowHeight(1),
00024     font(NULL),
00025     useTexture(false),
00026     fontChanged(false),
00027     textBlock(0)
00028 {
00029     sbuf.setOverlay(this);
00030 }
00031 
00032 Overlay::~Overlay()
00033 {
00034 }
00035 
00036 
00037 void Overlay::begin()
00038 {
00039     glMatrixMode(GL_PROJECTION);
00040     glPushMatrix();
00041     glLoadIdentity();
00042     gluOrtho2D(0, windowWidth, 0, windowHeight);
00043     glMatrixMode(GL_MODELVIEW);
00044     glPushMatrix();
00045     glLoadIdentity();
00046     glTranslatef(0.125f, 0.125f, 0);
00047 
00048     glDisable(GL_LIGHTING);
00049     glDisable(GL_TEXTURE_2D);
00050     glEnable(GL_BLEND);
00051     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00052 
00053     useTexture = false;
00054 }
00055 
00056 void Overlay::end()
00057 {
00058     glMatrixMode(GL_PROJECTION);
00059     glPopMatrix();
00060     glMatrixMode(GL_MODELVIEW);
00061     glPopMatrix();
00062 }
00063 
00064 
00065 void Overlay::setWindowSize(int w, int h)
00066 {
00067     windowWidth = w;
00068     windowHeight = h;
00069 }
00070 
00071 void Overlay::setFont(TextureFont* f)
00072 {
00073     if (f != font)
00074     {
00075         font = f;
00076         fontChanged = true;
00077     }
00078 }
00079 
00080 
00081 void Overlay::beginText()
00082 {
00083     glPushMatrix();
00084     textBlock++;
00085 }
00086 
00087 void Overlay::endText()
00088 {
00089     if (textBlock > 0)
00090     {
00091         textBlock--;
00092         glPopMatrix();
00093     }
00094 }
00095 
00096 
00097 void Overlay::print(wchar_t c)
00098 {
00099     if (font != NULL)
00100     {
00101         if (!useTexture || fontChanged)
00102         {
00103             glEnable(GL_TEXTURE_2D);
00104             font->bind();
00105             useTexture = true;
00106             fontChanged = false;
00107         }
00108 
00109         switch (c)
00110         {
00111         case '\n':
00112             if (textBlock > 0)
00113             {
00114                 glPopMatrix();
00115                 glTranslatef(0, -(1 + font->getHeight()), 0);
00116                 glPushMatrix();
00117             }
00118             break;
00119         default:
00120             font->render(c);
00121             break;
00122         }
00123     }
00124 }
00125 
00126 
00127 void Overlay::print(char c)
00128 {
00129     if (font != NULL)
00130     {
00131         if (!useTexture || fontChanged)
00132         {
00133             glEnable(GL_TEXTURE_2D);
00134             font->bind();
00135             useTexture = true;
00136             fontChanged = false;
00137         }
00138 
00139         switch (c)
00140         {
00141         case '\n':
00142             if (textBlock > 0)
00143             {
00144                 glPopMatrix();
00145                 glTranslatef(0, -(1 + font->getHeight()), 0);
00146                 glPushMatrix();
00147             }
00148             break;
00149         default:
00150             font->render(c);
00151             break;
00152         }
00153     }
00154 }
00155 
00156 void Overlay::print(char* s)
00157 {
00158 #if 0
00159     while (*s != '\0')
00160         print(*s++);
00161 #else
00162     int length = strlen(s);
00163     bool validChar = true;
00164         int i = 0;
00165     while (i < length && validChar)
00166     {
00167         wchar_t ch = 0;
00168         validChar = UTF8Decode(s, i, length, ch);
00169         i += UTF8EncodedSize(ch);
00170         print(ch);
00171     }
00172 #endif    
00173 }
00174 
00175 
00176 void Overlay::printf(const char* format, ...)
00177 {
00178     va_list args;
00179     va_start(args, format);
00180 
00181     char buf[1024];
00182     vsprintf(buf, format, args);
00183     print(buf);
00184     
00185     va_end(args);
00186 }
00187 
00188 
00189 void Overlay::rect(float x, float y, float w, float h, bool fill)
00190 {
00191     if (useTexture)
00192     {
00193         glDisable(GL_TEXTURE_2D);
00194         useTexture = false;
00195     }
00196 
00197     if (fill)
00198     {
00199         glRectf(x, y, x + w, y + h);
00200     }
00201     else
00202     {
00203         glBegin(GL_LINE_LOOP);
00204         glVertex3f(x, y, 0);
00205         glVertex3f(x + w, y, 0);
00206         glVertex3f(x + w, y + h, 0);
00207         glVertex3f(x, y + h, 0);
00208         glEnd();
00209     }
00210 }
00211 
00212 
00213 //
00214 // OverlayStreamBuf implementation
00215 //
00216 OverlayStreamBuf::OverlayStreamBuf() :
00217     overlay(NULL),
00218     decodeState(UTF8DecodeStart)
00219 {
00220     setbuf(0, 0);
00221 };
00222 
00223 
00224 void OverlayStreamBuf::setOverlay(Overlay* o)
00225 {
00226     overlay = o;
00227 }
00228 
00229 
00230 int OverlayStreamBuf::overflow(int c)
00231 {
00232     if (overlay != NULL)
00233     {
00234         switch (decodeState)
00235         {
00236         case UTF8DecodeStart:
00237             if (c < 0x80)
00238             {
00239                 // Just a normal 7-bit character
00240                 overlay->print((char) c);
00241             }
00242             else
00243             {
00244                 unsigned int count;
00245 
00246                 if ((c & 0xe0) == 0xc0)
00247                     count = 2;
00248                 else if ((c & 0xf0) == 0xe0)
00249                     count = 3;
00250                 else if ((c & 0xf8) == 0xf0)
00251                     count = 4;
00252                 else if ((c & 0xfc) == 0xf8)
00253                     count = 5;
00254                 else if ((c & 0xfe) == 0xfc)
00255                     count = 6;
00256                 else
00257                     count = 1; // Invalid byte
00258 
00259                 if (count > 1)
00260                 {
00261                     unsigned int mask = (1 << (7 - count)) - 1;
00262                     decodeShift = (count - 1) * 6;
00263                     decodedChar = (c & mask) << decodeShift;
00264                     decodeState = UTF8DecodeMultibyte;
00265                 }
00266                 else
00267                 {
00268                     // If the character isn't valid multibyte sequence head,
00269                     // silently skip it by leaving the decoder state alone.
00270                 }
00271             }
00272             break;
00273 
00274         case UTF8DecodeMultibyte:
00275             if ((c & 0xc0) == 0x80)
00276             {
00277                 // We have a valid non-head byte in the sequence
00278                 decodeShift -= 6;
00279                 decodedChar |= (c & 0x3f) << decodeShift;
00280                 if (decodeShift == 0)
00281                 {
00282                     overlay->print(decodedChar);
00283                     decodeState = UTF8DecodeStart;
00284                 }
00285             }
00286             else
00287             {
00288                 // Bad byte in UTF-8 encoded sequence; we'll silently ignore
00289                 // it and reset the state of the UTF-8 decoder.
00290                 decodeState = UTF8DecodeStart;
00291             }
00292             break;
00293         }
00294     }
00295 
00296     return c;
00297 }

Generated on Sat Jan 14 22:30:28 2006 for Celestia by  doxygen 1.4.1