Initial commit
This commit is contained in:
252
engines/crab/text/TextManager.cpp
Normal file
252
engines/crab/text/TextManager.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/file.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/screen.h"
|
||||
#include "graphics/fonts/ttf.h"
|
||||
#include "crab/crab.h"
|
||||
#include "crab/GameParam.h"
|
||||
#include "crab/XMLDoc.h"
|
||||
#include "crab/text/TextManager.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::text;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Initialize, set cache etc
|
||||
//------------------------------------------------------------------------
|
||||
void TextManager::init() {
|
||||
// First, delete everything that exists
|
||||
quit();
|
||||
|
||||
// Load the list of fonts
|
||||
XMLDoc fontList(g_engine->_filePath->_font);
|
||||
if (fontList.ready()) {
|
||||
rapidxml::xml_node<char> *node = fontList.doc()->first_node("fonts");
|
||||
|
||||
loadNum(_cacheSize, "cache_size", node);
|
||||
_cache.resize(_cacheSize);
|
||||
_oldest = 0;
|
||||
|
||||
if (nodeValid(node->first_node("padding")))
|
||||
_padBg.load(node->first_node("padding"));
|
||||
|
||||
for (auto n = node->first_node("font"); n != nullptr; n = n->next_sibling("font")) {
|
||||
rapidxml::xml_attribute<char> *id, *path, *size;
|
||||
id = n->first_attribute("id");
|
||||
path = n->first_attribute("path");
|
||||
size = n->first_attribute("size");
|
||||
|
||||
if (id != nullptr && path != nullptr && size != nullptr) {
|
||||
uint pos = stringToNumber<uint>(id->value());
|
||||
if (_font.size() <= pos)
|
||||
_font.resize(pos + 1);
|
||||
Common::File *file = new Common::File();
|
||||
fileOpen(path->value(), file);
|
||||
_font[pos] = Graphics::loadTTFFont(file, DisposeAfterUse::YES, stringToNumber<int>(size->value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_colpool.load(g_engine->_filePath->_colors);
|
||||
}
|
||||
|
||||
void TextManager::reset() {
|
||||
_cache.clear();
|
||||
_cache.resize(_cacheSize);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Search cache for rendered text
|
||||
//------------------------------------------------------------------------
|
||||
int TextManager::search(const Common::String &text, int col, FontKey fontid) {
|
||||
int pos = 0;
|
||||
for (auto i = _cache.begin(); i != _cache.end(); ++i, ++pos)
|
||||
if (i->_empty == false && i->_text == text && i->EqualCol(col) && i->_font == fontid)
|
||||
return pos;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TextManager::findFreeSlot() {
|
||||
int pos = 0;
|
||||
for (auto i = _cache.begin(); i != _cache.end(); ++i, ++pos)
|
||||
if (i->_empty)
|
||||
return pos;
|
||||
|
||||
int ret = _oldest;
|
||||
_oldest = (_oldest + 1) % _cache.size();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Render the SDL surface for text
|
||||
//------------------------------------------------------------------------
|
||||
Graphics::ManagedSurface *TextManager::renderTextBlended(const FontKey &fKey, const Common::String &text, const int &color) {
|
||||
Color pooledColor = _colpool.get(color);
|
||||
uint32 col = g_engine->_format.ARGBToColor(255, pooledColor.r, pooledColor.g, pooledColor.b);
|
||||
|
||||
Graphics::ManagedSurface *surf = nullptr;
|
||||
|
||||
if (text.empty()) {
|
||||
Common::Rect rec = getFont(fKey)->getBoundingBox(" ");
|
||||
int h = rec.height();
|
||||
surf = new Graphics::ManagedSurface(rec.width(), h + (h / 2), g_engine->_format);
|
||||
getFont(fKey)->drawString(surf, " ", 0, 0, rec.width(), col);
|
||||
} else {
|
||||
Common::Rect rec = getFont(fKey)->getBoundingBox(text);
|
||||
int h = rec.height();
|
||||
surf = new Graphics::ManagedSurface(rec.width(), h + (h / 2), g_engine->_format);
|
||||
getFont(fKey)->drawString(surf, text, 0, 0, rec.width(), col);
|
||||
}
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Draw text
|
||||
//------------------------------------------------------------------------
|
||||
void TextManager::draw(const int &x, const int &y, const Common::String &text, const int &color,
|
||||
const FontKey &fontk, const Align &align, const bool &background) {
|
||||
if (text == " ") return;
|
||||
|
||||
int pos = search(text, color, fontk);
|
||||
if (pos == -1) {
|
||||
pos = findFreeSlot();
|
||||
Graphics::ManagedSurface *surf = renderTextBlended(fontk, text, color);
|
||||
_cache[pos]._img.deleteImage();
|
||||
_cache[pos]._empty = false;
|
||||
|
||||
_cache[pos]._text = text;
|
||||
_cache[pos]._col = color;
|
||||
_cache[pos]._font = fontk;
|
||||
|
||||
_cache[pos]._img.load(surf);
|
||||
|
||||
delete surf;
|
||||
}
|
||||
|
||||
if (background) {
|
||||
_rect.w = _cache[pos]._img.w() + (2 * _padBg.x);
|
||||
_rect.h = _cache[pos]._img.h() + (2 * _padBg.y);
|
||||
|
||||
uint32 col = g_engine->_format.ARGBToColor(128, 0, 0, 0);
|
||||
Graphics::Surface surf;
|
||||
surf.create(_rect.w, _rect.h, g_engine->_format);
|
||||
surf.fillRect(Common::Rect(_rect.w, _rect.h), col);
|
||||
|
||||
if (align == ALIGN_LEFT) {
|
||||
_rect.x = x - _padBg.x;
|
||||
_rect.y = y - _padBg.y;
|
||||
|
||||
g_engine->_screen->blitFrom(surf, Common::Point(_rect.x, _rect.y));
|
||||
|
||||
_cache[pos]._img.draw(x, y);
|
||||
} else if (align == ALIGN_CENTER) {
|
||||
_rect.x = x - _cache[pos]._img.w() / 2 - _padBg.x;
|
||||
_rect.y = y - _cache[pos]._img.h() / 2 - _padBg.y;
|
||||
|
||||
g_engine->_screen->blitFrom(surf, Common::Point(_rect.x, _rect.y));
|
||||
|
||||
_cache[pos]._img.draw(x - _cache[pos]._img.w() / 2, y - _cache[pos]._img.h() / 2);
|
||||
} else {
|
||||
_rect.x = x - _cache[pos]._img.w() - _padBg.x;
|
||||
_rect.y = y - _padBg.y;
|
||||
|
||||
g_engine->_screen->blitFrom(surf, Common::Point(_rect.x, _rect.y));
|
||||
|
||||
_cache[pos]._img.draw(x - _cache[pos]._img.w(), y);
|
||||
}
|
||||
|
||||
surf.free();
|
||||
|
||||
} else {
|
||||
if (align == ALIGN_LEFT)
|
||||
_cache[pos]._img.draw(x, y);
|
||||
else if (align == ALIGN_CENTER)
|
||||
_cache[pos]._img.draw(x - _cache[pos]._img.w() / 2, y - _cache[pos]._img.h() / 2);
|
||||
else
|
||||
_cache[pos]._img.draw(x - _cache[pos]._img.w(), y);
|
||||
}
|
||||
}
|
||||
|
||||
void TextManager::draw(const int &x, int y, const Common::String &text, const int &color, const FontKey &fKey, const Align &align,
|
||||
const uint &lineWidth, const uint &lineHeight, const bool &background) {
|
||||
for (uint startPos = 0, len = text.size(); startPos < len; y += lineHeight) {
|
||||
uint endPos = startPos + 1;
|
||||
int lastInterrupt = -1;
|
||||
Common::String word;
|
||||
|
||||
while (endPos - startPos <= lineWidth) {
|
||||
if (endPos == len || text[endPos] == '`') {
|
||||
lastInterrupt = endPos;
|
||||
break;
|
||||
}
|
||||
|
||||
if (text[endPos] == ' ' || text[endPos] == ',' || text[endPos] == '.')
|
||||
lastInterrupt = endPos;
|
||||
|
||||
endPos++;
|
||||
}
|
||||
|
||||
if (lastInterrupt >= 0) { // wrap a word around
|
||||
for (uint i = 0; i < lastInterrupt - startPos; i++)
|
||||
word += text[startPos + i];
|
||||
|
||||
startPos = lastInterrupt + 1;
|
||||
} else { // word bigger than line, just thunk
|
||||
for (uint i = 0; i < endPos - startPos; i++)
|
||||
word += text[startPos + i];
|
||||
|
||||
startPos += lineWidth;
|
||||
}
|
||||
|
||||
draw(x, y, word, color, fKey, align, background);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Quit
|
||||
//------------------------------------------------------------------------
|
||||
void TextManager::quit() {
|
||||
for (auto &i : _font)
|
||||
delete i;
|
||||
|
||||
for (auto &i : _cache) {
|
||||
if (i._empty == false) {
|
||||
i._img.deleteImage();
|
||||
i._empty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
130
engines/crab/text/TextManager.h
Normal file
130
engines/crab/text/TextManager.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_TEXTMANAGER_H
|
||||
#define CRAB_TEXTMANAGER_H
|
||||
|
||||
#include "crab/vectors.h"
|
||||
#include "crab/image/Image.h"
|
||||
#include "crab/text/color.h"
|
||||
|
||||
namespace Graphics {
|
||||
class Font;
|
||||
} // End of namespace Graphics
|
||||
|
||||
namespace Crab {
|
||||
|
||||
// We use this object as the key for all fonts
|
||||
typedef uint FontKey;
|
||||
|
||||
// Since we use uint as a key for images, our loadImgKey function is loadNum
|
||||
#define LoadFontKey loadNum
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace text {
|
||||
class TextManager {
|
||||
// The collection of stored fonts
|
||||
Common::Array<Graphics::Font *> _font;
|
||||
|
||||
// The size of the cache
|
||||
int _cacheSize;
|
||||
|
||||
// The padding at the end of the background - this needs to be loaded from file later
|
||||
Vector2i _padBg;
|
||||
|
||||
// The data stored in our cache - text and texture
|
||||
struct TextCacheUnit {
|
||||
Common::String _text;
|
||||
int _col;
|
||||
FontKey _font;
|
||||
|
||||
pyrodactyl::image::Image _img;
|
||||
bool _empty;
|
||||
|
||||
TextCacheUnit() {
|
||||
_empty = true;
|
||||
_col = 0;
|
||||
_font = 0;
|
||||
}
|
||||
~TextCacheUnit() {
|
||||
_img.deleteImage();
|
||||
}
|
||||
|
||||
bool EqualCol(int color) {
|
||||
return _col == color;
|
||||
}
|
||||
};
|
||||
|
||||
// Text Cache - done to avoid having to render a texture every time text is drawn
|
||||
Common::Array<TextCacheUnit> _cache;
|
||||
|
||||
// The oldest element in the text cache
|
||||
int _oldest;
|
||||
|
||||
// The place to store all colors
|
||||
ColorPool _colpool;
|
||||
|
||||
// The rectangle used to store the darkened rectangle coordinates
|
||||
Rect _rect;
|
||||
|
||||
int search(const Common::String &text, int col, FontKey fontid);
|
||||
int findFreeSlot();
|
||||
|
||||
public:
|
||||
TextManager() {
|
||||
_oldest = 0;
|
||||
_cacheSize = 30;
|
||||
}
|
||||
|
||||
~TextManager() {}
|
||||
|
||||
void init();
|
||||
void quit();
|
||||
void reset();
|
||||
|
||||
Graphics::Font *getFont(const FontKey &fontid) {
|
||||
return _font[fontid];
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *renderTextBlended(const FontKey &font, const Common::String &text, const int &color);
|
||||
|
||||
void draw(const int &x, const int &y, const Common::String &text, const int &color,
|
||||
const FontKey &font = 0, const Align &align = ALIGN_LEFT, const bool &background = false);
|
||||
|
||||
void draw(const int &x, int y, const Common::String &text, const int &color, const FontKey &font, const Align &align,
|
||||
const uint &lineWidth, const uint &lineHeight, const bool &background = false);
|
||||
};
|
||||
|
||||
} // End of namespace text
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_TEXTMANAGER_H
|
||||
58
engines/crab/text/color.cpp
Normal file
58
engines/crab/text/color.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "crab/XMLDoc.h"
|
||||
#include "crab/text/color.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::text;
|
||||
|
||||
void ColorPool::load(const Common::Path &filename) {
|
||||
_pool.clear();
|
||||
XMLDoc colList(filename);
|
||||
if (colList.ready()) {
|
||||
rapidxml::xml_node<char> *node = colList.doc()->first_node("colors");
|
||||
for (rapidxml::xml_node<char> *n = node->first_node("color"); n != nullptr; n = n->next_sibling("color")) {
|
||||
Color c;
|
||||
loadColor(c, n);
|
||||
_pool.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Color &ColorPool::get(const int &num) {
|
||||
if (_pool.size() <= static_cast<uint>(num))
|
||||
return _invalid;
|
||||
|
||||
return _pool[num];
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
67
engines/crab/text/color.h
Normal file
67
engines/crab/text/color.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_TEXTCOLOR_H
|
||||
#define CRAB_TEXTCOLOR_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "crab/loaders.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace text {
|
||||
// Storage pool for saving colors from one file, then using them
|
||||
|
||||
class ColorPool {
|
||||
|
||||
Common::Array<Color> _pool;
|
||||
|
||||
// Default invalid color
|
||||
Color _invalid;
|
||||
|
||||
public:
|
||||
ColorPool() {
|
||||
_pool.clear();
|
||||
_invalid.r = 255;
|
||||
_invalid.g = 0;
|
||||
_invalid.b = 220;
|
||||
_invalid.a = 255;
|
||||
}
|
||||
|
||||
Color &get(const int &num);
|
||||
void load(const Common::Path &filename);
|
||||
};
|
||||
} // End of namespace text
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_TEXTCOLOR_H
|
||||
Reference in New Issue
Block a user