aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics/text32.h
blob: d95792aa8db17f5a214d93ff4839f99c97207a29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/* 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.
 *
 */

#ifndef SCI_GRAPHICS_TEXT32_H
#define SCI_GRAPHICS_TEXT32_H

#include "sci/graphics/celobj32.h"
#include "sci/graphics/frameout.h"

namespace Sci {

enum TextAlign {
	kTextAlignLeft   = 0,
	kTextAlignCenter = 1,
	kTextAlignRight  = 2
};

/**
 * This class handles text calculation and rendering for
 * SCI32 games. The text calculation system in SCI32 is
 * nearly the same as SCI16, which means this class behaves
 * similarly. Notably, GfxText32 maintains drawing
 * parameters across multiple calls.
 */
class GfxText32 {
private:
	SegManager *_segMan;
	GfxCache *_cache;
	GfxScreen *_screen;

	/**
	 * The resource ID of the default font used by the game.
	 *
	 * @todo Check all SCI32 games to learn what their
	 * default font is.
	 */
	static int16 _defaultFontId;

	/**
	 * The width and height of the currently active text
	 * bitmap, in text-system coordinates.
	 *
	 * @note These are unsigned in the actual engine.
	 */
	int16 _width, _height;

	/**
	 * The color used to draw text.
	 */
	uint8 _foreColor;

	/**
	 * The background color of the text box.
	 */
	uint8 _backColor;

	/**
	 * The transparent color of the text box. Used when
	 * compositing the bitmap onto the screen.
	 */
	uint8 _skipColor;

	/**
	 * The rect where the text is drawn within the bitmap.
	 * This rect is clipped to the dimensions of the bitmap.
	 */
	Common::Rect _textRect;

	/**
	 * The text being drawn to the currently active text
	 * bitmap.
	 */
	Common::String _text;

	/**
	 * The font being used to draw the text.
	 */
	GuiResourceId _fontId;

	/**
	 * The color of the text box border.
	 */
	int16 _borderColor;

	/**
	 * TODO: Document
	 */
	bool _dimmed;

	/**
	 * The text alignment for the drawn text.
	 */
	TextAlign _alignment;

	/**
	 * The memory handle of the currently active bitmap.
	 */
	reg_t _bitmap;

	int16 _field_20;

	/**
	 * TODO: Document
	 */
	int16 _field_22;

	int _field_2C, _field_30, _field_34, _field_38;

	int16 _field_3C;

	/**
	 * The position of the text draw cursor.
	 */
	Common::Point _drawPosition;

	void drawFrame(const Common::Rect &rect, const int16 size, const uint8 color, const bool doScaling);
	void drawTextBox();
	void erase(const Common::Rect &rect, const bool doScaling);

	void drawChar(const uint8 charIndex);
	uint16 getCharWidth(const uint8 charIndex, const bool doScaling) const;
	void drawText(const uint index, uint length);

	inline int scaleUpWidth(int value) const {
		const int scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
		return (value * scriptWidth + _scaledWidth - 1) / _scaledWidth;
	}

	/**
	 * Gets the length of the longest run of text available
	 * within the currently loaded text, starting from the
	 * given `charIndex` and running for up to `maxWidth`
	 * pixels. Returns the number of characters that can be
	 * written, and mutates the value pointed to by
	 * `charIndex` to point to the index of the next
	 * character to render.
	 */
	uint getLongest(uint *charIndex, const int16 maxWidth);

	/**
	 * Gets the pixel width of a substring of the currently
	 * loaded text, without scaling.
	 */
	int16 getTextWidth(const uint index, uint length) const;

	/**
	 * Gets the pixel width of a substring of the currently
	 * loaded text, with scaling.
	 */
	int16 getTextWidth(const Common::String &text, const uint index, const uint length);

	inline Common::Rect scaleRect(const Common::Rect &rect) {
		Common::Rect scaledRect(rect);
		int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
		int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
		Ratio scaleX(_scaledWidth, scriptWidth);
		Ratio scaleY(_scaledHeight, scriptHeight);
		mul(scaledRect, scaleX, scaleY);
		return scaledRect;
	}

public:
	GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen);

	/**
	 * The size of the x-dimension of the coordinate system
	 * used by the text renderer.
	 */
	int16 _scaledWidth;

	/**
	 * The size of the y-dimension of the coordinate system
	 * used by the text renderer.
	 */
	int16 _scaledHeight;

	/**
	 * The currently active font resource used to write text
	 * into the bitmap.
	 *
	 * @note SCI engine builds the font table directly
	 * inside of FontMgr; we use GfxFont instead.
	 */
	GfxFont *_font;

	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, reg_t *outBitmapObject);

	reg_t createTitledFontBitmap(CelInfo32 &celInfo, Common::Rect &rect, Common::String &text, int16 foreColor, int16 backColor, int font, int16 skipColor, int16 borderColor, bool dimmed, void *unknown1);

	void disposeTextBitmap(reg_t hunkId);

	/**
	 * Sets the font to be used for rendering and
	 * calculation of text dimensions.
	 */
	void setFont(const GuiResourceId fontId);

	/**
	 * Retrieves the width and height of a block of text.
	 */
	Common::Rect getTextSize(const Common::String &text, const int16 maxWidth, bool doScaling);

	/**
	 * Retrieves the width of a line of text.
	 */
	int16 getStringWidth(const Common::String &text);
};

} // End of namespace Sci

#endif