1
/* ScummVM - Graphic Adventure Engine
3
* ScummVM is the legal property of its developers, whose names
4
* are too numerous to list here. Please refer to the COPYRIGHT
5
* file distributed with this source distribution.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 2
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26
#include "common/debug.h"
28
#include "toon/font.h"
32
FontRenderer::FontRenderer(ToonEngine *vm) : _vm(vm) {
33
_currentFontColor[0] = 0;
34
_currentFontColor[1] = 0xc8;
35
_currentFontColor[2] = 0xcb;
36
_currentFontColor[3] = 0xce;
39
FontRenderer::~FontRenderer() {
42
// mapping extended characters required for foreign versions to font (animation)
43
static const byte map_textToFont[0x80] = {
44
'?', '?', '?', '?', 0x03, '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', // 0x8x
45
'?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', // 0x9x
46
'?', 0x09, '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', // 0xAx
47
'?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', 0x0a, // 0xBx
48
'?', '?', '?', '?', 0x1d, '?', '?', 0x02, '?', '?', '?', '?', '?', '?', '?', '?', // 0xCx
49
'?', 0x0b, '?', '?', '?', '?', 0x1e, '?', '?', '?', '?', 0x20, 0x1f, '?', '?', 0x19, // 0xDx
50
0x0d, 0x04, 0x0e, '?', 0x1a, '?', '?', 0x18, 0x10, 0x0f, 0x12, 0x11, 0x09, 0x05, 0x14, 0x13, // 0xEx
51
0x23, 0x08, 0x23, 0x06, 0x15, 0x23, 0x1b, 0x23, 0x23, 0x16, 0x07, 0x17, 0x1c, 0x23, 0x23, 0x23 // 0xFx
54
byte FontRenderer::textToFont(byte c) {
55
// No need to remap simple characters.
59
// The Spanish version shows grave accent over the 'e' when it should
60
// be acute. This happens both in the original interpreter and when
61
// using the common map which works for other languages, so we add a
62
// special case for it.
63
if (_vm->_language == Common::ES_ESP && c == 0xe9)
66
// Use the common map to convert the extended characters.
67
return map_textToFont[c - 0x80];
70
void FontRenderer::renderText(int32 x, int32 y, Common::String origText, int32 mode) {
71
debugC(5, kDebugFont, "renderText(%d, %d, %s, %d)", x, y, origText.c_str(), mode);
74
computeSize(origText, &xx, &yy);
78
} else if (mode & 4) {
86
_vm->addDirtyRect(x, y, x + xx + 2, y + yy);
92
const byte *text = (const byte *)origText.c_str();
100
curChar = textToFont(curChar);
101
_currentFont->drawFontFrame(_vm->getMainSurface(), curChar, curX, curY, _currentFontColor);
102
curX = curX + _currentFont->getFrameWidth(curChar) - 1;
103
height = MAX(height, _currentFont->getFrameHeight(curChar));
109
void FontRenderer::computeSize(Common::String origText, int32 *retX, int32 *retY) {
110
debugC(4, kDebugFont, "computeSize(%s, retX, retY)", origText.c_str());
113
int32 lineHeight = 0;
114
int32 totalHeight = 0;
115
int32 totalWidth = 0;
117
const byte *text = (const byte *)origText.c_str();
119
byte curChar = *text;
123
} else if (curChar == 13) {
124
totalWidth = MAX(totalWidth, lineWidth);
125
totalHeight += lineHeight;
129
curChar = textToFont(curChar);
130
int32 charWidth = _currentFont->getFrameWidth(curChar) - 1;
131
int32 charHeight = _currentFont->getFrameHeight(curChar);
132
lineWidth += charWidth;
133
lineHeight = MAX(lineHeight, charHeight);
138
totalHeight += lineHeight;
139
totalWidth = MAX(totalWidth, lineWidth);
145
void FontRenderer::setFont(Animation *font) {
146
debugC(5, kDebugFont, "setFont(font)");
151
void FontRenderer::setFontColorByCharacter(int32 characterId) {
152
debugC(5, kDebugFont, "setFontColorByCharacter(%d)", characterId);
154
// unfortunately this table was hardcoded in the original executable
155
static const byte colorsByCharacters[] = {
156
0xe0, 0xdc, 0xc8, 0xd6, 0xc1, 0xc8, 0xe9, 0xde, 0xc8, 0xeb, 0xe8, 0xc8,
157
0xd1, 0xcf, 0xc8, 0xdb, 0xd5, 0xc8, 0xfb, 0xfa, 0xc8, 0xd9, 0xd7, 0xc8,
158
0xe8, 0xe4, 0xc8, 0xe9, 0xfa, 0xc8, 0xeb, 0xe4, 0xc8, 0xeb, 0xe4, 0xc8,
159
0xd2, 0xea, 0xc8, 0xd3, 0xd0, 0xc8, 0xe1, 0xdd, 0xc8, 0xd9, 0xd7, 0xc8,
160
0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8,
161
0xd2, 0xcf, 0xc8, 0xd1, 0xcf, 0xc8, 0xd9, 0xd7, 0xc8, 0xe3, 0xdd, 0xc8,
162
0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8,
163
0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8,
164
0xd9, 0xd7, 0xc8, 0xe6, 0xe4, 0xc8, 0xd9, 0xd7, 0xc8, 0xcd, 0xca, 0xc8,
165
0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xeb, 0xe8, 0xc8, 0xdb, 0xd5, 0xc8,
166
0xe0, 0xdc, 0xc8, 0xd6, 0xc1, 0xc8, 0xd3, 0xd0, 0xc8, 0xd1, 0xcf, 0xc8,
167
0xe6, 0xe4, 0xc8, 0xd1, 0xcf, 0xc8, 0xd2, 0xcf, 0xc8, 0xcc, 0xcb, 0xc8,
168
0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8,
169
0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8,
170
0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8, 0xd9, 0xd7, 0xc8
173
setFontColor(colorsByCharacters[characterId * 3 + 2], colorsByCharacters[characterId * 3 + 1], colorsByCharacters[characterId * 3 + 0]);
176
void FontRenderer::setFontColor(int32 fontColor1, int32 fontColor2, int32 fontColor3) {
177
debugC(5, kDebugFont, "setFontColor(%d, %d, %d)", fontColor1, fontColor2, fontColor3);
179
_currentFontColor[0] = 0;
180
_currentFontColor[1] = fontColor1;
181
_currentFontColor[2] = fontColor2;
182
_currentFontColor[3] = fontColor3;
185
void FontRenderer::renderMultiLineText(int32 x, int32 y, Common::String origText, int32 mode) {
186
debugC(5, kDebugFont, "renderMultiLineText(%d, %d, %s, %d)", x, y, origText.c_str(), mode);
188
// divide the text in several lines
189
// based on number of characters or size of lines.
191
strncpy((char *)text, origText.c_str(), 1023);
205
byte *lastSpace = it;
206
int32 lastSpaceX = 0;
207
int32 curLetterNr = 0;
210
while (*it && curLetterNr < 50 && curWidth < 580) {
214
lastSpaceX = curWidth;
216
curChar = textToFont(curChar);
218
int width = _currentFont->getFrameWidth(curChar);
219
curWidth += MAX<int32>(width - 2, 0);
227
lines[numLines] = lastLine;
230
lineSize[numLines] = curWidth;
232
lineSize[numLines] = lastSpaceX;
234
if (lineSize[numLines] > maxWidth)
235
maxWidth = lineSize[numLines];
237
lastLine = lastSpace + 1;
250
if (curWidth > maxWidth) {
255
// get font height (assumed to be constant)
256
int32 height = _currentFont->getHeight();
257
int textSize = (height - 2) * numLines;
261
if (y + textSize > 370)
264
x -= _vm->state()->_currentScrollValue;
267
if (x - 30 - maxWidth / 2 < 0)
268
x = maxWidth / 2 + 30;
270
if (x + 30 + (maxWidth / 2) > TOON_SCREEN_WIDTH)
271
x = TOON_SCREEN_WIDTH - (maxWidth / 2) - 30;
273
// we have good coordinates now, we can render the multi line
277
for (int32 i = 0; i < numLines; i++) {
278
const byte *line = lines[i];
279
curX = x - lineSize[i] / 2;
280
_vm->addDirtyRect(curX + _vm->state()->_currentScrollValue, curY, curX + lineSize[i] + _vm->state()->_currentScrollValue + 2, curY + height);
283
byte curChar = textToFont(*line);
284
if (curChar != 32) _currentFont->drawFontFrame(_vm->getMainSurface(), curChar, curX + _vm->state()->_currentScrollValue, curY, _currentFontColor);
285
curX = curX + MAX<int32>(_currentFont->getFrameWidth(curChar) - 2, 0);
286
//height = MAX(height, _currentFont->getFrameHeight(curChar));
293
} // End of namespace Toon