ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

text.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/visual/text.h"
00024 
00025 #include "graphics/font.h"
00026 #include "graphics/pixelformat.h"
00027 #include "graphics/surface.h"
00028 
00029 #include "engines/stark/debug.h"
00030 #include "engines/stark/gfx/driver.h"
00031 #include "engines/stark/gfx/surfacerenderer.h"
00032 #include "engines/stark/gfx/texture.h"
00033 #include "engines/stark/scene.h"
00034 #include "engines/stark/services/services.h"
00035 #include "engines/stark/services/settings.h"
00036 
00037 #include "common/util.h"
00038 
00039 namespace Stark {
00040 
00041 VisualText::VisualText(Gfx::Driver *gfx) :
00042         Visual(TYPE),
00043         _gfx(gfx),
00044         _texture(nullptr),
00045         _color(Color(0, 0, 0)),
00046         _backgroundColor(Color(0, 0, 0, 0)),
00047         _align(Graphics::kTextAlignLeft),
00048         _targetWidth(600),
00049         _targetHeight(600),
00050         _fontType(FontProvider::kBigFont),
00051         _fontCustomIndex(-1) {
00052     _surfaceRenderer = _gfx->createSurfaceRenderer();
00053     _surfaceRenderer->setNoScalingOverride(true);
00054 }
00055 
00056 VisualText::~VisualText() {
00057     freeTexture();
00058     delete _surfaceRenderer;
00059 }
00060 
00061 Common::Rect VisualText::getRect() {
00062     if (!_texture) {
00063         createTexture();
00064     }
00065     return _originalRect;
00066 }
00067 
00068 void VisualText::setText(const Common::String &text) {
00069     if (_text != text) {
00070         freeTexture();
00071         _text = text;
00072     }
00073 }
00074 
00075 void VisualText::setColor(const Color &color) {
00076     if (_color == color) {
00077         return;
00078     }
00079 
00080     freeTexture();
00081     _color = color;
00082 }
00083 
00084 void VisualText::setBackgroundColor(const Color &color) {
00085     if (color == _backgroundColor) {
00086         return;
00087     }
00088 
00089     freeTexture();
00090     _backgroundColor = color;
00091 }
00092 
00093 void VisualText::setAlign(Graphics::TextAlign align) {
00094     if (align != _align) {
00095         freeTexture();
00096         _align = align;
00097     }
00098 }
00099 
00100 void VisualText::setTargetWidth(uint32 width) {
00101     if (width != _targetWidth) {
00102         freeTexture();
00103         _targetWidth = width;
00104     }
00105 }
00106 
00107 void VisualText::setTargetHeight(uint32 height) {
00108     if (height != _targetHeight) {
00109         freeTexture();
00110         _targetHeight = height;
00111     }
00112 }
00113 
00114 void VisualText::setFont(FontProvider::FontType type, int32 customFontIndex) {
00115     if (type != _fontType || customFontIndex != _fontCustomIndex) {
00116         freeTexture();
00117         _fontType = type;
00118         _fontCustomIndex = customFontIndex;
00119     }
00120 }
00121 
00122 void VisualText::createTexture() {
00123     Common::CodePage codePage = StarkSettings->getTextCodePage();
00124     Common::U32String unicodeText = Common::convertToU32String(_text.c_str(), codePage);
00125 
00126     // Get the font and required metrics
00127     const Graphics::Font *font = StarkFontProvider->getScaledFont(_fontType, _fontCustomIndex);
00128     uint scaledLineHeight = StarkFontProvider->getScaledFontHeight(_fontType, _fontCustomIndex);
00129     uint originalLineHeight = StarkFontProvider->getOriginalFontHeight(_fontType, _fontCustomIndex);
00130     uint maxScaledLineWidth = StarkGfx->scaleWidthOriginalToCurrent(_targetWidth);
00131 
00132     // Word wrap the text
00133     Common::Array<Common::U32String> lines;
00134     font->wordWrapText(unicodeText, maxScaledLineWidth, lines);
00135 
00136     // Use the actual font bounding box to prevent text from being cut off
00137     Common::Rect scaledRect;
00138     if (!lines.empty()) {
00139         scaledRect = font->getBoundingBox(lines[0]);
00140         for (uint i = 1; i < lines.size(); i++) {
00141             scaledRect.extend(font->getBoundingBox(lines[i], 0, scaledLineHeight * i));
00142         }
00143     }
00144 
00145     // Make sure lines have approximately consistent height regardless of the characters they use
00146     scaledRect.bottom = MAX<int16>(scaledRect.bottom, scaledLineHeight * lines.size());
00147 
00148     if (!isBlank()) {
00149         _originalRect.right = StarkGfx->scaleWidthCurrentToOriginal(scaledRect.right);
00150         _originalRect.bottom = originalLineHeight * lines.size();
00151     } else {
00152         // For Empty text, preserve the original width and height for being used as clicking area
00153         _originalRect.right = _targetWidth;
00154         _originalRect.bottom = _targetHeight;
00155     }
00156 
00157     // Create a surface to render to
00158     Graphics::Surface surface;
00159     surface.create(scaledRect.right, scaledRect.bottom, Gfx::Driver::getRGBAPixelFormat());
00160 
00161     uint32 color = surface.format.ARGBToColor(
00162             _color.a, _color.r, _color.g, _color.b
00163     );
00164     uint32 bgColor = surface.format.ARGBToColor(
00165             _backgroundColor.a, _backgroundColor.r, _backgroundColor.g, _backgroundColor.b
00166     );
00167 
00168     surface.fillRect(Common::Rect(surface.w, surface.h), bgColor);
00169 
00170     // Render the lines to the surface
00171     for (uint i = 0; i < lines.size(); i++) {
00172         font->drawString(&surface, lines[i], 0, scaledLineHeight * i, surface.w, color, _align);
00173     }
00174 
00175     // Create a texture from the surface
00176     _texture = _gfx->createTexture(&surface);
00177     _texture->setSamplingFilter(Gfx::Texture::kNearest);
00178 
00179     surface.free();
00180 }
00181 
00182 void VisualText::freeTexture() {
00183     delete _texture;
00184     _texture = nullptr;
00185 }
00186 
00187 void VisualText::render(const Common::Point &position) {
00188     if (!_texture) {
00189         createTexture();
00190     }
00191 
00192     _surfaceRenderer->render(_texture, position);
00193 }
00194 
00195 void VisualText::resetTexture() {
00196     freeTexture();
00197 }
00198 
00199 bool VisualText::isBlank() {
00200     for (uint i = 0; i < _text.size(); ++i) {
00201         if (!Common::isSpace(_text[i])) {
00202             return false;
00203         }
00204     }
00205     return true;
00206 }
00207 
00208 } // End of namespace Stark


Generated on Sat Feb 16 2019 05:01:08 for ResidualVM by doxygen 1.7.1
curved edge   curved edge