1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef SCI_GRAPHICS_TEXT32_H 24 #define SCI_GRAPHICS_TEXT32_H 25 26 #include "sci/engine/state.h" 27 #include "sci/graphics/celobj32.h" 28 #include "sci/graphics/frameout.h" 29 #include "sci/graphics/helpers.h" 30 31 namespace Sci { 32 33 enum TextAlign { 34 kTextAlignDefault = -1, 35 kTextAlignLeft = 0, 36 kTextAlignCenter = 1, 37 kTextAlignRight = 2 38 }; 39 40 enum ScrollDirection { 41 kScrollUp, 42 kScrollDown 43 }; 44 45 class GfxFont; 46 47 /** 48 * This class handles text calculation and rendering for SCI32 games. The text 49 * calculation system in SCI32 is nearly the same as SCI16, which means this 50 * class behaves similarly. Notably, GfxText32 maintains drawing parameters 51 * across multiple calls, instead of requiring all text parameters to be 52 * provided on every draw call. 53 */ 54 class GfxText32 { 55 private: 56 SegManager *_segMan; 57 GfxCache *_cache; 58 59 /** 60 * The width and height of the currently active text bitmap, in text-system 61 * coordinates. 62 * 63 * @note These are unsigned in SSCI. 64 */ 65 int16 _width, _height; 66 67 /** 68 * The color used to draw text. 69 */ 70 uint8 _foreColor; 71 72 /** 73 * The background color of the text box. 74 */ 75 uint8 _backColor; 76 77 /** 78 * The transparent color of the text box. Used when compositing the bitmap 79 * onto the screen. 80 */ 81 uint8 _skipColor; 82 83 /** 84 * The rect where the text is drawn within the bitmap. This rect is clipped 85 * to the dimensions of the bitmap. 86 */ 87 Common::Rect _textRect; 88 89 /** 90 * The text being drawn to the currently active text bitmap. 91 */ 92 Common::String _text; 93 94 /** 95 * The font being used to draw the text. 96 */ 97 GuiResourceId _fontId; 98 99 /** 100 * The color of the text box border. 101 */ 102 int16 _borderColor; 103 104 /** 105 * If true, text will be drawn using a dither that draws only every other 106 * pixel of the text. 107 */ 108 bool _dimmed; 109 110 /** 111 * The text alignment for the drawn text. 112 */ 113 TextAlign _alignment; 114 115 /** 116 * The position of the text draw cursor. 117 */ 118 Common::Point _drawPosition; 119 120 void drawFrame(const Common::Rect &rect, const int16 size, const uint8 color, const bool doScaling); 121 122 void drawChar(const char charIndex); 123 void drawText(const uint index, uint length); 124 125 /** 126 * Gets the length of the longest run of text available within the currently 127 * loaded text, starting from the given `charIndex` and running for up to 128 * `maxWidth` pixels. Returns the number of characters that can be written, 129 * and mutates the value pointed to by `charIndex` to point to the index of 130 * the next character to render. 131 */ 132 uint getLongest(uint *charIndex, const int16 maxWidth); 133 134 /** 135 * Gets the pixel width of a substring of the currently loaded text, without 136 * scaling. 137 */ 138 int16 getTextWidth(const uint index, uint length) const; 139 scaleRect(const Common::Rect & rect)140 inline Common::Rect scaleRect(const Common::Rect &rect) { 141 Common::Rect scaledRect(rect); 142 const int16 scriptWidth = g_sci->_gfxFrameout->getScriptWidth(); 143 const int16 scriptHeight = g_sci->_gfxFrameout->getScriptHeight(); 144 const Ratio scaleX(_xResolution, scriptWidth); 145 const Ratio scaleY(_yResolution, scriptHeight); 146 mulinc(scaledRect, scaleX, scaleY); 147 return scaledRect; 148 } 149 150 public: 151 GfxText32(SegManager *segMan, GfxCache *fonts); 152 153 /** 154 * Initialises static GfxText32 members. 155 */ 156 static void init(); 157 158 /** 159 * The memory handle of the currently active bitmap. 160 */ 161 reg_t _bitmap; 162 163 /** 164 * The size of the x-dimension of the coordinate system used by the text 165 * renderer. Static since it was global in SSCI. 166 */ 167 static int16 _xResolution; 168 169 /** 170 * The size of the y-dimension of the coordinate system used by the text 171 * renderer. Static since it was global in SSCI. 172 */ 173 static int16 _yResolution; 174 175 /** 176 * The currently active font resource used to write text into the bitmap. 177 * 178 * @note SSCI builds the font table directly inside of FontMgr; we use 179 * GfxFont instead. 180 */ 181 GfxFont *_font; 182 183 /** 184 * Creates a plain font bitmap with a flat color background. 185 */ 186 reg_t createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, TextAlign alignment, const int16 borderColor, bool dimmed, const bool doScaling, const bool gc); 187 188 /** 189 * Creates a font bitmap with a view background. 190 */ 191 reg_t createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, const bool gc); 192 scaleUpWidth(int value)193 inline int scaleUpWidth(int value) const { 194 const int scriptWidth = g_sci->_gfxFrameout->getScriptWidth(); 195 return (value * scriptWidth + _xResolution - 1) / _xResolution; 196 } 197 scaleUpHeight(int value)198 inline int scaleUpHeight(int value) const { 199 const int scriptHeight = g_sci->_gfxFrameout->getScriptHeight(); 200 return (value * scriptHeight + _yResolution - 1) / _yResolution; 201 } 202 203 /** 204 * Draws the text to the bitmap. 205 */ 206 void drawTextBox(); 207 208 /** 209 * Draws the given text to the bitmap. 210 * 211 * @note SSCI holds a reference to a shared string which lets the text be 212 * updated from outside of the font manager. Instead, we use this extra 213 * signature to send the text to draw. 214 */ 215 void drawTextBox(const Common::String &text); 216 217 /** 218 * Erases the given rect by filling with the background color. 219 */ 220 void erase(const Common::Rect &rect, const bool doScaling); 221 222 void invertRect(const reg_t bitmap, const int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling); 223 224 /** 225 * Sets the font to be used for rendering and calculation of text 226 * dimensions. 227 */ 228 void setFont(const GuiResourceId fontId); 229 230 /** 231 * Gets the pixel height of the currently loaded font. 232 */ 233 int16 getScaledFontHeight() const; 234 235 /** 236 * Gets the width of a character. 237 */ 238 uint16 getCharWidth(const char charIndex, const bool doScaling) const; 239 240 /** 241 * Retrieves the width and height of a block of text. 242 */ 243 Common::Rect getTextSize(const Common::String &text, const int16 maxWidth, bool doScaling); 244 245 /** 246 * Gets the pixel width of a substring of the currently loaded text, with 247 * scaling. 248 */ 249 int16 getTextWidth(const Common::String &text, const uint index, const uint length); 250 251 /** 252 * Retrieves the width of a line of text. 253 */ 254 int16 getStringWidth(const Common::String &text); 255 256 /** 257 * Gets the number of characters of `text`, starting from `index`, that can 258 * be safely rendered into `textRect`. 259 */ 260 int16 getTextCount(const Common::String &text, const uint index, const Common::Rect &textRect, const bool doScaling); 261 262 /** 263 * Gets the number of characters of `text`, starting from `index`, that can 264 * be safely rendered into `textRect` using the given font. 265 */ 266 int16 getTextCount(const Common::String &text, const uint index, const GuiResourceId fontId, const Common::Rect &textRect, const bool doScaling); 267 268 /** 269 * Scroll up/down one line. `numLines` is the number of the lines in the 270 * textarea, and `textLine` contains the text to draw as the newly visible 271 * line. Originally FontMgr::DrawOneLine and FontMgr::UpOneLine. 272 */ 273 void scrollLine(const Common::String &textLine, int numLines, uint8 color, TextAlign align, GuiResourceId fontId, ScrollDirection dir); 274 }; 275 276 } // End of namespace Sci 277 278 #endif 279