diff options
author | Willem Jan Palenstijn | 2012-09-04 22:17:23 +0200 |
---|---|---|
committer | Willem Jan Palenstijn | 2012-09-04 22:17:23 +0200 |
commit | b4090ead4d4334e08725323ff72fd355c93b63d5 (patch) | |
tree | 4eb58e5698b1cfd1a89d2b038f929071264ffeb9 /engines/wintermute/base/font | |
parent | df80820184c90a87511f0cabdca4addb9fa13a66 (diff) | |
download | scummvm-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.cpp | 280 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font.h | 122 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font_bitmap.cpp | 1178 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font_bitmap.h | 142 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font_storage.cpp | 284 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font_storage.h | 110 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font_truetype.cpp | 1210 | ||||
-rw-r--r-- | engines/wintermute/base/font/base_font_truetype.h | 304 |
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 **)¶ms) == 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 **)¶ms) == 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 **)¶ms) != 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 **)¶ms)) > 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 **)¶ms) != 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 **)¶ms)) > 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 **)¶ms) != 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 **)¶ms)) > 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 **)¶ms)) > 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 **)¶ms) != 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 **)¶ms)) > 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 **)¶ms)) > 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 |