1 /*
2 Copyright (C) 2007, 2010 - Bit-Blot
3
4 This file is part of Aquaria.
5
6 Aquaria is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 #include "BitmapFont.h"
22 #include "Core.h"
23 //#include "DSQ.h"
24
25 using namespace glfont;
26
BmpFont()27 BmpFont::BmpFont()
28 {
29 scale = 1;
30 loaded = false;
31 overrideTexture = 0;
32 fontTopColor = Vector(1,1,1);
33 fontBtmColor = Vector(1,1,1);
34 }
35
~BmpFont()36 BmpFont::~BmpFont()
37 {
38 destroy();
39 }
40
destroy()41 void BmpFont::destroy()
42 {
43 if (loaded)
44 {
45 font.Destroy();
46 loaded = false;
47 }
48
49 overrideTexture = NULL;
50 }
51
load(const std::string & file,float scale,bool loadTexture)52 void BmpFont::load(const std::string &file, float scale, bool loadTexture)
53 {
54 if (loaded)
55 font.Destroy();
56
57 this->scale = scale;
58
59 #ifdef BBGE_BUILD_OPENGL
60 GLuint id=0;
61 glGenTextures(1, &id);
62
63 if (!font.Create(file.c_str(), id, loadTexture))
64 return;
65
66 #endif
67
68 loaded = true;
69 }
70
71 Texture *fontTextureTest = 0;
BitmapText(BmpFont * bmpFont)72 BitmapText::BitmapText(BmpFont *bmpFont)
73 {
74 this->bmpFont = bmpFont;
75 bfePass =0;
76 bfe = BFE_NONE;
77
78 currentScrollLine = currentScrollChar = 0;
79 scrollDelay = 0;
80 scrolling = false;
81 align = ALIGN_CENTER;
82 textWidth = 600;
83 this->fontDrawSize = 24;
84 //color = Vector(0.5,0.5,1);
85 cull = false;
86 //setTexture(font);
87
88 alignWidth = 0;
89
90 //fontTextureTest = core->addTexture("font");
91 }
92
autoKern()93 void BitmapText::autoKern()
94 {
95 }
96
loadSpacingMap(const std::string & file)97 void BitmapText::loadSpacingMap(const std::string &file)
98 {
99 spacingMap.clear();
100 InStream inFile(file.c_str());
101 std::string line;
102 while (std::getline(inFile, line))
103 {
104 if (!line.empty())
105 {
106 char c = line[0];
107 line = line.substr(2, line.length());
108 std::istringstream is(line);
109 is >> spacingMap[c];
110 }
111 }
112 }
113
getWidthOnScreen()114 int BitmapText::getWidthOnScreen()
115 {
116 return text.size()*(fontDrawSize/2);
117 }
118
setAlign(Align align)119 void BitmapText::setAlign(Align align)
120 {
121 this->align = align;
122 }
123
getText()124 std::string BitmapText::getText()
125 {
126 return this->text;
127 }
128
setText(const std::string & text)129 void BitmapText::setText(const std::string &text)
130 {
131 this->text = text;
132 formatText();
133 }
134
setWidth(float width)135 void BitmapText::setWidth(float width)
136 {
137 textWidth = width;
138 }
139
getSetWidth()140 float BitmapText::getSetWidth()
141 {
142 return textWidth;
143 }
144
getHeight()145 float BitmapText::getHeight()
146 {
147 float sz = bmpFont->font.GetCharHeight('A') * bmpFont->scale;
148 return lines.size()*sz;
149 }
150
getLineHeight()151 float BitmapText::getLineHeight()
152 {
153 return bmpFont->font.GetCharHeight('A') * bmpFont->scale;
154 }
155
formatText()156 void BitmapText::formatText()
157 {
158 std::string text;
159 text = this->text;
160 lines.clear();
161 std::string currentLine;
162 int lastSpace = -1;
163 float currentWidth = 0;
164 alignWidth = 0;
165 maxW = 0;
166 for (int i = 0; i < text.size(); i++)
167 {
168 //currentWidth += spacingMap[text[i]]*fontDrawSize;
169 float sz = bmpFont->font.GetCharWidth(text[i])*bmpFont->scale;
170 currentWidth += sz;
171
172 if (currentWidth+sz >= textWidth || text[i] == '\n')
173 {
174 if (text[i] == '\n')
175 {
176 lastSpace = i;
177 }
178 lines.push_back(text.substr(0, lastSpace));
179 int tsz = text.size();
180 text = text.substr(lastSpace+1, tsz);
181 i = 0;
182 alignWidth = currentWidth;
183 maxW = std::max(currentWidth, maxW);
184 currentWidth = 0;
185 lastSpace = 0;
186 continue;
187 }
188
189 if (text[i] == ' ')
190 {
191 lastSpace = i;
192 }
193 }
194 maxW = std::max(currentWidth, maxW);
195 if (alignWidth == 0)
196 alignWidth = currentWidth;
197 if (!text.empty() && (text.size() > 1 || text[0] != ' '))
198 {
199 lines.push_back(text);
200 }
201 colorIndices.clear();
202 }
203
setBitmapFontEffect(BitmapFontEffect bfe)204 void BitmapText::setBitmapFontEffect(BitmapFontEffect bfe)
205 {
206 this->bfe = bfe;
207 }
208
updateWordColoring()209 void BitmapText::updateWordColoring()
210 {
211 colorIndices.resize(lines.size());
212 for (int i = 0; i < colorIndices.size(); i++)
213 {
214 colorIndices[i].resize(lines[i].size());
215 for (int j = 0; j < colorIndices[i].size(); j++)
216 {
217 colorIndices[i][j] = Vector(1,1,1);
218 }
219 }
220
221 /*
222 for (int i = 0; i < lines.size(); i++)
223 {
224 int c = 0;
225 for (int t = 0; t < dsq->continuity.wordColoring.size(); t++)
226 {
227 WordColoring *w = &dsq->continuity.wordColoring[t];
228 if ((c = lines[i].find(w->word)) != std::string::npos)
229 {
230 for (int j = c; j < c + w->word.size(); j++)
231 {
232 colorIndices[i][j] = w->color;
233 }
234 }
235 }
236 }
237 */
238 //lines.push_back(text);
239
240 }
241
isEmpty()242 bool BitmapText::isEmpty()
243 {
244 return lines.empty();
245 }
246
scrollText(const std::string & text,float scrollSpeed)247 void BitmapText::scrollText(const std::string &text, float scrollSpeed)
248 {
249 if (text.empty()) return;
250 this->scrollSpeed = scrollSpeed;
251 scrollDelay = scrollSpeed;
252 this->text = text;
253 scrolling = true;
254 formatText();
255 currentScrollLine = 0;
256 currentScrollChar = 0;
257 }
258
setFontSize(float sz)259 void BitmapText::setFontSize(float sz)
260 {
261 this->fontDrawSize = sz;
262 }
263
onUpdate(float dt)264 void BitmapText::onUpdate(float dt)
265 {
266 bfePass = 0;
267 RenderObject::onUpdate(dt);
268 if (scrollDelay > 0 && scrolling)
269 {
270 if (lines.empty())
271 {
272 currentScrollLine = 0;
273 scrolling = false;
274 scrollDelay = 0;
275 }
276 else
277 {
278 scrollDelay -= dt;
279 while (scrollDelay <= 0)
280 {
281 float diff = scrollDelay;
282 scrollDelay = scrollSpeed;
283 scrollDelay += diff;
284 currentScrollChar ++;
285 if (currentScrollChar >= lines[currentScrollLine].size())
286 {
287 currentScrollLine++;
288 currentScrollChar = 0;
289 if (currentScrollLine >= lines.size())
290 {
291 currentScrollLine = 0;
292 scrolling = false;
293 }
294 }
295 }
296 }
297 }
298 }
299
getColorIndex(int i,int j)300 Vector BitmapText::getColorIndex(int i, int j)
301 {
302 Vector c(1,1,1);
303 if (!(i < 0 || j < 0))
304 {
305 if ( i < colorIndices.size() && j < colorIndices[i].size())
306 {
307 c = colorIndices[i][j];
308 }
309 }
310 return c;
311 }
312
onRender()313 void BitmapText::onRender()
314 {
315 if (!bmpFont) return;
316 float top_color[3] = {bmpFont->fontTopColor.x*color.x, bmpFont->fontTopColor.y*color.y, bmpFont->fontTopColor.z*color.z};
317 float bottom_color[3] = {bmpFont->fontBtmColor.x*color.x, bmpFont->fontBtmColor.y*color.y, bmpFont->fontBtmColor.z*color.z};
318
319 #ifdef BBGE_BUILD_OPENGL
320 glEnable(GL_TEXTURE_2D);
321 /*
322 glEnable(GL_BLEND);
323 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
324 */
325 //glDisable(GL_CULL_FACE);
326
327 //glScalef(1, -1, 0);
328
329 bmpFont->font.Begin();
330
331 if (fontTextureTest) fontTextureTest->apply();
332
333 if (bmpFont->overrideTexture) bmpFont->overrideTexture->apply();
334
335 float y=0;
336 float x=0;
337
338 float adj = bmpFont->font.GetCharHeight('A') * bmpFont->scale;
339
340 if (scrolling)
341 {
342 for (int i = 0; i <= currentScrollLine; i++)
343 {
344 std::string theLine = lines[i];
345 if (i == currentScrollLine)
346 theLine = theLine.substr(0, currentScrollChar);
347
348 x=0;
349 if (align == ALIGN_CENTER)
350 {
351 std::pair<int, int> sz;
352 bmpFont->font.GetStringSize(lines[i], &sz);
353 x = -sz.first*0.5f*bmpFont->scale;
354 }
355 float la = 1.0f-(scrollDelay/scrollSpeed);
356 /*
357 std::ostringstream os;
358 os << "la: " << la;
359 debugLog(os.str());
360 */
361
362 bmpFont->font.DrawString(theLine, bmpFont->scale, x, y, top_color, bottom_color, alpha.x, la);
363 y += adj;
364 }
365 }
366 else
367 {
368 for (int i = 0; i < lines.size(); i++)
369 {
370 x=0;
371 if (align == ALIGN_CENTER)
372 {
373 std::pair<int, int> sz;
374 bmpFont->font.GetStringSize(lines[i], &sz);
375 x = -sz.first*0.5f*bmpFont->scale;
376 }
377 bmpFont->font.DrawString(lines[i], bmpFont->scale, x, y, top_color, bottom_color, alpha.x, 1);
378 y += adj;
379 }
380 }
381
382 //glEnable(GL_CULL_FACE);
383 glBindTexture(GL_TEXTURE_2D, 0);
384
385 #endif
386 }
387
unloadDevice()388 void BitmapText::unloadDevice()
389 {
390 RenderObject::unloadDevice();
391 }
392
reloadDevice()393 void BitmapText::reloadDevice()
394 {
395 RenderObject::reloadDevice();
396 setText(this->text);
397 }
398
render()399 void BitmapText::render()
400 {
401 RenderObject::render();
402 if (!bfePass)
403 {
404 if (bfe == BFE_SHADOWBLUR)
405 {
406 InterpolatedVector oldAlpha = alpha, oldPos = position;
407 Vector adjust(rand()%5-2, rand()%5-2+2);
408 position += adjust;
409 alpha *= 0.4f;
410 bfePass = 1;
411 RenderObject::render();
412 alpha = oldAlpha;
413 position = oldPos;
414 }
415 }
416 }
417
stopScrollingText()418 void BitmapText::stopScrollingText()
419 {
420 scrolling = false;
421 }
422
isScrollingText()423 bool BitmapText::isScrollingText()
424 {
425 return scrolling;
426 }
427
getNumLines()428 int BitmapText::getNumLines()
429 {
430 return lines.size();
431 }
432
getStringWidth(const std::string & text)433 float BitmapText::getStringWidth(const std::string& text)
434 {
435 std::string tmp;
436 int maxsize = 0;
437 tmp.reserve(text.length());
438 for (size_t i = 0; i < text.size(); i++)
439 {
440 if(text[i] == '\n')
441 {
442 std::pair<int, int> dim;
443 bmpFont->font.GetStringSize(tmp, &dim);
444 maxsize = std::max(maxsize, dim.first);
445 tmp.resize(0);
446 }
447 else
448 tmp += text[i];
449 }
450 std::pair<int, int> dim;
451 bmpFont->font.GetStringSize(tmp, &dim);
452 maxsize = std::max(maxsize, dim.first);
453
454 return maxsize * bmpFont->scale;
455 }
456
457 /*
458 BitmapText::BitmapText() : RenderObject()
459 {
460 cull = false;
461 followCamera = 1;
462 scrollSpeed = 0.1f;
463 }
464
465 void BitmapText::scrollText(const std::string &text, float scrollSpeed)
466 {
467 setText(text);
468 this->scrollSpeed = scrollSpeed;
469 }
470
471 void BitmapText::setText(const std::string &text)
472 {
473 this->text = text;
474 }
475
476 std::string BitmapText::getText()
477 {
478 return text;
479 }
480
481 void BitmapText::onRender()
482 {
483 CTextDrawer::GetSingleton().SetColor(color.x, color.y, color.z, alpha.getValue());
484 dsq->print(position.x, 600 - (position.y + 16*2), text);
485 }
486 */
487