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 VECTOR_RENDERER_H
24 #define VECTOR_RENDERER_H
25 
26 #include "common/rect.h"
27 #include "common/scummsys.h"
28 #include "common/str.h"
29 
30 #include "graphics/managed_surface.h"
31 
32 #include "gui/ThemeEngine.h"
33 
34 class OSystem;
35 
36 namespace Graphics {
37 class VectorRenderer;
38 struct DrawStep;
39 
40 /**
41  * @defgroup graphics_vector_renderer Vector renderer
42  * @ingroup graphics
43  *
44  * @brief VectorRenderer for drawing on a given surface.
45  *
46  * @{
47  */
48 
49 typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, const Graphics::DrawStep &);
50 
51 
52 struct DrawStep {
53 	DrawingFunctionCallback drawingCall; /**< Pointer to drawing function */
54 	Graphics::ManagedSurface *blitSrc;
55 
56 	struct Color {
57 		uint8 r, g, b;
58 		bool set;
59 
ColorDrawStep::Color60 		Color () : r(0), g(0), b(0), set(false) {}
61 	};
62 	Color fgColor; /**< Foreground color */
63 	Color bgColor; /**< background color */
64 	Color gradColor1; /**< gradient start*/
65 	Color gradColor2; /**< gradient end */
66 	Color bevelColor;
67 
68 	bool autoWidth, autoHeight;
69 	int16 x, y, w, h; /**< width, height and position, if not measured automatically.
70 						  negative values mean counting from the opposite direction */
71 
72 	Common::Rect padding;
73 	Common::Rect clip; /**< Clipping rect restriction */
74 
75 	enum VectorAlignment {
76 		kVectorAlignManual,
77 		kVectorAlignLeft,
78 		kVectorAlignRight,
79 		kVectorAlignBottom,
80 		kVectorAlignTop,
81 		kVectorAlignCenter
82 	};
83 
84 	VectorAlignment xAlign;
85 	VectorAlignment yAlign;
86 
87 	uint8 shadow, stroke, factor, radius, bevel; /**< Misc options... */
88 
89 	uint8 fillMode; /**< active fill mode */
90 	uint8 shadowFillMode; /**< fill mode of the shadow used */
91 
92 	uint32 extraData; /**< Generic parameter for extra options (orientation/bevel) */
93 
94 	uint32 scale; /**< scale of all the coordinates in FIXED POINT with 16 bits mantissa */
95 
96 	GUI::ThemeEngine::AutoScaleMode autoscale; /**< scale alphaimage if present */
97 
DrawStepDrawStep98 	DrawStep() {
99 		drawingCall = nullptr;
100 		blitSrc = nullptr;
101 		// fgColor, bgColor, gradColor1, gradColor2, bevelColor initialized by Color default constructor
102 		autoWidth = autoHeight = false;
103 		x = y = w = h = 0;
104 		// padding initialized by Common::Rect default constructor
105 		xAlign = yAlign = kVectorAlignManual;
106 		shadow = stroke = factor = radius = bevel = 0;
107 		fillMode = 0;
108 		shadowFillMode = 0;
109 		extraData = 0;
110 		scale = 0;
111 		autoscale = GUI::ThemeEngine::kAutoScaleNone;
112 	}
113 };
114 
115 VectorRenderer *createRenderer(int mode);
116 
117 /**
118  * VectorRenderer: The core Vector Renderer Class
119  *
120  * This virtual class exposes the API with all the vectorial
121  * rendering functions that may be used to draw on a given Surface.
122  *
123  * This class must be instantiated as one of its children, which implement
124  * the actual rendering functionality for each Byte Depth / Byte Format
125  * combination, and may also contain platform specific code.
126  *
127  * When specifying define DISABLE_FANCY_THEMES eye candy related code
128  * gets stripped off. This is especially useful for small devices like NDS.
129  *
130  * TODO: Expand documentation.
131  *
132  * @see VectorRendererSpec
133  * @see VectorRendererAA
134  */
135 class VectorRenderer {
136 public:
VectorRenderer()137 	VectorRenderer() : _activeSurface(NULL), _fillMode(kFillDisabled), _shadowOffset(0), _shadowFillMode(kShadowExponential),
138 		_disableShadows(false), _strokeWidth(1), _gradientFactor(1), _bevel(0), _dynamicData(0) {
139 
140 	}
141 
~VectorRenderer()142 	virtual ~VectorRenderer() {}
143 
144 	/** Specifies the way in which a shape is filled */
145 	enum FillMode {
146 		kFillDisabled = 0,
147 		kFillForeground = 1,
148 		kFillBackground = 2,
149 		kFillGradient = 3
150 	};
151 
152 	enum TriangleOrientation {
153 		kTriangleAuto = 0,
154 		kTriangleUp,
155 		kTriangleDown,
156 		kTriangleLeft,
157 		kTriangleRight
158 	};
159 
160 	enum ShadowFillMode {
161 		kShadowLinear = 0,
162 		kShadowExponential = 1
163 	};
164 
165 	/**
166 	 * Draws a line by considering the special cases for optimization.
167 	 *
168 	 * @param x1 Horizontal (X) coordinate for the line start
169 	 * @param x2 Horizontal (X) coordinate for the line end
170 	 * @param y1 Vertical (Y) coordinate for the line start
171 	 * @param y2 Vertical (Y) coordinate for the line end
172 	 */
173 	virtual void drawLine(int x1, int y1, int x2, int y2) = 0;
174 
175 	/**
176 	 * Draws a circle centered at (x,y) with radius r.
177 	 *
178 	 * @param x Horizontal (X) coordinate for the center of the circle
179 	 * @param y Vertical (Y) coordinate for the center of the circle
180 	 * @param r Radius of the circle.
181 	 */
182 	virtual void drawCircle(int x, int y, int r) = 0;
183 
184 	/**
185 	 * Draws a square starting at (x,y) with the given width and height.
186 	 *
187 	 * @param x Horizontal (X) coordinate for the center of the square
188 	 * @param y Vertical (Y) coordinate for the center of the square
189 	 * @param w Width of the square.
190 	 * @param h Height of the square
191 	 */
192 	virtual void drawSquare(int x, int y, int w, int h) = 0;
193 
194 	/**
195 	 * Draws a rounded square starting at (x,y) with the given width and height.
196 	 * The corners of the square are rounded with the given radius.
197 	 *
198 	 * @param x Horizontal (X) coordinate for the center of the square
199 	 * @param y Vertical (Y) coordinate for the center of the square
200 	 * @param w Width of the square.
201 	 * @param h Height of the square
202 	 * @param r Radius of the corners.
203 	 */
204 	virtual void drawRoundedSquare(int x, int y, int r, int w, int h) = 0;
205 
206 	/**
207 	 * Draws a triangle starting at (x,y) with the given base and height.
208 	 * The triangle will always be isosceles, with the given base and height.
209 	 * The orientation parameter controls the position of the base of the triangle.
210 	 *
211 	 * @param x Horizontal (X) coordinate for the top left corner of the triangle
212 	 * @param y Vertical (Y) coordinate for the top left corner of the triangle
213 	 * @param base Width of the base of the triangle
214 	 * @param height Height of the triangle
215 	 * @param orient Orientation of the triangle.
216 	 */
217 	virtual void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient) = 0;
218 
219 	/**
220 	 * Draws a beveled square like the ones in the Classic GUI themes.
221 	 * Beveled squares are always drawn with a transparent background. Draw them on top
222 	 * of a standard square to fill it.
223 	 *
224 	 * @param x Horizontal (X) coordinate for the center of the square
225 	 * @param y Vertical (Y) coordinate for the center of the square
226 	 * @param w Width of the square.
227 	 * @param h Height of the square
228 	 * @param bevel Amount of bevel. Must be positive.
229 	 */
230 	virtual void drawBeveledSquare(int x, int y, int w, int h) = 0;
231 
232 	/**
233 	 * Draws a tab-like shape, specially thought for the Tab widget.
234 	 * If a radius is given, the tab will have rounded corners. Otherwise,
235 	 * the tab will be squared.
236 	 *
237 	 * @param x Horizontal (X) coordinate for the tab
238 	 * @param y Vertical (Y) coordinate for the tab
239 	 * @param w Width of the tab
240 	 * @param h Height of the tab
241 	 * @param r Radius of the corners of the tab (0 for squared tabs).
242 	 * @param s Shadow size
243 	 */
244 	virtual void drawTab(int x, int y, int r, int w, int h, int s) = 0;
245 
246 	/**
247 	 * Simple helper function to draw a cross.
248 	 */
drawCross(int x,int y,int w,int h)249 	virtual void drawCross(int x, int y, int w, int h) {
250 		drawLine(x, y, x + w, y + w);
251 		drawLine(x + w, y, x, y + h);
252 	}
253 
254 	/**
255 	 * Set the active foreground painting color for the renderer.
256 	 * All the foreground drawing from then on will be done with that color, unless
257 	 * specified otherwise.
258 	 *
259 	 * Foreground drawing means all outlines and basic shapes.
260 	 *
261 	 * @param r	value of the red color byte
262 	 * @param g	value of the green color byte
263 	 * @param b	value of the blue color byte
264 	 */
265 	virtual void setFgColor(uint8 r, uint8 g, uint8 b) = 0;
266 
267 	/**
268 	 * Set the active background painting color for the renderer.
269 	 * All the background drawing from then on will be done with that color, unless
270 	 * specified otherwise.
271 	 *
272 	 * Background drawing means all the shape filling.
273 	 *
274 	 * @param r	value of the red color byte
275 	 * @param g	value of the green color byte
276 	 * @param b	value of the blue color byte
277 	 */
278 	virtual void setBgColor(uint8 r, uint8 g, uint8 b) = 0;
279 
280 	virtual void setBevelColor(uint8 r, uint8 g, uint8 b) = 0;
281 
282 	/**
283 	 * Set the active gradient color. All shapes drawn using kFillGradient
284 	 * as their fill mode will use this VERTICAL gradient as their fill color.
285 	 *
286 	 * @param r1	value of the red color byte for the start color
287 	 * @param g1	value of the green color byte for the start color
288 	 * @param b1	value of the blue color byte for the start color
289 	 * @param r2	value of the red color byte for the end color
290 	 * @param g2	value of the green color byte for the end color
291 	 * @param b2	value of the blue color byte for the end color
292 	 */
293 	virtual void setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) = 0;
294 
295 	/**
296 	 * Sets the active drawing surface. All drawing from this
297 	 * point on will be done on that surface.
298 	 *
299 	 * @param surface Pointer to a Surface object.
300 	 */
setSurface(ManagedSurface * surface)301 	virtual void setSurface(ManagedSurface *surface) {
302 		_activeSurface = surface;
303 	}
304 
305 	/**
306 	 * Returns the currently active drawing surface
307 	 */
getActiveSurface()308 	virtual ManagedSurface *getActiveSurface() {
309 		return _activeSurface;
310 	}
311 
312 	/**
313 	 * Fills the active surface with the specified fg/bg color or the active gradient.
314 	 * Defaults to using the active Foreground color for filling.
315 	 */
316 	virtual void fillSurface() = 0;
317 
318 	/**
319 	 * Clears the active surface.
320 	 */
clearSurface()321 	virtual void clearSurface() {
322 		byte *src = (byte *)_activeSurface->getPixels();
323 		memset(src, 0, _activeSurface->pitch * _activeSurface->h);
324 	}
325 
326 	/**
327 	 * Sets the active fill mode for all shapes.
328 	 *
329 	 * @see VectorRenderer::FillMode
330 	 * @param mode Specified fill mode.
331 	 */
setFillMode(FillMode mode)332 	virtual void setFillMode(FillMode mode) {
333 		_fillMode = mode;
334 	}
335 
setShadowFillMode(ShadowFillMode mode)336 	virtual void setShadowFillMode(ShadowFillMode mode) {
337 		_shadowFillMode = mode;
338 	}
339 
340 	/**
341 	 * Sets the stroke width. All shapes drawn with a stroke will
342 	 * have that width. Pass 0 to disable shape stroking.
343 	 *
344 	 * @param width Width of the stroke in pixels.
345 	 */
setStrokeWidth(int width)346 	virtual void setStrokeWidth(int width) {
347 		_strokeWidth = width;
348 	}
349 
350 	/**
351 	 * Enables adding shadows to all drawn primitives.
352 	 * Shadows are drawn automatically under the shapes. The given offset
353 	 * controls their intensity and size (the higher the offset, the
354 	 * bigger the shadows). If the offset is 0, no shadows are drawn.
355 	 *
356 	 * @param offset Shadow offset.
357 	 */
setShadowOffset(int offset)358 	virtual void setShadowOffset(int offset) {
359 		if (offset >= 0)
360 			_shadowOffset = offset;
361 	}
362 
setBevel(int amount)363 	virtual void setBevel(int amount) {
364 		if (amount >= 0)
365 			_bevel = amount;
366 	}
367 
368 	/**
369 	 * Sets the multiplication factor of the active gradient.
370 	 *
371 	 * @see _gradientFactor
372 	 * @param factor Multiplication factor.
373 	 */
setGradientFactor(int factor)374 	virtual void setGradientFactor(int factor) {
375 		if (factor > 0)
376 			_gradientFactor = factor;
377 	}
378 
379 	/**
380 	 * Sets the clipping rectangle to be used by draw calls.
381 	 *
382 	 * Draw calls are restricted to pixels that are inside of the clipping
383 	 * rectangle. Pixels outside the clipping rectangle are not modified.
384 	 * To disable the clipping rectangle, call this method with a rectangle
385 	 * the same size as the target surface.
386 	 */
387 	virtual void setClippingRect(const Common::Rect &clippingArea) = 0;
388 
389 	/**
390 	 * Translates the position data inside a DrawStep into actual
391 	 * screen drawing positions.
392 	 */
393 	void stepGetPositions(const DrawStep &step, const Common::Rect &area, uint16 &in_x, uint16 &in_y, uint16 &in_w, uint16 &in_h);
394 
395 	/**
396 	 * Translates the radius data inside a drawstep into the real radius
397 	 * for the shape. Used for automatic radius calculations.
398 	 */
399 	int stepGetRadius(const DrawStep &step, const Common::Rect &area);
400 
401 	/**
402 	 * Restrict a draw call clipping rect with a step specific clipping rect
403 	 */
404 	Common::Rect applyStepClippingRect(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step);
405 
406 	/**
407 	 * DrawStep callback functions for each drawing feature
408 	 */
drawCallback_CIRCLE(const Common::Rect & area,const DrawStep & step)409 	void drawCallback_CIRCLE(const Common::Rect &area, const DrawStep &step) {
410 		uint16 x, y, w, h, radius;
411 
412 		radius = stepGetRadius(step, area);
413 		stepGetPositions(step, area, x, y, w, h);
414 
415 		drawCircle(x + radius, y + radius, radius);
416 	}
417 
drawCallback_SQUARE(const Common::Rect & area,const DrawStep & step)418 	void drawCallback_SQUARE(const Common::Rect &area, const DrawStep &step) {
419 		uint16 x, y, w, h;
420 		stepGetPositions(step, area, x, y, w, h);
421 		drawSquare(x, y, w, h);
422 	}
423 
drawCallback_LINE(const Common::Rect & area,const DrawStep & step)424 	void drawCallback_LINE(const Common::Rect &area, const DrawStep &step) {
425 		uint16 x, y, w, h;
426 		stepGetPositions(step, area, x, y, w, h);
427 		drawLine(x, y, x + w, y + h);
428 	}
429 
drawCallback_ROUNDSQ(const Common::Rect & area,const DrawStep & step)430 	void drawCallback_ROUNDSQ(const Common::Rect &area, const DrawStep &step) {
431 		uint16 x, y, w, h;
432 		stepGetPositions(step, area, x, y, w, h);
433 		drawRoundedSquare(x, y, stepGetRadius(step, area), w, h);
434 	}
435 
drawCallback_FILLSURFACE(const Common::Rect & area,const DrawStep & step)436 	void drawCallback_FILLSURFACE(const Common::Rect &area, const DrawStep &step) {
437 		fillSurface();
438 	}
439 
drawCallback_TRIANGLE(const Common::Rect & area,const DrawStep & step)440 	void drawCallback_TRIANGLE(const Common::Rect &area, const DrawStep &step) {
441 		uint16 x, y, w, h;
442 		stepGetPositions(step, area, x, y, w, h);
443 		drawTriangle(x, y, w, h, (TriangleOrientation)step.extraData);
444 	}
445 
drawCallback_BEVELSQ(const Common::Rect & area,const DrawStep & step)446 	void drawCallback_BEVELSQ(const Common::Rect &area, const DrawStep &step) {
447 		uint16 x, y, w, h;
448 		stepGetPositions(step, area, x, y, w, h);
449 		drawBeveledSquare(x, y, w, h);
450 	}
451 
drawCallback_TAB(const Common::Rect & area,const DrawStep & step)452 	void drawCallback_TAB(const Common::Rect &area, const DrawStep &step) {
453 		uint16 x, y, w, h;
454 		stepGetPositions(step, area, x, y, w, h);
455 		drawTab(x, y, stepGetRadius(step, area), w, h, step.shadow);
456 	}
457 
drawCallback_BITMAP(const Common::Rect & area,const DrawStep & step)458 	void drawCallback_BITMAP(const Common::Rect &area, const DrawStep &step) {
459 		uint16 x, y, w, h;
460 		stepGetPositions(step, area, x, y, w, h);
461 		blitKeyBitmap(step.blitSrc, Common::Point(x, y), true);
462 	}
463 
drawCallback_CROSS(const Common::Rect & area,const DrawStep & step)464 	void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step) {
465 		uint16 x, y, w, h;
466 		stepGetPositions(step, area, x, y, w, h);
467 		drawCross(x, y, w, h);
468 	}
469 
drawCallback_VOID(const Common::Rect & area,const DrawStep & step)470 	void drawCallback_VOID(const Common::Rect &area, const DrawStep &step) {}
471 
472 	/**
473 	 * Draws the specified draw step on the screen.
474 	 *
475 	 * @see DrawStep
476 	 * @param area Zone to paint on
477 	 * @param step Pointer to a DrawStep struct.
478 	 */
479 	virtual void drawStep(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step, uint32 extra = 0);
480 
481 	/**
482 	 * Copies the part of the current frame to the system overlay.
483 	 *
484 	 * @param sys Pointer to the global System class
485 	 * @param r Zone of the surface to copy into the overlay.
486 	 */
487 	virtual void copyFrame(OSystem *sys, const Common::Rect &r) = 0;
488 
489 	/**
490 	 * Copies the current surface to the system overlay
491 	 *
492 	 * @param sys Pointer to the global System class
493 	 */
494 	virtual void copyWholeFrame(OSystem *sys) = 0;
495 
496 	/**
497 	 * Blits a given graphics surface on top of the current drawing surface.
498 	 *
499 	 * Note that the source surface and the active
500 	 * surface are expected to be of the same size, hence the area delimited
501 	 * by "r" in the source surface will be blitted into the area delimited by
502 	 * "r" on the current surface.
503 	 *
504 	 * If you wish to blit a smaller surface into the active drawing area, use
505 	 * VectorRenderer::blitSubSurface().
506 	 *
507 	 * @param source Surface to blit into the drawing surface.
508 	 * @param r Position in the active drawing surface to do the blitting.
509 	 */
510 	virtual void blitSurface(const Graphics::ManagedSurface *source, const Common::Rect &r) = 0;
511 
512 	virtual void blitKeyBitmap(const Graphics::ManagedSurface *source, const Common::Point &p, bool themeTrans) = 0;
513 
514 	/**
515 	 * Draws a string into the screen. Wrapper for the Graphics::Font string drawing
516 	 * method.
517 	 */
518 	virtual void drawString(const Graphics::Font *font, const Common::U32String &text,
519 	                        const Common::Rect &area, Graphics::TextAlign alignH,
520 	                        GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool useEllipsis, const Common::Rect &textDrawableArea) = 0;
521 
522 	/**
523 	 * Allows to temporarily enable/disable all shadows drawing.
524 	 * i.e. for performance issues, blitting, etc
525 	 */
disableShadows()526 	virtual void disableShadows() { _disableShadows = true; }
enableShadows()527 	virtual void enableShadows() { _disableShadows = false; }
528 
529 	/**
530 	 * Applies a whole-screen shading effect, used before opening a new dialog.
531 	 * Currently supports screen dimmings and luminance (b&w).
532 	 */
533 	virtual void applyScreenShading(GUI::ThemeEngine::ShadingStyle) = 0;
534 
535 protected:
536 	ManagedSurface *_activeSurface; /**< Pointer to the surface currently being drawn */
537 
538 	FillMode _fillMode; /**< Defines in which way (if any) are filled the drawn shapes */
539 	ShadowFillMode _shadowFillMode;
540 
541 	int _shadowOffset; /**< offset for drawn shadows */
542 	int _bevel; /**< amount of fake bevel */
543 	bool _disableShadows; /**< Disables temporarily shadow drawing for overlayed images. */
544 	int _strokeWidth; /**< Width of the stroke of all drawn shapes */
545 	uint32 _dynamicData; /**< Dynamic data from the GUI Theme that modifies the drawing of the current shape */
546 
547 	int _gradientFactor; /**< Multiplication factor of the active gradient */
548 };
549 /** @} */
550 } // End of namespace Graphics
551 
552 #endif
553