00001
00002
00003
00004
00005
00006
00007
00008
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
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
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;
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
00269
00270 }
00271 }
00272 break;
00273
00274 case UTF8DecodeMultibyte:
00275 if ((c & 0xc0) == 0x80)
00276 {
00277
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
00289
00290 decodeState = UTF8DecodeStart;
00291 }
00292 break;
00293 }
00294 }
00295
00296 return c;
00297 }