ScummVM API documentation
gdraw.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  *
21  * Based on the original sources
22  * Faery Tale II -- The Halls of the Dead
23  * (c) 1993-1996 The Wyrmkeep Entertainment Co.
24  */
25 
26 #ifndef SAGA2_GDRAW_H
27 #define SAGA2_GDRAW_H
28 
29 #include "saga2/rect.h"
30 
31 namespace Saga2 {
32 
33 /* ===================================================================== *
34  Drawing Pens
35  * ===================================================================== */
36 
37 // A drawing pen. Note that this should later be a class?
38 
39 typedef uint8 gPen; // a pen index number
40 
41 /* ============================================================================ *
42  PixelMap: defines a chunky bitmap
43  * ============================================================================ */
44 
45 // A general purpose image
46 
48  StaticPoint16 size;
49  uint8 *data;
50 
51  int32 bytes() {
52  return size.x * size.y;
53  }
54 };
55 
56 class gPixelMap {
57 public:
58  Extent16 _size; // image size
59  uint8 *_data;
60 
61  gPixelMap() : _data(nullptr) {}
62 
63  gPixelMap(StaticPixelMap m) : _size(m.size), _data(m.data) {}
64 
65  // Compute the number of bytes in the pixel map
66  int32 bytes() {
67  return _size.x * _size.y;
68  }
69 };
70 
71 // The simplest kind of pixel map is a static image
72 
73 class gStaticImage : public gPixelMap {
74 public:
75  // constructors:
76 
77  gStaticImage() {
78  _size.x = _size.y = 0;
79  _data = NULL;
80  }
81  gStaticImage(int w, int h, uint8 *buffer) {
82  _size.x = w;
83  _size.y = h;
84  _data = buffer;
85  }
86 };
87 
88 // Automatically-remapped images: Eacn image adds itself to a
89 // chain at the time it is constructed, and will automatically
90 // remap to a new palette by calling the global remap() function.
91 
92 class gMappedImage : public gPixelMap {
93  static gMappedImage *_head; // first image in map chain
94 
95  gMappedImage *_next; // next image to remap
96  gPixelMap _original;
97 
98 public:
99  // Constructor and destructor
100  gMappedImage(int w, int h, uint8 *buffer);
101  virtual ~gMappedImage() {
102  if (_data) free(_data);
103  }
104  static void remap(gPen[]);
105 };
106 
107 /* ============================================================================ *
108  gFont: A bitmapped font structure
109  * ============================================================================ */
110 
111 struct gFont {
112  uint16 height; // height of the font
113  uint16 baseLine; // baseline of the font
114  uint16 rowMod; // row modulus for char data
115 
116  uint16 charXOffset[256]; // offset of each char in data
117 
118  int8 charWidth[256], // width of character in pixels
119  charKern[256], // character kern value
120  charSpace[256]; // character space value
121 
122  // followed by (row_mod * height) bytes of character data
123  byte *fontdata;
124 };
125 
126 // Prototypes
127 
128 gFont *LoadFont(char *fontname);
129 void DisposeFont(gFont *font);
130 int16 TextWidth(gFont *font, const char *s, int16 length, int16 styles);
131 int16 WhichChar(gFont *font, uint8 *s, int16 length, int16 maxLen);
132 int16 WhichIChar(gFont *font, uint8 *s, int16 length, int16 maxLen);
133 int32 GTextWrap(gFont *font, char *mark, uint16 &count, uint16 width, int16 styles);
134 
135 /* ============================================================================ *
136  gPenState: Used by gPorts to save the current state
137  * ============================================================================ */
138 
139 struct gPenState {
140  gPen fgPen, // current foregroung pen
141  bgPen, // current drawing mode
142  olPen, // text outline pen
143  shPen; // text shadow pen
144  uint8 drawMode; // current drawing mode
145 };
146 
147 /* ============================================================================ *
148  gPort: Facilitates redering operations on PixelMaps
149  * ============================================================================ */
150 
151 enum DrawModes {
152  kDrawModeMatte = 0, // use transparency
153  kDrawModeColor, // solid color, use transparency
154  kDrawModeReplace, // don't use transparency
155  kDrawModeComplement, // blit in complement mode
156 
157  kNumDrawModes
158 };
159 
160 enum {
161  kTextStyleOutline = (1 << 0), // outline the characters
162  kTextStyleShadow = (1 << 1), // drop shadow the characters
163  kTextStyleUnderScore = (1 << 2), // underscore all chars
164  kTextStyleUnderBar = (1 << 3), // underscore char after a '_'
165  kTextStyleHiLiteBar = (1 << 4), // highlight char after a '_'
166  kTextStyleThickOutline = (1 << 5), // extra-thick outline
167  kTextStyleBold = (1 << 6), // bold
168  kTextStyleItalics = (1 << 7) // italic
169 };
170 
171 enum TextPositions {
172  kTextPosLeft = (1 << 0),
173  kTextPosRight = (1 << 1),
174  kTextPosHigh = (1 << 2),
175  kTextPosLow = (1 << 3)
176 };
177 
178 class gPort {
179 public:
180  gPixelMap *_map; // pointer to map
181 
182  // Added by Talin to speed up rendering and allow inverted
183  // gPorts for WinG compatibility
184 
185  uint8 *_baseRow; // address of row 0
186  int16 _rowMod; // modulus or row
187 
188  Point16 _origin; // origin drawing point
189  Rect16 _clip; // clip region DrawPort
190  gPen _fgPen, // current foregroung pen
191  _bgPen, // current drawing mode
192  _olPen, // text outline pen
193  _shPen; // text shadow pen
194  gPen *_penMap; // indirect pen map
195  DrawModes _drawMode; // current drawing mode
196  Point16 _penPos; // current pen position
197  gFont *_font; // current font
198  int16 _textSpacing; // extra space between characters
199  uint16 _textStyles; // text style bits
200 
201  // Constructor
202  gPort() {
203  _map = nullptr;
204  _baseRow = nullptr;
205 
206  _rowMod = 0;
207  _penMap = nullptr;
208  _drawMode = kDrawModeMatte;
209  _font = nullptr;
210  _textSpacing = 0;
211  _textStyles = 0;
212  _fgPen = _bgPen = _olPen = _shPen = 0;
213  }
214 
215  virtual ~gPort() {}
216 
217  // Set attributes
218 
219  virtual void setMap(gPixelMap *newmap, bool inverted = false);
220 
221  // Direct colors
222 
223  void setColor(gPen color) {
224  _fgPen = color;
225  }
226  void setBgColor(gPen color) {
227  _bgPen = color;
228  }
229  void setShadowColor(gPen color) {
230  _shPen = color;
231  }
232  void setOutlineColor(gPen color) {
233  _olPen = color;
234  }
235 
236  // Indirect colors
237 
238  void setPenMap(gPen *pmap) {
239  _penMap = pmap;
240  }
241  void setIndirectColor(uint8 color) {
242  _fgPen = _penMap[color];
243  }
244  void setIndirectBgColor(uint8 color) {
245  _bgPen = _penMap[color];
246  }
247  void setIndirectShColor(uint8 color) {
248  _shPen = _penMap[color];
249  }
250  void setIndirectOLColor(uint8 color) {
251  _olPen = _penMap[color];
252  }
253 
254  // modes & styles
255 
256  void setMode(DrawModes mode) {
257  _drawMode = mode;
258  }
259  void setStyle(int style) {
260  _textStyles = style;
261  }
262 
263  // Pen states
264 
265  void setState(gPenState &);
266  void getState(gPenState &);
267 
268  // REM: calc intersection of pixel map rect...
269 
270  void setClip(const Rect16 &newclip) {
271  _clip = newclip;
272  }
273  void getClip(Rect16 &r) {
274  r = _clip;
275  }
276 
277  void setOrigin(Point16 pt) {
278  _origin = pt;
279  }
280  Point16 getOrigin() {
281  return _origin;
282  }
283 
284  // Pen position movement
285 
286  void move(int16 x, int16 y) {
287  _penPos.x += x;
288  _penPos.y += y;
289  }
290  void move(Vector16 v) {
291  _penPos += v;
292  }
293  void moveTo(int16 x, int16 y) {
294  _penPos.x = x;
295  _penPos.y = y;
296  }
297  void moveTo(Point16 p) {
298  _penPos = p;
299  }
300 
301  // Simple drawing functions
302  // REM: This should clip!
303 
304  virtual void clear() {
305  memset(_map->_data, (int)_fgPen, (int)_map->bytes());
306  }
307 
308  // Functions to set a single pixel
309  // NOTE: should this actually be a function pointer to deal
310  // with drawing mode?
311 
312  virtual void setPixel(int16 x, int16 y, gPen color) {
313  if (x >= _clip.x && x < _clip.x + _clip.width
314  && y >= _clip.y && y < _clip.y + _clip.height) {
315  _baseRow[(y + _origin.y) * _rowMod + x + _origin.x] = color;
316  }
317  }
318  void setPixel(int16 x, int16 y) {
319  setPixel(x, y, _fgPen);
320  }
321  void setPixel(Point16 p, gPen color) {
322  setPixel(p.x, p.y, color);
323  }
324  void setPixel(Point16 p) {
325  setPixel(p.x, p.y, _fgPen);
326  }
327 
328  // pixel query functions
329 
330  virtual gPen getPixel(int16 x, int16 y) {
331  return _baseRow[(y + _origin.y) * _rowMod + x + _origin.x];
332  }
333  virtual gPen getPixel(Point16 p) {
334  return _baseRow[(p.y + _origin.y) * _rowMod + p.x + _origin.x];
335  }
336 
337  // Rectangle fill functions
338 
339  virtual void fillRect(const Rect16 r);
340  void fillRect(int16 x, int16 y, int16 w, int16 h) {
341  fillRect(Rect16(x, y, w, h));
342  }
343  // Rectangle frame functions //
344 
345  virtual void frameRect(const Rect16 r, int16 thick);
346  void frameRect(int16 x, int16 y, int16 w, int16 h, int16 thick) {
347  frameRect(Rect16(x, y, w, h), thick);
348  }
349 
350  // Horiztonal and vertical lines
351 
352  virtual void hLine(int16 x, int16 y, int16 width);
353  virtual void vLine(int16 x, int16 y, int16 height);
354 
355  // Bresenham line-drawing functions
356 
357  virtual void line(int16 x1, int16 y1, int16 x2, int16 y2);
358  void line(Point16 from, Point16 to) {
359  line(from.x, from.y, to.x, to.y);
360  }
361  void drawTo(int16 x, int16 y) {
362  line(_penPos.x, _penPos.y, x, y);
363  _penPos.x = x;
364  _penPos.y = y;
365  }
366  void drawTo(Point16 to) {
367  line(_penPos, to);
368  _penPos = to;
369  }
370  void draw(int16 x, int16 y) {
371  line(_penPos.x, _penPos.y, _penPos.x + x, _penPos.y + y);
372  _penPos.x += x;
373  _penPos.y += y;
374  }
375  void draw(Vector16 v) {
376  line(_penPos, v);
377  _penPos += v;
378  }
379 
380  // Blitting functions
381 
382  virtual void bltPixels(const gPixelMap &src,
383  int src_x, int src_y,
384  int dst_x, int dst_y,
385  int width, int height);
386 
387  virtual void bltPixelMask(gPixelMap &src,
388  gPixelMap &msk,
389  int src_x, int src_y,
390  int dst_x, int dst_y,
391  int width, int height);
392 
393  virtual void scrollPixels(const Rect16 r, int dx, int dy);
394 
395  // Text rendering functions
396 
397  void setFont(gFont *newFont) {
398  _font = newFont;
399  }
400  void setTextSpacing(int16 fs) {
401  _textSpacing = fs;
402  }
403 
404 private:
405  // Unclipped text rendering
406  void drawStringChars(const char *, int16, gPixelMap &, int, int);
407  // Clipped but still low-level
408  int16 drawClippedString(const char *str, int16 len, int xpos, int ypos);
409 public:
410 
411  // Draw a text string with the current settings at the
412  // current pen position. If the length is < 0, then use the
413  // natural string length.
414  void drawText(const char *str, int16 length = -1);
415  void drawTextInBox(const char *str, int16 length,
416  const Rect16 &r, int16 pos,
417  Point16 borders);
418 };
419 
420 void mapImage(gPort &from, gPort &to, gPen map[]);
421 void mapImage(gPixelMap &from, gPixelMap &to, gPen map[]);
422 
423 bool NewTempPort(gPort &, int width, int height);
424 void DisposeTempPort(gPort &);
425 
426 /* ============================================================================ *
427  gSavePort: a class which auto-saves and auto-restores the port state
428  * ============================================================================ */
429 
430 struct gSavePort {
431  gPenState state; // saved state of port
432 public:
433  gPort &port; // port which was saved
434 
435  gSavePort(gPort &p) : port(p) {
436  port.getState(state);
437  }
438  ~gSavePort() {
439  port.setState(state);
440  }
441 };
442 
443 #define SAVE_GPORT_STATE(p) gSavePort sp( p )
444 
445 } // end of namespace Saga2
446 
447 #endif
Definition: gdraw.h:139
Definition: gdraw.h:430
Definition: actor.h:32
Definition: gdraw.h:56
Definition: gdraw.h:178
Definition: gdraw.h:47
Definition: rect.h:42
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
Definition: gdraw.h:73
Definition: gdraw.h:92
Definition: gdraw.h:111
Definition: rect.h:33
Definition: rect.h:290