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