aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/base/font
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2012-09-04 22:17:23 +0200
committerWillem Jan Palenstijn2012-09-04 22:17:23 +0200
commitb4090ead4d4334e08725323ff72fd355c93b63d5 (patch)
tree4eb58e5698b1cfd1a89d2b038f929071264ffeb9 /engines/wintermute/base/font
parentdf80820184c90a87511f0cabdca4addb9fa13a66 (diff)
downloadscummvm-rg350-b4090ead4d4334e08725323ff72fd355c93b63d5.tar.gz
scummvm-rg350-b4090ead4d4334e08725323ff72fd355c93b63d5.tar.bz2
scummvm-rg350-b4090ead4d4334e08725323ff72fd355c93b63d5.zip
WINTERMUTE: Convert CRLF to LF
Diffstat (limited to 'engines/wintermute/base/font')
-rw-r--r--engines/wintermute/base/font/base_font.cpp280
-rw-r--r--engines/wintermute/base/font/base_font.h122
-rw-r--r--engines/wintermute/base/font/base_font_bitmap.cpp1178
-rw-r--r--engines/wintermute/base/font/base_font_bitmap.h142
-rw-r--r--engines/wintermute/base/font/base_font_storage.cpp284
-rw-r--r--engines/wintermute/base/font/base_font_storage.h110
-rw-r--r--engines/wintermute/base/font/base_font_truetype.cpp1210
-rw-r--r--engines/wintermute/base/font/base_font_truetype.h304
8 files changed, 1815 insertions, 1815 deletions
diff --git a/engines/wintermute/base/font/base_font.cpp b/engines/wintermute/base/font/base_font.cpp
index cb70c4add8..87dd3da5a3 100644
--- a/engines/wintermute/base/font/base_font.cpp
+++ b/engines/wintermute/base/font/base_font.cpp
@@ -1,140 +1,140 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This file is based on WME Lite.
- * http://dead-code.org/redir.php?target=wmelite
- * Copyright (c) 2011 Jan Nedoma
- */
-
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/base/font/base_font_bitmap.h"
-#include "engines/wintermute/base/font/base_font_truetype.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_file_manager.h"
-
-namespace Wintermute {
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-IMPLEMENT_PERSISTENT(BaseFont, false)
-
-//////////////////////////////////////////////////////////////////////
-BaseFont::BaseFont(BaseGame *inGame) : BaseObject(inGame) {
-
-}
-
-
-//////////////////////////////////////////////////////////////////////
-BaseFont::~BaseFont() {
-}
-
-
-//////////////////////////////////////////////////////////////////////
-void BaseFont::drawText(const byte *text, int x, int y, int width, TTextAlign align, int maxHeight, int maxLength) {
-}
-
-
-//////////////////////////////////////////////////////////////////////
-int BaseFont::getTextHeight(byte *text, int width) {
- return 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////
-int BaseFont::getTextWidth(byte *text, int maxLength) {
- return 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int BaseFont::getLetterHeight() {
- return 0;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFont::persist(BasePersistenceManager *persistMgr) {
-
- BaseObject::persist(persistMgr);
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-BaseFont *BaseFont::createFromFile(BaseGame *gameRef, const Common::String &filename) {
- if (isTrueType(gameRef, filename)) {
- BaseFontTT *font = new BaseFontTT(gameRef);
- if (font) {
- if (DID_FAIL(font->loadFile(filename))) {
- delete font;
- return NULL;
- }
- }
- return font;
- } else {
- BaseFontBitmap *font = new BaseFontBitmap(gameRef);
- if (font) {
- if (DID_FAIL(font->loadFile(filename))) {
- delete font;
- return NULL;
- }
- }
- return font;
- }
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(FONT)
-TOKEN_DEF(TTFONT)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////////
-bool BaseFont::isTrueType(BaseGame *gameRef, const Common::String &filename) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(FONT)
- TOKEN_TABLE(TTFONT)
- TOKEN_TABLE_END
-
-
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- return false;
- }
-
- byte *workBuffer = buffer;
-
- char *params;
- BaseParser parser;
-
- bool ret = false;
- if (parser.getCommand((char **)&workBuffer, commands, (char **)&params) == TOKEN_TTFONT) {
- ret = true;
- }
-
- delete[] buffer;
- return ret;
-}
-
-} // end of namespace Wintermute
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/font/base_font_bitmap.h"
+#include "engines/wintermute/base/font/base_font_truetype.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_file_manager.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(BaseFont, false)
+
+//////////////////////////////////////////////////////////////////////
+BaseFont::BaseFont(BaseGame *inGame) : BaseObject(inGame) {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////
+BaseFont::~BaseFont() {
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void BaseFont::drawText(const byte *text, int x, int y, int width, TTextAlign align, int maxHeight, int maxLength) {
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int BaseFont::getTextHeight(byte *text, int width) {
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int BaseFont::getTextWidth(byte *text, int maxLength) {
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int BaseFont::getLetterHeight() {
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFont::persist(BasePersistenceManager *persistMgr) {
+
+ BaseObject::persist(persistMgr);
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+BaseFont *BaseFont::createFromFile(BaseGame *gameRef, const Common::String &filename) {
+ if (isTrueType(gameRef, filename)) {
+ BaseFontTT *font = new BaseFontTT(gameRef);
+ if (font) {
+ if (DID_FAIL(font->loadFile(filename))) {
+ delete font;
+ return NULL;
+ }
+ }
+ return font;
+ } else {
+ BaseFontBitmap *font = new BaseFontBitmap(gameRef);
+ if (font) {
+ if (DID_FAIL(font->loadFile(filename))) {
+ delete font;
+ return NULL;
+ }
+ }
+ return font;
+ }
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(FONT)
+TOKEN_DEF(TTFONT)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool BaseFont::isTrueType(BaseGame *gameRef, const Common::String &filename) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(FONT)
+ TOKEN_TABLE(TTFONT)
+ TOKEN_TABLE_END
+
+
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ return false;
+ }
+
+ byte *workBuffer = buffer;
+
+ char *params;
+ BaseParser parser;
+
+ bool ret = false;
+ if (parser.getCommand((char **)&workBuffer, commands, (char **)&params) == TOKEN_TTFONT) {
+ ret = true;
+ }
+
+ delete[] buffer;
+ return ret;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/font/base_font.h b/engines/wintermute/base/font/base_font.h
index acd424ac06..0abe62ab98 100644
--- a/engines/wintermute/base/font/base_font.h
+++ b/engines/wintermute/base/font/base_font.h
@@ -1,61 +1,61 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This file is based on WME Lite.
- * http://dead-code.org/redir.php?target=wmelite
- * Copyright (c) 2011 Jan Nedoma
- */
-
-#ifndef WINTERMUTE_BASE_FONT_H
-#define WINTERMUTE_BASE_FONT_H
-
-#include "engines/wintermute/base/base_object.h"
-
-#define NUM_CHARACTERS 256
-
-namespace Wintermute {
-
-class BaseFont: public BaseObject {
-public:
- DECLARE_PERSISTENT(BaseFont, BaseObject)
- virtual int getTextWidth(byte *text, int maxLength = -1);
- virtual int getTextHeight(byte *text, int width);
- virtual void drawText(const byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int maxLength = -1);
- virtual int getLetterHeight();
-
- virtual void initLoop() {}
- virtual void afterLoad() {}
- BaseFont(BaseGame *inGame);
- virtual ~BaseFont();
-
- static BaseFont *createFromFile(BaseGame *game, const Common::String &filename);
-
-private:
- //bool loadBuffer(byte * Buffer);
- //bool loadFile(const char* Filename);
- static bool isTrueType(BaseGame *game, const Common::String &filename);
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_BASE_FONT_H
+#define WINTERMUTE_BASE_FONT_H
+
+#include "engines/wintermute/base/base_object.h"
+
+#define NUM_CHARACTERS 256
+
+namespace Wintermute {
+
+class BaseFont: public BaseObject {
+public:
+ DECLARE_PERSISTENT(BaseFont, BaseObject)
+ virtual int getTextWidth(byte *text, int maxLength = -1);
+ virtual int getTextHeight(byte *text, int width);
+ virtual void drawText(const byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int maxLength = -1);
+ virtual int getLetterHeight();
+
+ virtual void initLoop() {}
+ virtual void afterLoad() {}
+ BaseFont(BaseGame *inGame);
+ virtual ~BaseFont();
+
+ static BaseFont *createFromFile(BaseGame *game, const Common::String &filename);
+
+private:
+ //bool loadBuffer(byte * Buffer);
+ //bool loadFile(const char* Filename);
+ static bool isTrueType(BaseGame *game, const Common::String &filename);
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/font/base_font_bitmap.cpp b/engines/wintermute/base/font/base_font_bitmap.cpp
index 062f4801cf..fced08c7e2 100644
--- a/engines/wintermute/base/font/base_font_bitmap.cpp
+++ b/engines/wintermute/base/font/base_font_bitmap.cpp
@@ -1,589 +1,589 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This file is based on WME Lite.
- * http://dead-code.org/redir.php?target=wmelite
- * Copyright (c) 2011 Jan Nedoma
- */
-
-#include "engines/wintermute/base/font/base_font_bitmap.h"
-#include "engines/wintermute/utils/string_util.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_frame.h"
-#include "engines/wintermute/base/gfx/base_surface.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_sub_frame.h"
-#include "engines/wintermute/base/base_frame.h"
-#include "engines/wintermute/base/base_sprite.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/platform_osystem.h"
-
-namespace Wintermute {
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-IMPLEMENT_PERSISTENT(BaseFontBitmap, false)
-
-//////////////////////////////////////////////////////////////////////
-BaseFontBitmap::BaseFontBitmap(BaseGame *inGame) : BaseFont(inGame) {
- _subframe = NULL;
- _sprite = NULL;
- _widthsFrame = 0;
- memset(_widths, 0, NUM_CHARACTERS);
- _tileWidth = _tileHeight = _numColumns = 0;
- _fontextFix = false;
- _freezable = false;
- _wholeCell = false;
-}
-
-
-//////////////////////////////////////////////////////////////////////
-BaseFontBitmap::~BaseFontBitmap() {
- delete _subframe;
- delete _sprite;
- _subframe = NULL;
- _sprite = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////
-void BaseFontBitmap::drawText(const byte *text, int x, int y, int width, TTextAlign align, int maxHeight, int maxLength) {
- textHeightDraw(text, x, y, width, align, true, maxHeight, maxLength);
-}
-
-
-//////////////////////////////////////////////////////////////////////
-int BaseFontBitmap::getTextHeight(byte *text, int width) {
- return textHeightDraw(text, 0, 0, width, TAL_LEFT, false);
-}
-
-
-//////////////////////////////////////////////////////////////////////
-int BaseFontBitmap::getTextWidth(byte *text, int maxLength) {
- AnsiString str;
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- WideString wstr = StringUtil::utf8ToWide(Utf8String((char *)text));
- str = StringUtil::wideToAnsi(wstr);
- } else {
- str = AnsiString((char *)text);
- }
-
- if (maxLength >= 0 && str.size() > (uint32)maxLength) {
- str = Common::String(str.c_str(), (uint32)maxLength);
- }
- //str.substr(0, maxLength); // TODO: Remove
-
- int textWidth = 0;
- for (int i = 0; (uint32)i < str.size(); i++) {
- textWidth += getCharWidth((byte)str[i]);
- }
-
- return textWidth;
-}
-
-
-//////////////////////////////////////////////////////////////////////
-int BaseFontBitmap::textHeightDraw(const byte *text, int x, int y, int width, TTextAlign align, bool draw, int maxHeight, int maxLength) {
- if (maxLength == 0) {
- return 0;
- }
-
- if (text == NULL || text[0] == '\0') {
- return _tileHeight;
- }
-
- AnsiString str;
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- WideString wstr = StringUtil::utf8ToWide(Utf8String((const char *)text));
- str = StringUtil::wideToAnsi(wstr);
- } else {
- str = AnsiString((const char *)text);
- }
- if (str.empty()) {
- return 0;
- }
-
- int lineLength = 0;
- int realLength = 0;
- int numLines = 0;
-
- int i;
-
- int index = -1;
- int start = 0;
- int end = 0;
- int last_end = 0;
-
- bool done = false;
- bool newLine = false;
- bool longLine = false;
-
- if (draw) {
- _gameRef->_renderer->startSpriteBatch();
- }
-
- while (!done) {
- if (maxHeight > 0 && (numLines + 1)*_tileHeight > maxHeight) {
- if (draw) {
- _gameRef->_renderer->endSpriteBatch();
- }
- return numLines * _tileHeight;
- }
-
- index++;
-
- if (str[index] == ' ' && (maxHeight < 0 || maxHeight / _tileHeight > 1)) {
- end = index - 1;
- realLength = lineLength;
- }
-
- if (str[index] == '\n') {
- end = index - 1;
- realLength = lineLength;
- newLine = true;
- }
-
- if (lineLength + getCharWidth(str[index]) > width && last_end == end) {
- end = index - 1;
- realLength = lineLength;
- newLine = true;
- longLine = true;
- }
-
- if ((int)str.size() == (index + 1) || (maxLength >= 0 && index == maxLength - 1)) {
- done = true;
- if (!newLine) {
- end = index;
- lineLength += getCharWidth(str[index]);
- realLength = lineLength;
- }
- } else {
- lineLength += getCharWidth(str[index]);
- }
-
- if ((lineLength > width) || done || newLine) {
- if (end < 0) {
- done = true;
- }
- int startX;
- switch (align) {
- case TAL_CENTER:
- startX = x + (width - realLength) / 2;
- break;
- case TAL_RIGHT:
- startX = x + width - realLength;
- break;
- case TAL_LEFT:
- startX = x;
- break;
- default:
- error("BaseFontBitmap::TextHeightDraw - Unhandled enum");
- break;
- }
- for (i = start; i < end + 1; i++) {
- if (draw) {
- drawChar(str[i], startX, y);
- }
- startX += getCharWidth(str[i]);
- }
- y += _tileHeight;
- last_end = end;
- if (longLine) {
- end--;
- }
- start = end + 2;
- index = end + 1;
- lineLength = 0;
- newLine = false;
- longLine = false;
- numLines++;
- }
- }
-
- if (draw) {
- _gameRef->_renderer->endSpriteBatch();
- }
-
- return numLines * _tileHeight;
-}
-
-
-//////////////////////////////////////////////////////////////////////
-void BaseFontBitmap::drawChar(byte c, int x, int y) {
- if (_fontextFix) {
- c--;
- }
-
- int row, col;
-
- row = c / _numColumns;
- col = c % _numColumns;
-
- Rect32 rect;
- /* l t r b */
- int tileWidth;
- if (_wholeCell) {
- tileWidth = _tileWidth;
- } else {
- tileWidth = _widths[c];
- }
-
- BasePlatform::setRect(&rect, col * _tileWidth, row * _tileHeight, col * _tileWidth + tileWidth, (row + 1)*_tileHeight);
- bool handled = false;
- if (_sprite) {
- _sprite->getCurrentFrame();
- if (_sprite->_currentFrame >= 0 && _sprite->_currentFrame < (int32)_sprite->_frames.size() && _sprite->_frames[_sprite->_currentFrame]) {
- if (_sprite->_frames[_sprite->_currentFrame]->_subframes.size() > 0) {
- _sprite->_frames[_sprite->_currentFrame]->_subframes[0]->_surface->displayTrans(x, y, rect);
- }
- handled = true;
- }
- }
- if (!handled && _subframe) {
- _subframe->_surface->displayTrans(x, y, rect);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////
-bool BaseFontBitmap::loadFile(const Common::String &filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "BaseFontBitmap::LoadFile failed for file '%s'", filename.c_str());
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename.c_str());
-
- if (DID_FAIL(ret = loadBuffer(buffer))) {
- _gameRef->LOG(0, "Error parsing FONT file '%s'", filename.c_str());
- }
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(FONTEXT_FIX)
-TOKEN_DEF(FONT)
-TOKEN_DEF(IMAGE)
-TOKEN_DEF(TRANSPARENT)
-TOKEN_DEF(COLUMNS)
-TOKEN_DEF(TILE_WIDTH)
-TOKEN_DEF(TILE_HEIGHT)
-TOKEN_DEF(DEFAULT_WIDTH)
-TOKEN_DEF(WIDTHS)
-TOKEN_DEF(AUTO_WIDTH)
-TOKEN_DEF(SPACE_WIDTH)
-TOKEN_DEF(EXPAND_WIDTH)
-TOKEN_DEF(EDITOR_PROPERTY)
-TOKEN_DEF(SPRITE)
-TOKEN_DEF(WIDTHS_FRAME)
-TOKEN_DEF(PAINT_WHOLE_CELL)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////
-bool BaseFontBitmap::loadBuffer(byte *buffer) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(FONTEXT_FIX)
- TOKEN_TABLE(FONT)
- TOKEN_TABLE(IMAGE)
- TOKEN_TABLE(TRANSPARENT)
- TOKEN_TABLE(COLUMNS)
- TOKEN_TABLE(TILE_WIDTH)
- TOKEN_TABLE(TILE_HEIGHT)
- TOKEN_TABLE(DEFAULT_WIDTH)
- TOKEN_TABLE(WIDTHS)
- TOKEN_TABLE(AUTO_WIDTH)
- TOKEN_TABLE(SPACE_WIDTH)
- TOKEN_TABLE(EXPAND_WIDTH)
- TOKEN_TABLE(EDITOR_PROPERTY)
- TOKEN_TABLE(SPRITE)
- TOKEN_TABLE(WIDTHS_FRAME)
- TOKEN_TABLE(PAINT_WHOLE_CELL)
- TOKEN_TABLE_END
-
- char *params;
- int cmd;
- BaseParser parser;
-
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_FONT) {
- _gameRef->LOG(0, "'FONT' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = (byte *)params;
-
- int widths[300];
- int num = 0, defaultWidth = 8;
- int lastWidth = 0;
- int i;
- int r = 255, g = 255, b = 255;
- bool custoTrans = false;
- char *surfaceFile = NULL;
- char *spriteFile = NULL;
-
- bool autoWidth = false;
- int spaceWidth = 0;
- int expandWidth = 0;
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
-
- switch (cmd) {
- case TOKEN_IMAGE:
- surfaceFile = (char *)params;
- break;
-
- case TOKEN_SPRITE:
- spriteFile = (char *)params;
- break;
-
- case TOKEN_TRANSPARENT:
- parser.scanStr(params, "%d,%d,%d", &r, &g, &b);
- custoTrans = true;
- break;
-
- case TOKEN_WIDTHS:
- parser.scanStr(params, "%D", widths, &num);
- for (i = 0; lastWidth < NUM_CHARACTERS && num > 0; lastWidth++, num--, i++) {
- _widths[lastWidth] = (byte)widths[i];
- }
- break;
-
- case TOKEN_DEFAULT_WIDTH:
- parser.scanStr(params, "%d", &defaultWidth);
- break;
-
- case TOKEN_WIDTHS_FRAME:
- parser.scanStr(params, "%d", &_widthsFrame);
- break;
-
- case TOKEN_COLUMNS:
- parser.scanStr(params, "%d", &_numColumns);
- break;
-
- case TOKEN_TILE_WIDTH:
- parser.scanStr(params, "%d", &_tileWidth);
- break;
-
- case TOKEN_TILE_HEIGHT:
- parser.scanStr(params, "%d", &_tileHeight);
- break;
-
- case TOKEN_AUTO_WIDTH:
- parser.scanStr(params, "%b", &autoWidth);
- break;
-
- case TOKEN_FONTEXT_FIX:
- parser.scanStr(params, "%b", &_fontextFix);
- break;
-
- case TOKEN_PAINT_WHOLE_CELL:
- parser.scanStr(params, "%b", &_wholeCell);
- break;
-
- case TOKEN_SPACE_WIDTH:
- parser.scanStr(params, "%d", &spaceWidth);
- break;
-
- case TOKEN_EXPAND_WIDTH:
- parser.scanStr(params, "%d", &expandWidth);
- break;
-
- case TOKEN_EDITOR_PROPERTY:
- parseEditorProperty((byte *)params, false);
- break;
- }
-
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in FONT definition");
- return STATUS_FAILED;
- }
-
- if (spriteFile != NULL) {
- delete _sprite;
- _sprite = new BaseSprite(_gameRef, this);
- if (!_sprite || DID_FAIL(_sprite->loadFile(spriteFile))) {
- delete _sprite;
- _sprite = NULL;
- }
- }
-
- if (surfaceFile != NULL && !_sprite) {
- _subframe = new BaseSubFrame(_gameRef);
- if (custoTrans) {
- _subframe->setSurface(surfaceFile, false, r, g, b);
- } else {
- _subframe->setSurface(surfaceFile);
- }
- }
-
-
- if (((_subframe == NULL || _subframe->_surface == NULL) && _sprite == NULL) || _numColumns == 0 || _tileWidth == 0 || _tileHeight == 0) {
- _gameRef->LOG(0, "Incomplete font definition");
- return STATUS_FAILED;
- }
-
- if (autoWidth) {
- // calculate characters width
- getWidths();
-
- // do we need to modify widths?
- if (expandWidth != 0) {
- for (i = 0; i < NUM_CHARACTERS; i++) {
- int newWidth = (int)_widths[i] + expandWidth;
- if (newWidth < 0) {
- newWidth = 0;
- }
-
- _widths[i] = (byte)newWidth;
- }
- }
-
- // handle space character
- uint32 spaceChar = ' ';
- if (_fontextFix) {
- spaceChar--;
- }
-
- if (spaceWidth != 0) {
- _widths[spaceChar] = spaceWidth;
- } else {
- if (_widths[spaceChar] == expandWidth || _widths[spaceChar] == 0) {
- _widths[spaceChar] = (_widths['m'] + _widths['i']) / 2;
- }
- }
- } else {
- for (i = lastWidth; i < NUM_CHARACTERS; i++) {
- _widths[i] = defaultWidth;
- }
- }
-
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontBitmap::persist(BasePersistenceManager *persistMgr) {
-
- BaseFont::persist(persistMgr);
- persistMgr->transfer(TMEMBER(_numColumns));
-
- persistMgr->transfer(TMEMBER(_subframe));
- persistMgr->transfer(TMEMBER(_tileHeight));
- persistMgr->transfer(TMEMBER(_tileWidth));
- persistMgr->transfer(TMEMBER(_sprite));
- persistMgr->transfer(TMEMBER(_widthsFrame));
-
- if (persistMgr->getIsSaving()) {
- persistMgr->putBytes(_widths, sizeof(_widths));
- } else {
- persistMgr->getBytes(_widths, sizeof(_widths));
- }
-
-
- persistMgr->transfer(TMEMBER(_fontextFix));
- persistMgr->transfer(TMEMBER(_wholeCell));
-
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int BaseFontBitmap::getCharWidth(byte index) {
- if (_fontextFix) {
- index--;
- }
- return _widths[index];
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontBitmap::getWidths() {
- BaseSurface *surf = NULL;
-
- if (_sprite) {
- if (_widthsFrame >= 0 && _widthsFrame < (int32)_sprite->_frames.size()) {
- if (_sprite->_frames[_widthsFrame] && (int32)_sprite->_frames[_widthsFrame]->_subframes.size() > 0) {
- surf = _sprite->_frames[_widthsFrame]->_subframes[0]->_surface;
- }
- }
- }
- if (surf == NULL && _subframe) {
- surf = _subframe->_surface;
- }
- if (!surf || DID_FAIL(surf->startPixelOp())) {
- return STATUS_FAILED;
- }
-
-
- for (int i = 0; i < NUM_CHARACTERS; i++) {
- int xxx = (i % _numColumns) * _tileWidth;
- int yyy = (i / _numColumns) * _tileHeight;
-
-
- int minCol = -1;
- for (int row = 0; row < _tileHeight; row++) {
- for (int col = _tileWidth - 1; col >= minCol + 1; col--) {
- if (xxx + col < 0 || xxx + col >= surf->getWidth() || yyy + row < 0 || yyy + row >= surf->getHeight()) {
- continue;
- }
- if (!surf->isTransparentAtLite(xxx + col, yyy + row)) {
- //min_col = col;
- minCol = MAX(col, minCol);
- break;
- }
- }
- if (minCol == _tileWidth - 1) {
- break;
- }
- }
-
- _widths[i] = minCol + 1;
- }
- surf->endPixelOp();
- /*
- _gameRef->LOG(0, "----- %s ------", _filename);
- for(int j=0; j<16; j++)
- {
- _gameRef->LOG(0, "%02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d", _widths[j*16+0], _widths[j*16+1], _widths[j*16+2], _widths[j*16+3], _widths[j*16+4], _widths[j*16+5], _widths[j*16+6], _widths[j*16+7], _widths[j*16+8], _widths[j*16+9], _widths[j*16+10], _widths[j*16+11], _widths[j*16+12], _widths[j*16+13], _widths[j*16+14], _widths[j*16+15]);
- }
- */
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-int BaseFontBitmap::getLetterHeight() {
- return _tileHeight;
-}
-
-} // end of namespace Wintermute
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#include "engines/wintermute/base/font/base_font_bitmap.h"
+#include "engines/wintermute/utils/string_util.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_frame.h"
+#include "engines/wintermute/base/gfx/base_surface.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_sub_frame.h"
+#include "engines/wintermute/base/base_frame.h"
+#include "engines/wintermute/base/base_sprite.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/platform_osystem.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(BaseFontBitmap, false)
+
+//////////////////////////////////////////////////////////////////////
+BaseFontBitmap::BaseFontBitmap(BaseGame *inGame) : BaseFont(inGame) {
+ _subframe = NULL;
+ _sprite = NULL;
+ _widthsFrame = 0;
+ memset(_widths, 0, NUM_CHARACTERS);
+ _tileWidth = _tileHeight = _numColumns = 0;
+ _fontextFix = false;
+ _freezable = false;
+ _wholeCell = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+BaseFontBitmap::~BaseFontBitmap() {
+ delete _subframe;
+ delete _sprite;
+ _subframe = NULL;
+ _sprite = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void BaseFontBitmap::drawText(const byte *text, int x, int y, int width, TTextAlign align, int maxHeight, int maxLength) {
+ textHeightDraw(text, x, y, width, align, true, maxHeight, maxLength);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int BaseFontBitmap::getTextHeight(byte *text, int width) {
+ return textHeightDraw(text, 0, 0, width, TAL_LEFT, false);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int BaseFontBitmap::getTextWidth(byte *text, int maxLength) {
+ AnsiString str;
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ WideString wstr = StringUtil::utf8ToWide(Utf8String((char *)text));
+ str = StringUtil::wideToAnsi(wstr);
+ } else {
+ str = AnsiString((char *)text);
+ }
+
+ if (maxLength >= 0 && str.size() > (uint32)maxLength) {
+ str = Common::String(str.c_str(), (uint32)maxLength);
+ }
+ //str.substr(0, maxLength); // TODO: Remove
+
+ int textWidth = 0;
+ for (int i = 0; (uint32)i < str.size(); i++) {
+ textWidth += getCharWidth((byte)str[i]);
+ }
+
+ return textWidth;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int BaseFontBitmap::textHeightDraw(const byte *text, int x, int y, int width, TTextAlign align, bool draw, int maxHeight, int maxLength) {
+ if (maxLength == 0) {
+ return 0;
+ }
+
+ if (text == NULL || text[0] == '\0') {
+ return _tileHeight;
+ }
+
+ AnsiString str;
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ WideString wstr = StringUtil::utf8ToWide(Utf8String((const char *)text));
+ str = StringUtil::wideToAnsi(wstr);
+ } else {
+ str = AnsiString((const char *)text);
+ }
+ if (str.empty()) {
+ return 0;
+ }
+
+ int lineLength = 0;
+ int realLength = 0;
+ int numLines = 0;
+
+ int i;
+
+ int index = -1;
+ int start = 0;
+ int end = 0;
+ int last_end = 0;
+
+ bool done = false;
+ bool newLine = false;
+ bool longLine = false;
+
+ if (draw) {
+ _gameRef->_renderer->startSpriteBatch();
+ }
+
+ while (!done) {
+ if (maxHeight > 0 && (numLines + 1)*_tileHeight > maxHeight) {
+ if (draw) {
+ _gameRef->_renderer->endSpriteBatch();
+ }
+ return numLines * _tileHeight;
+ }
+
+ index++;
+
+ if (str[index] == ' ' && (maxHeight < 0 || maxHeight / _tileHeight > 1)) {
+ end = index - 1;
+ realLength = lineLength;
+ }
+
+ if (str[index] == '\n') {
+ end = index - 1;
+ realLength = lineLength;
+ newLine = true;
+ }
+
+ if (lineLength + getCharWidth(str[index]) > width && last_end == end) {
+ end = index - 1;
+ realLength = lineLength;
+ newLine = true;
+ longLine = true;
+ }
+
+ if ((int)str.size() == (index + 1) || (maxLength >= 0 && index == maxLength - 1)) {
+ done = true;
+ if (!newLine) {
+ end = index;
+ lineLength += getCharWidth(str[index]);
+ realLength = lineLength;
+ }
+ } else {
+ lineLength += getCharWidth(str[index]);
+ }
+
+ if ((lineLength > width) || done || newLine) {
+ if (end < 0) {
+ done = true;
+ }
+ int startX;
+ switch (align) {
+ case TAL_CENTER:
+ startX = x + (width - realLength) / 2;
+ break;
+ case TAL_RIGHT:
+ startX = x + width - realLength;
+ break;
+ case TAL_LEFT:
+ startX = x;
+ break;
+ default:
+ error("BaseFontBitmap::TextHeightDraw - Unhandled enum");
+ break;
+ }
+ for (i = start; i < end + 1; i++) {
+ if (draw) {
+ drawChar(str[i], startX, y);
+ }
+ startX += getCharWidth(str[i]);
+ }
+ y += _tileHeight;
+ last_end = end;
+ if (longLine) {
+ end--;
+ }
+ start = end + 2;
+ index = end + 1;
+ lineLength = 0;
+ newLine = false;
+ longLine = false;
+ numLines++;
+ }
+ }
+
+ if (draw) {
+ _gameRef->_renderer->endSpriteBatch();
+ }
+
+ return numLines * _tileHeight;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void BaseFontBitmap::drawChar(byte c, int x, int y) {
+ if (_fontextFix) {
+ c--;
+ }
+
+ int row, col;
+
+ row = c / _numColumns;
+ col = c % _numColumns;
+
+ Rect32 rect;
+ /* l t r b */
+ int tileWidth;
+ if (_wholeCell) {
+ tileWidth = _tileWidth;
+ } else {
+ tileWidth = _widths[c];
+ }
+
+ BasePlatform::setRect(&rect, col * _tileWidth, row * _tileHeight, col * _tileWidth + tileWidth, (row + 1)*_tileHeight);
+ bool handled = false;
+ if (_sprite) {
+ _sprite->getCurrentFrame();
+ if (_sprite->_currentFrame >= 0 && _sprite->_currentFrame < (int32)_sprite->_frames.size() && _sprite->_frames[_sprite->_currentFrame]) {
+ if (_sprite->_frames[_sprite->_currentFrame]->_subframes.size() > 0) {
+ _sprite->_frames[_sprite->_currentFrame]->_subframes[0]->_surface->displayTrans(x, y, rect);
+ }
+ handled = true;
+ }
+ }
+ if (!handled && _subframe) {
+ _subframe->_surface->displayTrans(x, y, rect);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////
+bool BaseFontBitmap::loadFile(const Common::String &filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "BaseFontBitmap::LoadFile failed for file '%s'", filename.c_str());
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename.c_str());
+
+ if (DID_FAIL(ret = loadBuffer(buffer))) {
+ _gameRef->LOG(0, "Error parsing FONT file '%s'", filename.c_str());
+ }
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(FONTEXT_FIX)
+TOKEN_DEF(FONT)
+TOKEN_DEF(IMAGE)
+TOKEN_DEF(TRANSPARENT)
+TOKEN_DEF(COLUMNS)
+TOKEN_DEF(TILE_WIDTH)
+TOKEN_DEF(TILE_HEIGHT)
+TOKEN_DEF(DEFAULT_WIDTH)
+TOKEN_DEF(WIDTHS)
+TOKEN_DEF(AUTO_WIDTH)
+TOKEN_DEF(SPACE_WIDTH)
+TOKEN_DEF(EXPAND_WIDTH)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(SPRITE)
+TOKEN_DEF(WIDTHS_FRAME)
+TOKEN_DEF(PAINT_WHOLE_CELL)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////
+bool BaseFontBitmap::loadBuffer(byte *buffer) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(FONTEXT_FIX)
+ TOKEN_TABLE(FONT)
+ TOKEN_TABLE(IMAGE)
+ TOKEN_TABLE(TRANSPARENT)
+ TOKEN_TABLE(COLUMNS)
+ TOKEN_TABLE(TILE_WIDTH)
+ TOKEN_TABLE(TILE_HEIGHT)
+ TOKEN_TABLE(DEFAULT_WIDTH)
+ TOKEN_TABLE(WIDTHS)
+ TOKEN_TABLE(AUTO_WIDTH)
+ TOKEN_TABLE(SPACE_WIDTH)
+ TOKEN_TABLE(EXPAND_WIDTH)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(SPRITE)
+ TOKEN_TABLE(WIDTHS_FRAME)
+ TOKEN_TABLE(PAINT_WHOLE_CELL)
+ TOKEN_TABLE_END
+
+ char *params;
+ int cmd;
+ BaseParser parser;
+
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_FONT) {
+ _gameRef->LOG(0, "'FONT' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = (byte *)params;
+
+ int widths[300];
+ int num = 0, defaultWidth = 8;
+ int lastWidth = 0;
+ int i;
+ int r = 255, g = 255, b = 255;
+ bool custoTrans = false;
+ char *surfaceFile = NULL;
+ char *spriteFile = NULL;
+
+ bool autoWidth = false;
+ int spaceWidth = 0;
+ int expandWidth = 0;
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+
+ switch (cmd) {
+ case TOKEN_IMAGE:
+ surfaceFile = (char *)params;
+ break;
+
+ case TOKEN_SPRITE:
+ spriteFile = (char *)params;
+ break;
+
+ case TOKEN_TRANSPARENT:
+ parser.scanStr(params, "%d,%d,%d", &r, &g, &b);
+ custoTrans = true;
+ break;
+
+ case TOKEN_WIDTHS:
+ parser.scanStr(params, "%D", widths, &num);
+ for (i = 0; lastWidth < NUM_CHARACTERS && num > 0; lastWidth++, num--, i++) {
+ _widths[lastWidth] = (byte)widths[i];
+ }
+ break;
+
+ case TOKEN_DEFAULT_WIDTH:
+ parser.scanStr(params, "%d", &defaultWidth);
+ break;
+
+ case TOKEN_WIDTHS_FRAME:
+ parser.scanStr(params, "%d", &_widthsFrame);
+ break;
+
+ case TOKEN_COLUMNS:
+ parser.scanStr(params, "%d", &_numColumns);
+ break;
+
+ case TOKEN_TILE_WIDTH:
+ parser.scanStr(params, "%d", &_tileWidth);
+ break;
+
+ case TOKEN_TILE_HEIGHT:
+ parser.scanStr(params, "%d", &_tileHeight);
+ break;
+
+ case TOKEN_AUTO_WIDTH:
+ parser.scanStr(params, "%b", &autoWidth);
+ break;
+
+ case TOKEN_FONTEXT_FIX:
+ parser.scanStr(params, "%b", &_fontextFix);
+ break;
+
+ case TOKEN_PAINT_WHOLE_CELL:
+ parser.scanStr(params, "%b", &_wholeCell);
+ break;
+
+ case TOKEN_SPACE_WIDTH:
+ parser.scanStr(params, "%d", &spaceWidth);
+ break;
+
+ case TOKEN_EXPAND_WIDTH:
+ parser.scanStr(params, "%d", &expandWidth);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ parseEditorProperty((byte *)params, false);
+ break;
+ }
+
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in FONT definition");
+ return STATUS_FAILED;
+ }
+
+ if (spriteFile != NULL) {
+ delete _sprite;
+ _sprite = new BaseSprite(_gameRef, this);
+ if (!_sprite || DID_FAIL(_sprite->loadFile(spriteFile))) {
+ delete _sprite;
+ _sprite = NULL;
+ }
+ }
+
+ if (surfaceFile != NULL && !_sprite) {
+ _subframe = new BaseSubFrame(_gameRef);
+ if (custoTrans) {
+ _subframe->setSurface(surfaceFile, false, r, g, b);
+ } else {
+ _subframe->setSurface(surfaceFile);
+ }
+ }
+
+
+ if (((_subframe == NULL || _subframe->_surface == NULL) && _sprite == NULL) || _numColumns == 0 || _tileWidth == 0 || _tileHeight == 0) {
+ _gameRef->LOG(0, "Incomplete font definition");
+ return STATUS_FAILED;
+ }
+
+ if (autoWidth) {
+ // calculate characters width
+ getWidths();
+
+ // do we need to modify widths?
+ if (expandWidth != 0) {
+ for (i = 0; i < NUM_CHARACTERS; i++) {
+ int newWidth = (int)_widths[i] + expandWidth;
+ if (newWidth < 0) {
+ newWidth = 0;
+ }
+
+ _widths[i] = (byte)newWidth;
+ }
+ }
+
+ // handle space character
+ uint32 spaceChar = ' ';
+ if (_fontextFix) {
+ spaceChar--;
+ }
+
+ if (spaceWidth != 0) {
+ _widths[spaceChar] = spaceWidth;
+ } else {
+ if (_widths[spaceChar] == expandWidth || _widths[spaceChar] == 0) {
+ _widths[spaceChar] = (_widths['m'] + _widths['i']) / 2;
+ }
+ }
+ } else {
+ for (i = lastWidth; i < NUM_CHARACTERS; i++) {
+ _widths[i] = defaultWidth;
+ }
+ }
+
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontBitmap::persist(BasePersistenceManager *persistMgr) {
+
+ BaseFont::persist(persistMgr);
+ persistMgr->transfer(TMEMBER(_numColumns));
+
+ persistMgr->transfer(TMEMBER(_subframe));
+ persistMgr->transfer(TMEMBER(_tileHeight));
+ persistMgr->transfer(TMEMBER(_tileWidth));
+ persistMgr->transfer(TMEMBER(_sprite));
+ persistMgr->transfer(TMEMBER(_widthsFrame));
+
+ if (persistMgr->getIsSaving()) {
+ persistMgr->putBytes(_widths, sizeof(_widths));
+ } else {
+ persistMgr->getBytes(_widths, sizeof(_widths));
+ }
+
+
+ persistMgr->transfer(TMEMBER(_fontextFix));
+ persistMgr->transfer(TMEMBER(_wholeCell));
+
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int BaseFontBitmap::getCharWidth(byte index) {
+ if (_fontextFix) {
+ index--;
+ }
+ return _widths[index];
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontBitmap::getWidths() {
+ BaseSurface *surf = NULL;
+
+ if (_sprite) {
+ if (_widthsFrame >= 0 && _widthsFrame < (int32)_sprite->_frames.size()) {
+ if (_sprite->_frames[_widthsFrame] && (int32)_sprite->_frames[_widthsFrame]->_subframes.size() > 0) {
+ surf = _sprite->_frames[_widthsFrame]->_subframes[0]->_surface;
+ }
+ }
+ }
+ if (surf == NULL && _subframe) {
+ surf = _subframe->_surface;
+ }
+ if (!surf || DID_FAIL(surf->startPixelOp())) {
+ return STATUS_FAILED;
+ }
+
+
+ for (int i = 0; i < NUM_CHARACTERS; i++) {
+ int xxx = (i % _numColumns) * _tileWidth;
+ int yyy = (i / _numColumns) * _tileHeight;
+
+
+ int minCol = -1;
+ for (int row = 0; row < _tileHeight; row++) {
+ for (int col = _tileWidth - 1; col >= minCol + 1; col--) {
+ if (xxx + col < 0 || xxx + col >= surf->getWidth() || yyy + row < 0 || yyy + row >= surf->getHeight()) {
+ continue;
+ }
+ if (!surf->isTransparentAtLite(xxx + col, yyy + row)) {
+ //min_col = col;
+ minCol = MAX(col, minCol);
+ break;
+ }
+ }
+ if (minCol == _tileWidth - 1) {
+ break;
+ }
+ }
+
+ _widths[i] = minCol + 1;
+ }
+ surf->endPixelOp();
+ /*
+ _gameRef->LOG(0, "----- %s ------", _filename);
+ for(int j=0; j<16; j++)
+ {
+ _gameRef->LOG(0, "%02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d", _widths[j*16+0], _widths[j*16+1], _widths[j*16+2], _widths[j*16+3], _widths[j*16+4], _widths[j*16+5], _widths[j*16+6], _widths[j*16+7], _widths[j*16+8], _widths[j*16+9], _widths[j*16+10], _widths[j*16+11], _widths[j*16+12], _widths[j*16+13], _widths[j*16+14], _widths[j*16+15]);
+ }
+ */
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int BaseFontBitmap::getLetterHeight() {
+ return _tileHeight;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/font/base_font_bitmap.h b/engines/wintermute/base/font/base_font_bitmap.h
index 14a6e1cc87..2f3a69d097 100644
--- a/engines/wintermute/base/font/base_font_bitmap.h
+++ b/engines/wintermute/base/font/base_font_bitmap.h
@@ -1,71 +1,71 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This file is based on WME Lite.
- * http://dead-code.org/redir.php?target=wmelite
- * Copyright (c) 2011 Jan Nedoma
- */
-
-#ifndef WINTERMUTE_BASE_FONTBITMAP_H
-#define WINTERMUTE_BASE_FONTBITMAP_H
-
-
-#include "engines/wintermute/base/font/base_font.h"
-
-namespace Wintermute {
-class BaseSubFrame;
-class BaseFontBitmap : public BaseFont {
-public:
- DECLARE_PERSISTENT(BaseFontBitmap, BaseFont)
- bool loadBuffer(byte *Buffer);
- bool loadFile(const Common::String &filename);
- virtual int getTextWidth(byte *text, int maxLength = -1);
- virtual int getTextHeight(byte *text, int width);
- virtual void drawText(const byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int maxLength = -1);
- virtual int getLetterHeight();
-
- BaseFontBitmap(BaseGame *inGame);
- virtual ~BaseFontBitmap();
-
-private:
- bool getWidths();
- BaseSprite *_sprite;
- int _widthsFrame;
- bool _fontextFix;
- int _numColumns;
- int _tileHeight;
- int _tileWidth;
- byte _widths[NUM_CHARACTERS];
- BaseSubFrame *_subframe;
- bool _wholeCell;
-
- int getCharWidth(byte index);
- void drawChar(byte c, int x, int y);
-
- int textHeightDraw(const byte *text, int x, int y, int width, TTextAlign align, bool draw, int max_height = -1, int maxLength = -1);
-
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_BASE_FONTBITMAP_H
+#define WINTERMUTE_BASE_FONTBITMAP_H
+
+
+#include "engines/wintermute/base/font/base_font.h"
+
+namespace Wintermute {
+class BaseSubFrame;
+class BaseFontBitmap : public BaseFont {
+public:
+ DECLARE_PERSISTENT(BaseFontBitmap, BaseFont)
+ bool loadBuffer(byte *Buffer);
+ bool loadFile(const Common::String &filename);
+ virtual int getTextWidth(byte *text, int maxLength = -1);
+ virtual int getTextHeight(byte *text, int width);
+ virtual void drawText(const byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int maxLength = -1);
+ virtual int getLetterHeight();
+
+ BaseFontBitmap(BaseGame *inGame);
+ virtual ~BaseFontBitmap();
+
+private:
+ bool getWidths();
+ BaseSprite *_sprite;
+ int _widthsFrame;
+ bool _fontextFix;
+ int _numColumns;
+ int _tileHeight;
+ int _tileWidth;
+ byte _widths[NUM_CHARACTERS];
+ BaseSubFrame *_subframe;
+ bool _wholeCell;
+
+ int getCharWidth(byte index);
+ void drawChar(byte c, int x, int y);
+
+ int textHeightDraw(const byte *text, int x, int y, int width, TTextAlign align, bool draw, int max_height = -1, int maxLength = -1);
+
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/font/base_font_storage.cpp b/engines/wintermute/base/font/base_font_storage.cpp
index 298417ec32..d26fa1d593 100644
--- a/engines/wintermute/base/font/base_font_storage.cpp
+++ b/engines/wintermute/base/font/base_font_storage.cpp
@@ -1,142 +1,142 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This file is based on WME Lite.
- * http://dead-code.org/redir.php?target=wmelite
- * Copyright (c) 2011 Jan Nedoma
- */
-
-#include "engines/wintermute/base/font/base_font_storage.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "common/str.h"
-
-namespace Wintermute {
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-IMPLEMENT_PERSISTENT(BaseFontStorage, true)
-
-//////////////////////////////////////////////////////////////////////////
-BaseFontStorage::BaseFontStorage(BaseGame *inGame) : BaseClass(inGame) {
-}
-
-//////////////////////////////////////////////////////////////////////////
-BaseFontStorage::~BaseFontStorage() {
- cleanup(true);
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontStorage::cleanup(bool warn) {
- for (uint32 i = 0; i < _fonts.size(); i++) {
- if (warn) {
- _gameRef->LOG(0, "Removing orphan font '%s'", _fonts[i]->getFilename());
- }
- delete _fonts[i];
- }
- _fonts.clear();
-
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontStorage::initLoop() {
- for (uint32 i = 0; i < _fonts.size(); i++) {
- _fonts[i]->initLoop();
- }
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-BaseFont *BaseFontStorage::addFont(const Common::String &filename) {
- if (!filename.size()) {
- return NULL;
- }
-
- for (uint32 i = 0; i < _fonts.size(); i++) {
- if (scumm_stricmp(_fonts[i]->getFilename(), filename.c_str()) == 0) {
- _fonts[i]->_refCount++;
- return _fonts[i];
- }
- }
-
- /*
- BaseFont* font = new BaseFont(_gameRef);
- if (!font) return NULL;
-
- if (DID_FAIL(font->loadFile(filename))) {
- delete font;
- return NULL;
- }
- else {
- font->_refCount = 1;
- _fonts.add(font);
- return font;
- }
- */
- BaseFont *font = BaseFont::createFromFile(_gameRef, filename);
- if (font) {
- font->_refCount = 1;
- _fonts.add(font);
- }
- return font;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontStorage::removeFont(BaseFont *font) {
- if (!font) {
- return STATUS_FAILED;
- }
-
- for (uint32 i = 0; i < _fonts.size(); i++) {
- if (_fonts[i] == font) {
- _fonts[i]->_refCount--;
- if (_fonts[i]->_refCount <= 0) {
- delete _fonts[i];
- _fonts.remove_at(i);
- }
- break;
- }
- }
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontStorage::persist(BasePersistenceManager *persistMgr) {
-
- if (!persistMgr->getIsSaving()) {
- cleanup(false);
- }
-
- persistMgr->transfer(TMEMBER(_gameRef));
- _fonts.persist(persistMgr);
-
- return STATUS_OK;
-}
-
-} // end of namespace Wintermute
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#include "engines/wintermute/base/font/base_font_storage.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(BaseFontStorage, true)
+
+//////////////////////////////////////////////////////////////////////////
+BaseFontStorage::BaseFontStorage(BaseGame *inGame) : BaseClass(inGame) {
+}
+
+//////////////////////////////////////////////////////////////////////////
+BaseFontStorage::~BaseFontStorage() {
+ cleanup(true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontStorage::cleanup(bool warn) {
+ for (uint32 i = 0; i < _fonts.size(); i++) {
+ if (warn) {
+ _gameRef->LOG(0, "Removing orphan font '%s'", _fonts[i]->getFilename());
+ }
+ delete _fonts[i];
+ }
+ _fonts.clear();
+
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontStorage::initLoop() {
+ for (uint32 i = 0; i < _fonts.size(); i++) {
+ _fonts[i]->initLoop();
+ }
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+BaseFont *BaseFontStorage::addFont(const Common::String &filename) {
+ if (!filename.size()) {
+ return NULL;
+ }
+
+ for (uint32 i = 0; i < _fonts.size(); i++) {
+ if (scumm_stricmp(_fonts[i]->getFilename(), filename.c_str()) == 0) {
+ _fonts[i]->_refCount++;
+ return _fonts[i];
+ }
+ }
+
+ /*
+ BaseFont* font = new BaseFont(_gameRef);
+ if (!font) return NULL;
+
+ if (DID_FAIL(font->loadFile(filename))) {
+ delete font;
+ return NULL;
+ }
+ else {
+ font->_refCount = 1;
+ _fonts.add(font);
+ return font;
+ }
+ */
+ BaseFont *font = BaseFont::createFromFile(_gameRef, filename);
+ if (font) {
+ font->_refCount = 1;
+ _fonts.add(font);
+ }
+ return font;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontStorage::removeFont(BaseFont *font) {
+ if (!font) {
+ return STATUS_FAILED;
+ }
+
+ for (uint32 i = 0; i < _fonts.size(); i++) {
+ if (_fonts[i] == font) {
+ _fonts[i]->_refCount--;
+ if (_fonts[i]->_refCount <= 0) {
+ delete _fonts[i];
+ _fonts.remove_at(i);
+ }
+ break;
+ }
+ }
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontStorage::persist(BasePersistenceManager *persistMgr) {
+
+ if (!persistMgr->getIsSaving()) {
+ cleanup(false);
+ }
+
+ persistMgr->transfer(TMEMBER(_gameRef));
+ _fonts.persist(persistMgr);
+
+ return STATUS_OK;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/font/base_font_storage.h b/engines/wintermute/base/font/base_font_storage.h
index 733e1c5da3..60874167e7 100644
--- a/engines/wintermute/base/font/base_font_storage.h
+++ b/engines/wintermute/base/font/base_font_storage.h
@@ -1,55 +1,55 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This file is based on WME Lite.
- * http://dead-code.org/redir.php?target=wmelite
- * Copyright (c) 2011 Jan Nedoma
- */
-
-#ifndef WINTERMUTE_BASE_FONTSTORAGE_H
-#define WINTERMUTE_BASE_FONTSTORAGE_H
-
-
-#include "engines/wintermute/base/base.h"
-#include "engines/wintermute/persistent.h"
-#include "engines/wintermute/coll_templ.h"
-
-namespace Wintermute {
-
-class BaseFont;
-
-class BaseFontStorage : public BaseClass {
-public:
- DECLARE_PERSISTENT(BaseFontStorage, BaseClass)
- bool cleanup(bool warn = false);
- bool removeFont(BaseFont *font);
- BaseFont *addFont(const Common::String &filename);
- BaseFontStorage(BaseGame *inGame);
- virtual ~BaseFontStorage();
- BaseArray<BaseFont *> _fonts;
- bool initLoop();
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_BASE_FONTSTORAGE_H
+#define WINTERMUTE_BASE_FONTSTORAGE_H
+
+
+#include "engines/wintermute/base/base.h"
+#include "engines/wintermute/persistent.h"
+#include "engines/wintermute/coll_templ.h"
+
+namespace Wintermute {
+
+class BaseFont;
+
+class BaseFontStorage : public BaseClass {
+public:
+ DECLARE_PERSISTENT(BaseFontStorage, BaseClass)
+ bool cleanup(bool warn = false);
+ bool removeFont(BaseFont *font);
+ BaseFont *addFont(const Common::String &filename);
+ BaseFontStorage(BaseGame *inGame);
+ virtual ~BaseFontStorage();
+ BaseArray<BaseFont *> _fonts;
+ bool initLoop();
+};
+
+} // end of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index 171f33d8ab..599010bbd5 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -1,605 +1,605 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This file is based on WME Lite.
- * http://dead-code.org/redir.php?target=wmelite
- * Copyright (c) 2011 Jan Nedoma
- */
-
-#include "engines/wintermute/base/file/base_file.h"
-#include "engines/wintermute/base/font/base_font_truetype.h"
-#include "engines/wintermute/utils/path_util.h"
-#include "engines/wintermute/utils/string_util.h"
-#include "engines/wintermute/math/math_util.h"
-#include "engines/wintermute/base/gfx/base_renderer.h"
-#include "engines/wintermute/base/gfx/base_surface.h"
-#include "engines/wintermute/base/base_parser.h"
-#include "engines/wintermute/base/base_game.h"
-#include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/utils/utils.h"
-#include "engines/wintermute/platform_osystem.h"
-#include "engines/wintermute/wintermute.h"
-#include "graphics/fonts/ttf.h"
-#include "graphics/fontman.h"
-#include <limits.h>
-
-namespace Wintermute {
-
-IMPLEMENT_PERSISTENT(BaseFontTT, false)
-
-//////////////////////////////////////////////////////////////////////////
-BaseFontTT::BaseFontTT(BaseGame *inGame) : BaseFont(inGame) {
- _fontHeight = 12;
- _isBold = _isItalic = _isUnderline = _isStriked = false;
-
- _fontFile = NULL;
- _font = NULL;
- _fallbackFont = NULL;
- _deletableFont = NULL;
-
- for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
- _cachedTexts[i] = NULL;
- }
-
- _lineHeight = 0;
- _maxCharWidth = _maxCharHeight = 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-BaseFontTT::~BaseFontTT(void) {
- clearCache();
-
- for (uint32 i = 0; i < _layers.size(); i++) {
- delete _layers[i];
- }
- _layers.clear();
-
- delete[] _fontFile;
- _fontFile = NULL;
-
- delete _deletableFont;
- _font = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void BaseFontTT::clearCache() {
- for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
- if (_cachedTexts[i]) {
- delete _cachedTexts[i];
- }
- _cachedTexts[i] = NULL;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-void BaseFontTT::initLoop() {
- // we need more aggressive cache management on iOS not to waste too much memory on fonts
- if (_gameRef->_constrainedMemory) {
- // purge all cached images not used in the last frame
- for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
- if (_cachedTexts[i] == NULL) {
- continue;
- }
-
- if (!_cachedTexts[i]->_marked) {
- delete _cachedTexts[i];
- _cachedTexts[i] = NULL;
- } else {
- _cachedTexts[i]->_marked = false;
- }
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-int BaseFontTT::getTextWidth(byte *text, int maxLength) {
- WideString textStr;
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- textStr = StringUtil::utf8ToWide((char *)text);
- } else {
- textStr = StringUtil::ansiToWide((char *)text);
- }
-
- if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
- textStr = Common::String(textStr.c_str(), (uint32)maxLength);
- }
- //text = text.substr(0, MaxLength); // TODO: Remove
-
- int textWidth, textHeight;
- measureText(textStr, -1, -1, textWidth, textHeight);
-
- return textWidth;
-}
-
-//////////////////////////////////////////////////////////////////////////
-int BaseFontTT::getTextHeight(byte *text, int width) {
- WideString textStr;
-
- if (_gameRef->_textEncoding == TEXT_UTF8) {
- textStr = StringUtil::utf8ToWide((char *)text);
- } else {
- textStr = StringUtil::ansiToWide((char *)text);
- }
-
-
- int textWidth, textHeight;
- measureText(textStr, width, -1, textWidth, textHeight);
-
- return textHeight;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign align, int maxHeight, int maxLength) {
- if (text == NULL || strcmp((const char *)text, "") == 0) {
- return;
- }
-
- WideString textStr = (const char *)text;
-
- // TODO: Why do we still insist on Widestrings everywhere?
- /* if (_gameRef->_textEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text);
- else text = StringUtil::AnsiToWide((char *)Text);*/
-
- if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
- textStr = Common::String(textStr.c_str(), (uint32)maxLength);
- }
- //text = text.substr(0, MaxLength); // TODO: Remove
-
- BaseRenderer *renderer = _gameRef->_renderer;
-
- // find cached surface, if exists
- int minPriority = INT_MAX;
- int minIndex = -1;
- BaseSurface *surface = NULL;
- int textOffset = 0;
-
- for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
- if (_cachedTexts[i] == NULL) {
- minPriority = 0;
- minIndex = i;
- } else {
- if (_cachedTexts[i]->_text == textStr && _cachedTexts[i]->_align == align && _cachedTexts[i]->_width == width && _cachedTexts[i]->_maxHeight == maxHeight && _cachedTexts[i]->_maxLength == maxLength) {
- surface = _cachedTexts[i]->_surface;
- textOffset = _cachedTexts[i]->_textOffset;
- _cachedTexts[i]->_priority++;
- _cachedTexts[i]->_marked = true;
- break;
- } else {
- if (_cachedTexts[i]->_priority < minPriority) {
- minPriority = _cachedTexts[i]->_priority;
- minIndex = i;
- }
- }
- }
- }
-
- // not found, create one
- if (!surface) {
- debugC(kWintermuteDebugFont, "Draw text: %s", text);
- surface = renderTextToTexture(textStr, width, align, maxHeight, textOffset);
- if (surface) {
- // write surface to cache
- if (_cachedTexts[minIndex] != NULL) {
- delete _cachedTexts[minIndex];
- }
- _cachedTexts[minIndex] = new BaseCachedTTFontText;
-
- _cachedTexts[minIndex]->_surface = surface;
- _cachedTexts[minIndex]->_align = align;
- _cachedTexts[minIndex]->_width = width;
- _cachedTexts[minIndex]->_maxHeight = maxHeight;
- _cachedTexts[minIndex]->_maxLength = maxLength;
- _cachedTexts[minIndex]->_priority = 1;
- _cachedTexts[minIndex]->_text = textStr;
- _cachedTexts[minIndex]->_textOffset = textOffset;
- _cachedTexts[minIndex]->_marked = true;
- }
- }
-
-
- // and paint it
- if (surface) {
- Rect32 rc;
- BasePlatform::setRect(&rc, 0, 0, surface->getWidth(), surface->getHeight());
- for (uint32 i = 0; i < _layers.size(); i++) {
- uint32 color = _layers[i]->_color;
- uint32 origForceAlpha = renderer->_forceAlphaColor;
- if (renderer->_forceAlphaColor != 0) {
- color = BYTETORGBA(RGBCOLGetR(color), RGBCOLGetG(color), RGBCOLGetB(color), RGBCOLGetA(renderer->_forceAlphaColor));
- renderer->_forceAlphaColor = 0;
- }
- surface->displayTransOffset(x, y - textOffset, rc, color, BLEND_NORMAL, false, false, _layers[i]->_offsetX, _layers[i]->_offsetY);
-
- renderer->_forceAlphaColor = origForceAlpha;
- }
- }
-
-
-}
-
-//////////////////////////////////////////////////////////////////////////
-BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset) {
- //TextLineList lines;
- // TODO: Use WideString-conversion here.
- //WrapText(text, width, maxHeight, lines);
- Common::Array<Common::String> lines;
- _font->wordWrapText(text, width, lines);
-
- while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) {
- lines.pop_back();
- }
- if (lines.size() == 0) {
- return NULL;
- }
-
- Graphics::TextAlign alignment = Graphics::kTextAlignInvalid;
- if (align == TAL_LEFT) {
- alignment = Graphics::kTextAlignLeft;
- } else if (align == TAL_CENTER) {
- alignment = Graphics::kTextAlignCenter;
- } else if (align == TAL_RIGHT) {
- alignment = Graphics::kTextAlignRight;
- }
-
- debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
-// void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
- Graphics::Surface *surface = new Graphics::Surface();
- if (_deletableFont) { // We actually have a TTF
- surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
- } else { // We are using a fallback, they can't do 32bpp
- surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
- }
- uint32 useColor = 0xffffffff;
- Common::Array<Common::String>::iterator it;
- int heightOffset = 0;
- for (it = lines.begin(); it != lines.end(); ++it) {
- _font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment);
- heightOffset += (int)_lineHeight;
- }
-
- BaseSurface *retSurface = _gameRef->_renderer->createSurface();
- Graphics::Surface *convertedSurface = surface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
- retSurface->putSurface(*convertedSurface, true);
- convertedSurface->free();
- surface->free();
- delete surface;
- delete convertedSurface;
- return retSurface;
- // TODO: _isUnderline, _isBold, _isItalic, _isStriked
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-int BaseFontTT::getLetterHeight() {
- return (int)getLineHeight();
-}
-
-
-//////////////////////////////////////////////////////////////////////
-bool BaseFontTT::loadFile(const Common::String &filename) {
- byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
- if (buffer == NULL) {
- _gameRef->LOG(0, "BaseFontTT::LoadFile failed for file '%s'", filename.c_str());
- return STATUS_FAILED;
- }
-
- bool ret;
-
- setFilename(filename.c_str());
-
- if (DID_FAIL(ret = loadBuffer(buffer))) {
- _gameRef->LOG(0, "Error parsing TTFONT file '%s'", filename.c_str());
- }
-
- delete[] buffer;
-
- return ret;
-}
-
-
-TOKEN_DEF_START
-TOKEN_DEF(TTFONT)
-TOKEN_DEF(SIZE)
-TOKEN_DEF(FACE)
-TOKEN_DEF(FILENAME)
-TOKEN_DEF(BOLD)
-TOKEN_DEF(ITALIC)
-TOKEN_DEF(UNDERLINE)
-TOKEN_DEF(STRIKE)
-TOKEN_DEF(CHARSET)
-TOKEN_DEF(COLOR)
-TOKEN_DEF(ALPHA)
-TOKEN_DEF(LAYER)
-TOKEN_DEF(OFFSET_X)
-TOKEN_DEF(OFFSET_Y)
-TOKEN_DEF_END
-//////////////////////////////////////////////////////////////////////
-bool BaseFontTT::loadBuffer(byte *buffer) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(TTFONT)
- TOKEN_TABLE(SIZE)
- TOKEN_TABLE(FACE)
- TOKEN_TABLE(FILENAME)
- TOKEN_TABLE(BOLD)
- TOKEN_TABLE(ITALIC)
- TOKEN_TABLE(UNDERLINE)
- TOKEN_TABLE(STRIKE)
- TOKEN_TABLE(CHARSET)
- TOKEN_TABLE(COLOR)
- TOKEN_TABLE(ALPHA)
- TOKEN_TABLE(LAYER)
- TOKEN_TABLE_END
-
- char *params;
- int cmd;
- BaseParser parser;
-
- if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TTFONT) {
- _gameRef->LOG(0, "'TTFONT' keyword expected.");
- return STATUS_FAILED;
- }
- buffer = (byte *)params;
-
- uint32 baseColor = 0x00000000;
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_SIZE:
- parser.scanStr(params, "%d", &_fontHeight);
- break;
-
- case TOKEN_FACE:
- // we don't need this anymore
- break;
-
- case TOKEN_FILENAME:
- BaseUtils::setString(&_fontFile, params);
- break;
-
- case TOKEN_BOLD:
- parser.scanStr(params, "%b", &_isBold);
- break;
-
- case TOKEN_ITALIC:
- parser.scanStr(params, "%b", &_isItalic);
- break;
-
- case TOKEN_UNDERLINE:
- parser.scanStr(params, "%b", &_isUnderline);
- break;
-
- case TOKEN_STRIKE:
- parser.scanStr(params, "%b", &_isStriked);
- break;
-
- case TOKEN_CHARSET:
- // we don't need this anymore
- break;
-
- case TOKEN_COLOR: {
- int r, g, b;
- parser.scanStr(params, "%d,%d,%d", &r, &g, &b);
- baseColor = BYTETORGBA(r, g, b, RGBCOLGetA(baseColor));
- }
- break;
-
- case TOKEN_ALPHA: {
- int a;
- parser.scanStr(params, "%d", &a);
- baseColor = BYTETORGBA(RGBCOLGetR(baseColor), RGBCOLGetG(baseColor), RGBCOLGetB(baseColor), a);
- }
- break;
-
- case TOKEN_LAYER: {
- BaseTTFontLayer *layer = new BaseTTFontLayer;
- if (layer && DID_SUCCEED(parseLayer(layer, (byte *)params))) {
- _layers.add(layer);
- } else {
- delete layer;
- layer = NULL;
- cmd = PARSERR_TOKENNOTFOUND;
- }
- }
- break;
-
- }
- }
- if (cmd == PARSERR_TOKENNOTFOUND) {
- _gameRef->LOG(0, "Syntax error in TTFONT definition");
- return STATUS_FAILED;
- }
-
- // create at least one layer
- if (_layers.size() == 0) {
- BaseTTFontLayer *layer = new BaseTTFontLayer;
- layer->_color = baseColor;
- _layers.add(layer);
- }
-
- if (!_fontFile) {
- BaseUtils::setString(&_fontFile, "arial.ttf");
- }
-
- return initFont();
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) {
- TOKEN_TABLE_START(commands)
- TOKEN_TABLE(OFFSET_X)
- TOKEN_TABLE(OFFSET_Y)
- TOKEN_TABLE(COLOR)
- TOKEN_TABLE(ALPHA)
- TOKEN_TABLE_END
-
- char *params;
- int cmd;
- BaseParser parser;
-
- while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
- switch (cmd) {
- case TOKEN_OFFSET_X:
- parser.scanStr(params, "%d", &layer->_offsetX);
- break;
-
- case TOKEN_OFFSET_Y:
- parser.scanStr(params, "%d", &layer->_offsetY);
- break;
-
- case TOKEN_COLOR: {
- int r, g, b;
- parser.scanStr(params, "%d,%d,%d", &r, &g, &b);
- layer->_color = BYTETORGBA(r, g, b, RGBCOLGetA(layer->_color));
- }
- break;
-
- case TOKEN_ALPHA: {
- int a;
- parser.scanStr(params, "%d", &a);
- layer->_color = BYTETORGBA(RGBCOLGetR(layer->_color), RGBCOLGetG(layer->_color), RGBCOLGetB(layer->_color), a);
- }
- break;
- }
- }
- if (cmd != PARSERR_EOF) {
- return STATUS_FAILED;
- } else {
- return STATUS_OK;
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontTT::persist(BasePersistenceManager *persistMgr) {
- BaseFont::persist(persistMgr);
-
- persistMgr->transfer(TMEMBER(_isBold));
- persistMgr->transfer(TMEMBER(_isItalic));
- persistMgr->transfer(TMEMBER(_isUnderline));
- persistMgr->transfer(TMEMBER(_isStriked));
- persistMgr->transfer(TMEMBER(_fontHeight));
- persistMgr->transfer(TMEMBER(_fontFile));
-
-
- // persist layers
- int numLayers;
- if (persistMgr->getIsSaving()) {
- numLayers = _layers.size();
- persistMgr->transfer(TMEMBER(numLayers));
- for (int i = 0; i < numLayers; i++) {
- _layers[i]->persist(persistMgr);
- }
- } else {
- numLayers = _layers.size();
- persistMgr->transfer(TMEMBER(numLayers));
- for (int i = 0; i < numLayers; i++) {
- BaseTTFontLayer *layer = new BaseTTFontLayer;
- layer->persist(persistMgr);
- _layers.add(layer);
- }
- }
-
- if (!persistMgr->getIsSaving()) {
- for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
- _cachedTexts[i] = NULL;
- }
- _fallbackFont = _font = _deletableFont = NULL;
- }
-
- return STATUS_OK;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-void BaseFontTT::afterLoad() {
- initFont();
-}
-
-//////////////////////////////////////////////////////////////////////////
-bool BaseFontTT::initFont() {
- if (!_fontFile) {
- return STATUS_FAILED;
- }
-
- Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(_fontFile);
- if (!file) {
- //TODO: Try to fallback from Arial to FreeSans
- /*
- // the requested font file is not in wme file space; try loading a system font
- AnsiString fontFileName = PathUtil::combine(BasePlatform::getSystemFontPath(), PathUtil::getFileName(_fontFile));
- file = BaseFileManager::getEngineInstance()->openFile(fontFileName.c_str(), false);
- if (!file) {
- _gameRef->LOG(0, "Error loading TrueType font '%s'", _fontFile);
- //return STATUS_FAILED;
- }*/
- }
-
- if (file) {
-#ifdef USE_FREETYPE2
- _deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72).
- _font = _deletableFont;
-#endif
- }
- if (!_font) {
- _font = _fallbackFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
- warning("BaseFontTT::InitFont - Couldn't load font: %s", _fontFile);
- }
- _lineHeight = _font->getFontHeight();
- return STATUS_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-void BaseFontTT::measureText(const WideString &text, int maxWidth, int maxHeight, int &textWidth, int &textHeight) {
- //TextLineList lines;
-
- if (maxWidth >= 0) {
- Common::Array<Common::String> lines;
- _font->wordWrapText(text, maxWidth, lines);
- Common::Array<Common::String>::iterator it;
- textWidth = 0;
- for (it = lines.begin(); it != lines.end(); ++it) {
- textWidth = MAX(textWidth, _font->getStringWidth(*it));
- }
-
- //WrapText(text, maxWidth, maxHeight, lines);
-
- textHeight = (int)(lines.size() * getLineHeight());
- } else {
- textWidth = _font->getStringWidth(text);
- textHeight = _fontHeight;
- }
- /*
- TextLineList::iterator it;
- for (it = lines.begin(); it != lines.end(); ++it) {
- TextLine *line = (*it);
- textWidth = MAX(textWidth, line->GetWidth());
- delete line;
- line = NULL;
- }*/
-}
-
-} // end of namespace Wintermute
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#include "engines/wintermute/base/file/base_file.h"
+#include "engines/wintermute/base/font/base_font_truetype.h"
+#include "engines/wintermute/utils/path_util.h"
+#include "engines/wintermute/utils/string_util.h"
+#include "engines/wintermute/math/math_util.h"
+#include "engines/wintermute/base/gfx/base_renderer.h"
+#include "engines/wintermute/base/gfx/base_surface.h"
+#include "engines/wintermute/base/base_parser.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/utils/utils.h"
+#include "engines/wintermute/platform_osystem.h"
+#include "engines/wintermute/wintermute.h"
+#include "graphics/fonts/ttf.h"
+#include "graphics/fontman.h"
+#include <limits.h>
+
+namespace Wintermute {
+
+IMPLEMENT_PERSISTENT(BaseFontTT, false)
+
+//////////////////////////////////////////////////////////////////////////
+BaseFontTT::BaseFontTT(BaseGame *inGame) : BaseFont(inGame) {
+ _fontHeight = 12;
+ _isBold = _isItalic = _isUnderline = _isStriked = false;
+
+ _fontFile = NULL;
+ _font = NULL;
+ _fallbackFont = NULL;
+ _deletableFont = NULL;
+
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
+ _cachedTexts[i] = NULL;
+ }
+
+ _lineHeight = 0;
+ _maxCharWidth = _maxCharHeight = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+BaseFontTT::~BaseFontTT(void) {
+ clearCache();
+
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ delete _layers[i];
+ }
+ _layers.clear();
+
+ delete[] _fontFile;
+ _fontFile = NULL;
+
+ delete _deletableFont;
+ _font = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void BaseFontTT::clearCache() {
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
+ if (_cachedTexts[i]) {
+ delete _cachedTexts[i];
+ }
+ _cachedTexts[i] = NULL;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void BaseFontTT::initLoop() {
+ // we need more aggressive cache management on iOS not to waste too much memory on fonts
+ if (_gameRef->_constrainedMemory) {
+ // purge all cached images not used in the last frame
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
+ if (_cachedTexts[i] == NULL) {
+ continue;
+ }
+
+ if (!_cachedTexts[i]->_marked) {
+ delete _cachedTexts[i];
+ _cachedTexts[i] = NULL;
+ } else {
+ _cachedTexts[i]->_marked = false;
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+int BaseFontTT::getTextWidth(byte *text, int maxLength) {
+ WideString textStr;
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ textStr = StringUtil::utf8ToWide((char *)text);
+ } else {
+ textStr = StringUtil::ansiToWide((char *)text);
+ }
+
+ if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
+ textStr = Common::String(textStr.c_str(), (uint32)maxLength);
+ }
+ //text = text.substr(0, MaxLength); // TODO: Remove
+
+ int textWidth, textHeight;
+ measureText(textStr, -1, -1, textWidth, textHeight);
+
+ return textWidth;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int BaseFontTT::getTextHeight(byte *text, int width) {
+ WideString textStr;
+
+ if (_gameRef->_textEncoding == TEXT_UTF8) {
+ textStr = StringUtil::utf8ToWide((char *)text);
+ } else {
+ textStr = StringUtil::ansiToWide((char *)text);
+ }
+
+
+ int textWidth, textHeight;
+ measureText(textStr, width, -1, textWidth, textHeight);
+
+ return textHeight;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign align, int maxHeight, int maxLength) {
+ if (text == NULL || strcmp((const char *)text, "") == 0) {
+ return;
+ }
+
+ WideString textStr = (const char *)text;
+
+ // TODO: Why do we still insist on Widestrings everywhere?
+ /* if (_gameRef->_textEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text);
+ else text = StringUtil::AnsiToWide((char *)Text);*/
+
+ if (maxLength >= 0 && textStr.size() > (uint32)maxLength) {
+ textStr = Common::String(textStr.c_str(), (uint32)maxLength);
+ }
+ //text = text.substr(0, MaxLength); // TODO: Remove
+
+ BaseRenderer *renderer = _gameRef->_renderer;
+
+ // find cached surface, if exists
+ int minPriority = INT_MAX;
+ int minIndex = -1;
+ BaseSurface *surface = NULL;
+ int textOffset = 0;
+
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
+ if (_cachedTexts[i] == NULL) {
+ minPriority = 0;
+ minIndex = i;
+ } else {
+ if (_cachedTexts[i]->_text == textStr && _cachedTexts[i]->_align == align && _cachedTexts[i]->_width == width && _cachedTexts[i]->_maxHeight == maxHeight && _cachedTexts[i]->_maxLength == maxLength) {
+ surface = _cachedTexts[i]->_surface;
+ textOffset = _cachedTexts[i]->_textOffset;
+ _cachedTexts[i]->_priority++;
+ _cachedTexts[i]->_marked = true;
+ break;
+ } else {
+ if (_cachedTexts[i]->_priority < minPriority) {
+ minPriority = _cachedTexts[i]->_priority;
+ minIndex = i;
+ }
+ }
+ }
+ }
+
+ // not found, create one
+ if (!surface) {
+ debugC(kWintermuteDebugFont, "Draw text: %s", text);
+ surface = renderTextToTexture(textStr, width, align, maxHeight, textOffset);
+ if (surface) {
+ // write surface to cache
+ if (_cachedTexts[minIndex] != NULL) {
+ delete _cachedTexts[minIndex];
+ }
+ _cachedTexts[minIndex] = new BaseCachedTTFontText;
+
+ _cachedTexts[minIndex]->_surface = surface;
+ _cachedTexts[minIndex]->_align = align;
+ _cachedTexts[minIndex]->_width = width;
+ _cachedTexts[minIndex]->_maxHeight = maxHeight;
+ _cachedTexts[minIndex]->_maxLength = maxLength;
+ _cachedTexts[minIndex]->_priority = 1;
+ _cachedTexts[minIndex]->_text = textStr;
+ _cachedTexts[minIndex]->_textOffset = textOffset;
+ _cachedTexts[minIndex]->_marked = true;
+ }
+ }
+
+
+ // and paint it
+ if (surface) {
+ Rect32 rc;
+ BasePlatform::setRect(&rc, 0, 0, surface->getWidth(), surface->getHeight());
+ for (uint32 i = 0; i < _layers.size(); i++) {
+ uint32 color = _layers[i]->_color;
+ uint32 origForceAlpha = renderer->_forceAlphaColor;
+ if (renderer->_forceAlphaColor != 0) {
+ color = BYTETORGBA(RGBCOLGetR(color), RGBCOLGetG(color), RGBCOLGetB(color), RGBCOLGetA(renderer->_forceAlphaColor));
+ renderer->_forceAlphaColor = 0;
+ }
+ surface->displayTransOffset(x, y - textOffset, rc, color, BLEND_NORMAL, false, false, _layers[i]->_offsetX, _layers[i]->_offsetY);
+
+ renderer->_forceAlphaColor = origForceAlpha;
+ }
+ }
+
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset) {
+ //TextLineList lines;
+ // TODO: Use WideString-conversion here.
+ //WrapText(text, width, maxHeight, lines);
+ Common::Array<Common::String> lines;
+ _font->wordWrapText(text, width, lines);
+
+ while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) {
+ lines.pop_back();
+ }
+ if (lines.size() == 0) {
+ return NULL;
+ }
+
+ Graphics::TextAlign alignment = Graphics::kTextAlignInvalid;
+ if (align == TAL_LEFT) {
+ alignment = Graphics::kTextAlignLeft;
+ } else if (align == TAL_CENTER) {
+ alignment = Graphics::kTextAlignCenter;
+ } else if (align == TAL_RIGHT) {
+ alignment = Graphics::kTextAlignRight;
+ }
+
+ debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
+// void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
+ Graphics::Surface *surface = new Graphics::Surface();
+ if (_deletableFont) { // We actually have a TTF
+ surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+ } else { // We are using a fallback, they can't do 32bpp
+ surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
+ }
+ uint32 useColor = 0xffffffff;
+ Common::Array<Common::String>::iterator it;
+ int heightOffset = 0;
+ for (it = lines.begin(); it != lines.end(); ++it) {
+ _font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment);
+ heightOffset += (int)_lineHeight;
+ }
+
+ BaseSurface *retSurface = _gameRef->_renderer->createSurface();
+ Graphics::Surface *convertedSurface = surface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+ retSurface->putSurface(*convertedSurface, true);
+ convertedSurface->free();
+ surface->free();
+ delete surface;
+ delete convertedSurface;
+ return retSurface;
+ // TODO: _isUnderline, _isBold, _isItalic, _isStriked
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int BaseFontTT::getLetterHeight() {
+ return (int)getLineHeight();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+bool BaseFontTT::loadFile(const Common::String &filename) {
+ byte *buffer = BaseFileManager::getEngineInstance()->readWholeFile(filename);
+ if (buffer == NULL) {
+ _gameRef->LOG(0, "BaseFontTT::LoadFile failed for file '%s'", filename.c_str());
+ return STATUS_FAILED;
+ }
+
+ bool ret;
+
+ setFilename(filename.c_str());
+
+ if (DID_FAIL(ret = loadBuffer(buffer))) {
+ _gameRef->LOG(0, "Error parsing TTFONT file '%s'", filename.c_str());
+ }
+
+ delete[] buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(TTFONT)
+TOKEN_DEF(SIZE)
+TOKEN_DEF(FACE)
+TOKEN_DEF(FILENAME)
+TOKEN_DEF(BOLD)
+TOKEN_DEF(ITALIC)
+TOKEN_DEF(UNDERLINE)
+TOKEN_DEF(STRIKE)
+TOKEN_DEF(CHARSET)
+TOKEN_DEF(COLOR)
+TOKEN_DEF(ALPHA)
+TOKEN_DEF(LAYER)
+TOKEN_DEF(OFFSET_X)
+TOKEN_DEF(OFFSET_Y)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////
+bool BaseFontTT::loadBuffer(byte *buffer) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(TTFONT)
+ TOKEN_TABLE(SIZE)
+ TOKEN_TABLE(FACE)
+ TOKEN_TABLE(FILENAME)
+ TOKEN_TABLE(BOLD)
+ TOKEN_TABLE(ITALIC)
+ TOKEN_TABLE(UNDERLINE)
+ TOKEN_TABLE(STRIKE)
+ TOKEN_TABLE(CHARSET)
+ TOKEN_TABLE(COLOR)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE(LAYER)
+ TOKEN_TABLE_END
+
+ char *params;
+ int cmd;
+ BaseParser parser;
+
+ if (parser.getCommand((char **)&buffer, commands, (char **)&params) != TOKEN_TTFONT) {
+ _gameRef->LOG(0, "'TTFONT' keyword expected.");
+ return STATUS_FAILED;
+ }
+ buffer = (byte *)params;
+
+ uint32 baseColor = 0x00000000;
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_SIZE:
+ parser.scanStr(params, "%d", &_fontHeight);
+ break;
+
+ case TOKEN_FACE:
+ // we don't need this anymore
+ break;
+
+ case TOKEN_FILENAME:
+ BaseUtils::setString(&_fontFile, params);
+ break;
+
+ case TOKEN_BOLD:
+ parser.scanStr(params, "%b", &_isBold);
+ break;
+
+ case TOKEN_ITALIC:
+ parser.scanStr(params, "%b", &_isItalic);
+ break;
+
+ case TOKEN_UNDERLINE:
+ parser.scanStr(params, "%b", &_isUnderline);
+ break;
+
+ case TOKEN_STRIKE:
+ parser.scanStr(params, "%b", &_isStriked);
+ break;
+
+ case TOKEN_CHARSET:
+ // we don't need this anymore
+ break;
+
+ case TOKEN_COLOR: {
+ int r, g, b;
+ parser.scanStr(params, "%d,%d,%d", &r, &g, &b);
+ baseColor = BYTETORGBA(r, g, b, RGBCOLGetA(baseColor));
+ }
+ break;
+
+ case TOKEN_ALPHA: {
+ int a;
+ parser.scanStr(params, "%d", &a);
+ baseColor = BYTETORGBA(RGBCOLGetR(baseColor), RGBCOLGetG(baseColor), RGBCOLGetB(baseColor), a);
+ }
+ break;
+
+ case TOKEN_LAYER: {
+ BaseTTFontLayer *layer = new BaseTTFontLayer;
+ if (layer && DID_SUCCEED(parseLayer(layer, (byte *)params))) {
+ _layers.add(layer);
+ } else {
+ delete layer;
+ layer = NULL;
+ cmd = PARSERR_TOKENNOTFOUND;
+ }
+ }
+ break;
+
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ _gameRef->LOG(0, "Syntax error in TTFONT definition");
+ return STATUS_FAILED;
+ }
+
+ // create at least one layer
+ if (_layers.size() == 0) {
+ BaseTTFontLayer *layer = new BaseTTFontLayer;
+ layer->_color = baseColor;
+ _layers.add(layer);
+ }
+
+ if (!_fontFile) {
+ BaseUtils::setString(&_fontFile, "arial.ttf");
+ }
+
+ return initFont();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontTT::parseLayer(BaseTTFontLayer *layer, byte *buffer) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(OFFSET_X)
+ TOKEN_TABLE(OFFSET_Y)
+ TOKEN_TABLE(COLOR)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE_END
+
+ char *params;
+ int cmd;
+ BaseParser parser;
+
+ while ((cmd = parser.getCommand((char **)&buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_OFFSET_X:
+ parser.scanStr(params, "%d", &layer->_offsetX);
+ break;
+
+ case TOKEN_OFFSET_Y:
+ parser.scanStr(params, "%d", &layer->_offsetY);
+ break;
+
+ case TOKEN_COLOR: {
+ int r, g, b;
+ parser.scanStr(params, "%d,%d,%d", &r, &g, &b);
+ layer->_color = BYTETORGBA(r, g, b, RGBCOLGetA(layer->_color));
+ }
+ break;
+
+ case TOKEN_ALPHA: {
+ int a;
+ parser.scanStr(params, "%d", &a);
+ layer->_color = BYTETORGBA(RGBCOLGetR(layer->_color), RGBCOLGetG(layer->_color), RGBCOLGetB(layer->_color), a);
+ }
+ break;
+ }
+ }
+ if (cmd != PARSERR_EOF) {
+ return STATUS_FAILED;
+ } else {
+ return STATUS_OK;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontTT::persist(BasePersistenceManager *persistMgr) {
+ BaseFont::persist(persistMgr);
+
+ persistMgr->transfer(TMEMBER(_isBold));
+ persistMgr->transfer(TMEMBER(_isItalic));
+ persistMgr->transfer(TMEMBER(_isUnderline));
+ persistMgr->transfer(TMEMBER(_isStriked));
+ persistMgr->transfer(TMEMBER(_fontHeight));
+ persistMgr->transfer(TMEMBER(_fontFile));
+
+
+ // persist layers
+ int numLayers;
+ if (persistMgr->getIsSaving()) {
+ numLayers = _layers.size();
+ persistMgr->transfer(TMEMBER(numLayers));
+ for (int i = 0; i < numLayers; i++) {
+ _layers[i]->persist(persistMgr);
+ }
+ } else {
+ numLayers = _layers.size();
+ persistMgr->transfer(TMEMBER(numLayers));
+ for (int i = 0; i < numLayers; i++) {
+ BaseTTFontLayer *layer = new BaseTTFontLayer;
+ layer->persist(persistMgr);
+ _layers.add(layer);
+ }
+ }
+
+ if (!persistMgr->getIsSaving()) {
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
+ _cachedTexts[i] = NULL;
+ }
+ _fallbackFont = _font = _deletableFont = NULL;
+ }
+
+ return STATUS_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void BaseFontTT::afterLoad() {
+ initFont();
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool BaseFontTT::initFont() {
+ if (!_fontFile) {
+ return STATUS_FAILED;
+ }
+
+ Common::SeekableReadStream *file = BaseFileManager::getEngineInstance()->openFile(_fontFile);
+ if (!file) {
+ //TODO: Try to fallback from Arial to FreeSans
+ /*
+ // the requested font file is not in wme file space; try loading a system font
+ AnsiString fontFileName = PathUtil::combine(BasePlatform::getSystemFontPath(), PathUtil::getFileName(_fontFile));
+ file = BaseFileManager::getEngineInstance()->openFile(fontFileName.c_str(), false);
+ if (!file) {
+ _gameRef->LOG(0, "Error loading TrueType font '%s'", _fontFile);
+ //return STATUS_FAILED;
+ }*/
+ }
+
+ if (file) {
+#ifdef USE_FREETYPE2
+ _deletableFont = Graphics::loadTTFFont(*file, 96, _fontHeight); // Use the same dpi as WME (96 vs 72).
+ _font = _deletableFont;
+#endif
+ }
+ if (!_font) {
+ _font = _fallbackFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
+ warning("BaseFontTT::InitFont - Couldn't load font: %s", _fontFile);
+ }
+ _lineHeight = _font->getFontHeight();
+ return STATUS_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void BaseFontTT::measureText(const WideString &text, int maxWidth, int maxHeight, int &textWidth, int &textHeight) {
+ //TextLineList lines;
+
+ if (maxWidth >= 0) {
+ Common::Array<Common::String> lines;
+ _font->wordWrapText(text, maxWidth, lines);
+ Common::Array<Common::String>::iterator it;
+ textWidth = 0;
+ for (it = lines.begin(); it != lines.end(); ++it) {
+ textWidth = MAX(textWidth, _font->getStringWidth(*it));
+ }
+
+ //WrapText(text, maxWidth, maxHeight, lines);
+
+ textHeight = (int)(lines.size() * getLineHeight());
+ } else {
+ textWidth = _font->getStringWidth(text);
+ textHeight = _fontHeight;
+ }
+ /*
+ TextLineList::iterator it;
+ for (it = lines.begin(); it != lines.end(); ++it) {
+ TextLine *line = (*it);
+ textWidth = MAX(textWidth, line->GetWidth());
+ delete line;
+ line = NULL;
+ }*/
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/base/font/base_font_truetype.h b/engines/wintermute/base/font/base_font_truetype.h
index a93e4efacb..02dca7439f 100644
--- a/engines/wintermute/base/font/base_font_truetype.h
+++ b/engines/wintermute/base/font/base_font_truetype.h
@@ -1,152 +1,152 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This file is based on WME Lite.
- * http://dead-code.org/redir.php?target=wmelite
- * Copyright (c) 2011 Jan Nedoma
- */
-
-#ifndef WINTERMUTE_BASE_FONTTT_H
-#define WINTERMUTE_BASE_FONTTT_H
-
-#include "engines/wintermute/base/font/base_font_storage.h"
-#include "engines/wintermute/base/font/base_font.h"
-#include "engines/wintermute/base/gfx/base_surface.h"
-#include "common/rect.h"
-#include "graphics/surface.h"
-#include "graphics/font.h"
-
-#define NUM_CACHED_TEXTS 30
-
-namespace Wintermute {
-
-class BaseFontTT : public BaseFont {
-private:
- //////////////////////////////////////////////////////////////////////////
- class BaseCachedTTFontText {
- public:
- WideString _text;
- int _width;
- TTextAlign _align;
- int _maxHeight;
- int _maxLength;
- BaseSurface *_surface;
- int _priority;
- int _textOffset;
- bool _marked;
-
- BaseCachedTTFontText() {
- //_text = L"";
- _text = "";
- _width = _maxHeight = _maxLength = -1;
- _align = TAL_LEFT;
- _surface = NULL;
- _priority = -1;
- _textOffset = 0;
- _marked = false;
- }
-
- virtual ~BaseCachedTTFontText() {
- if (_surface) {
- delete _surface;
- }
- }
- };
-
-public:
- //////////////////////////////////////////////////////////////////////////
- class BaseTTFontLayer {
- public:
- BaseTTFontLayer() {
- _offsetX = _offsetY = 0;
- _color = 0x00000000;
- }
-
- bool persist(BasePersistenceManager *persistMgr) {
- persistMgr->transfer(TMEMBER(_offsetX));
- persistMgr->transfer(TMEMBER(_offsetY));
- persistMgr->transfer(TMEMBER(_color));
- return STATUS_OK;
- }
-
- int _offsetX;
- int _offsetY;
- uint32 _color;
- };
-
-public:
- DECLARE_PERSISTENT(BaseFontTT, BaseFont)
- BaseFontTT(BaseGame *inGame);
- virtual ~BaseFontTT(void);
-
- virtual int getTextWidth(byte *text, int maxLength = -1);
- virtual int getTextHeight(byte *text, int width);
- virtual void drawText(const byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int maxLength = -1);
- virtual int getLetterHeight();
-
- bool loadBuffer(byte *buffer);
- bool loadFile(const Common::String &filename);
-
- float getLineHeight() const {
- return _lineHeight;
- }
-
- void afterLoad();
- void initLoop();
-
-private:
- bool parseLayer(BaseTTFontLayer *layer, byte *buffer);
-
- void measureText(const WideString &text, int maxWidth, int maxHeight, int &textWidth, int &textHeight);
-
- BaseSurface *renderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset);
-
- BaseCachedTTFontText *_cachedTexts[NUM_CACHED_TEXTS];
-
- bool initFont();
-
- Graphics::Font *_deletableFont;
- const Graphics::Font *_font;
- const Graphics::Font *_fallbackFont;
-
- float _lineHeight;
-
- size_t _maxCharWidth;
- size_t _maxCharHeight;
-
-public:
- bool _isBold;
- bool _isItalic;
- bool _isUnderline;
- bool _isStriked;
- int _fontHeight;
- char *_fontFile;
-
- BaseArray<BaseTTFontLayer *> _layers;
- void clearCache();
-
-};
-
-} // end of namespace Wintermute
-
-#endif
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_BASE_FONTTT_H
+#define WINTERMUTE_BASE_FONTTT_H
+
+#include "engines/wintermute/base/font/base_font_storage.h"
+#include "engines/wintermute/base/font/base_font.h"
+#include "engines/wintermute/base/gfx/base_surface.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+#include "graphics/font.h"
+
+#define NUM_CACHED_TEXTS 30
+
+namespace Wintermute {
+
+class BaseFontTT : public BaseFont {
+private:
+ //////////////////////////////////////////////////////////////////////////
+ class BaseCachedTTFontText {
+ public:
+ WideString _text;
+ int _width;
+ TTextAlign _align;
+ int _maxHeight;
+ int _maxLength;
+ BaseSurface *_surface;
+ int _priority;
+ int _textOffset;
+ bool _marked;
+
+ BaseCachedTTFontText() {
+ //_text = L"";
+ _text = "";
+ _width = _maxHeight = _maxLength = -1;
+ _align = TAL_LEFT;
+ _surface = NULL;
+ _priority = -1;
+ _textOffset = 0;
+ _marked = false;
+ }
+
+ virtual ~BaseCachedTTFontText() {
+ if (_surface) {
+ delete _surface;
+ }
+ }
+ };
+
+public:
+ //////////////////////////////////////////////////////////////////////////
+ class BaseTTFontLayer {
+ public:
+ BaseTTFontLayer() {
+ _offsetX = _offsetY = 0;
+ _color = 0x00000000;
+ }
+
+ bool persist(BasePersistenceManager *persistMgr) {
+ persistMgr->transfer(TMEMBER(_offsetX));
+ persistMgr->transfer(TMEMBER(_offsetY));
+ persistMgr->transfer(TMEMBER(_color));
+ return STATUS_OK;
+ }
+
+ int _offsetX;
+ int _offsetY;
+ uint32 _color;
+ };
+
+public:
+ DECLARE_PERSISTENT(BaseFontTT, BaseFont)
+ BaseFontTT(BaseGame *inGame);
+ virtual ~BaseFontTT(void);
+
+ virtual int getTextWidth(byte *text, int maxLength = -1);
+ virtual int getTextHeight(byte *text, int width);
+ virtual void drawText(const byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int maxLength = -1);
+ virtual int getLetterHeight();
+
+ bool loadBuffer(byte *buffer);
+ bool loadFile(const Common::String &filename);
+
+ float getLineHeight() const {
+ return _lineHeight;
+ }
+
+ void afterLoad();
+ void initLoop();
+
+private:
+ bool parseLayer(BaseTTFontLayer *layer, byte *buffer);
+
+ void measureText(const WideString &text, int maxWidth, int maxHeight, int &textWidth, int &textHeight);
+
+ BaseSurface *renderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset);
+
+ BaseCachedTTFontText *_cachedTexts[NUM_CACHED_TEXTS];
+
+ bool initFont();
+
+ Graphics::Font *_deletableFont;
+ const Graphics::Font *_font;
+ const Graphics::Font *_fallbackFont;
+
+ float _lineHeight;
+
+ size_t _maxCharWidth;
+ size_t _maxCharHeight;
+
+public:
+ bool _isBold;
+ bool _isItalic;
+ bool _isUnderline;
+ bool _isStriked;
+ int _fontHeight;
+ char *_fontFile;
+
+ BaseArray<BaseTTFontLayer *> _layers;
+ void clearCache();
+
+};
+
+} // end of namespace Wintermute
+
+#endif