rays 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +8 -0
- data/README +4 -0
- data/Rakefile +72 -0
- data/VERSION +1 -0
- data/ext/rays/bitmap.cpp +322 -0
- data/ext/rays/extconf.rb +61 -0
- data/ext/rays/font.cpp +125 -0
- data/ext/rays/image.cpp +166 -0
- data/ext/rays/native.cpp +24 -0
- data/ext/rays/painter.cpp +573 -0
- data/ext/rays/rays.cpp +61 -0
- data/ext/rays/rays.h +39 -0
- data/ext/rays/texture.cpp +130 -0
- data/include/rays.h +20 -0
- data/include/rays/bitmap.h +80 -0
- data/include/rays/colorspace.h +101 -0
- data/include/rays/defs.h +33 -0
- data/include/rays/font.h +49 -0
- data/include/rays/helpers.h +37 -0
- data/include/rays/image.h +68 -0
- data/include/rays/opengl.h +15 -0
- data/include/rays/painter.h +179 -0
- data/include/rays/rays.h +19 -0
- data/include/rays/ruby.h +15 -0
- data/include/rays/ruby/bitmap.h +39 -0
- data/include/rays/ruby/font.h +39 -0
- data/include/rays/ruby/image.h +39 -0
- data/include/rays/ruby/painter.h +39 -0
- data/include/rays/ruby/rays.h +21 -0
- data/include/rays/ruby/texture.h +39 -0
- data/include/rays/texture.h +56 -0
- data/include/rays/transform.h +35 -0
- data/lib/rays.rb +9 -0
- data/lib/rays/autoinit.rb +10 -0
- data/lib/rays/bitmap.rb +25 -0
- data/lib/rays/image.rb +15 -0
- data/lib/rays/module.rb +30 -0
- data/lib/rays/painter.rb +99 -0
- data/lib/rays/texture.rb +15 -0
- data/rays.gemspec +54 -0
- data/src/cocoa/bitmap.mm +286 -0
- data/src/cocoa/font.mm +193 -0
- data/src/cocoa/helpers.h +26 -0
- data/src/cocoa/helpers.mm +25 -0
- data/src/cocoa/rays.mm +40 -0
- data/src/colorspace.cpp +183 -0
- data/src/helpers.cpp +22 -0
- data/src/image.cpp +133 -0
- data/src/painter.cpp +769 -0
- data/src/texture.cpp +360 -0
- data/src/transform.cpp +88 -0
- data/src/win32/bitmap.cpp +212 -0
- data/src/win32/font.cpp +99 -0
- data/src/win32/gdi.cpp +771 -0
- data/src/win32/gdi.h +226 -0
- data/src/win32/rays.cpp +36 -0
- data/support.rb +58 -0
- data/task/ext.rake +41 -0
- data/task/gem.rake +33 -0
- data/task/git.rake +22 -0
- data/task/lib.rake +54 -0
- data/test/helpers.rb +15 -0
- data/test/test_painter.rb +11 -0
- data/test/test_rays.rb +19 -0
- data/test/test_texture.rb +11 -0
- metadata +153 -0
data/src/win32/font.cpp
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
#include "rays/font.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include "gdi.h"
|
5
|
+
|
6
|
+
|
7
|
+
namespace Rays
|
8
|
+
{
|
9
|
+
|
10
|
+
|
11
|
+
struct Font::Data
|
12
|
+
{
|
13
|
+
|
14
|
+
Win32::Font font;
|
15
|
+
|
16
|
+
};// Window::Data
|
17
|
+
|
18
|
+
|
19
|
+
Font::Font ()
|
20
|
+
{
|
21
|
+
}
|
22
|
+
|
23
|
+
Font::Font (const char* name, coord size)
|
24
|
+
{
|
25
|
+
self->font = Win32::Font(name, size);
|
26
|
+
}
|
27
|
+
|
28
|
+
Font::~Font ()
|
29
|
+
{
|
30
|
+
}
|
31
|
+
|
32
|
+
String
|
33
|
+
Font::name () const
|
34
|
+
{
|
35
|
+
return self->font.name();
|
36
|
+
}
|
37
|
+
|
38
|
+
coord
|
39
|
+
Font::size () const
|
40
|
+
{
|
41
|
+
return self->font.size();
|
42
|
+
}
|
43
|
+
|
44
|
+
bool
|
45
|
+
Font::get_extent (coord* width, coord* height, const char* str) const
|
46
|
+
{
|
47
|
+
return self->font.get_extent(width, height, str);
|
48
|
+
}
|
49
|
+
|
50
|
+
Font::operator bool () const
|
51
|
+
{
|
52
|
+
return self && self->font;
|
53
|
+
}
|
54
|
+
|
55
|
+
bool
|
56
|
+
Font::operator ! () const
|
57
|
+
{
|
58
|
+
return !operator bool();
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
const Font&
|
63
|
+
default_font ()
|
64
|
+
{
|
65
|
+
static const Font FONT(NULL);
|
66
|
+
return FONT;
|
67
|
+
}
|
68
|
+
|
69
|
+
|
70
|
+
bool
|
71
|
+
draw_string (
|
72
|
+
HDC hdc, coord context_height,
|
73
|
+
const char* str, coord x, coord y, const Font& font)
|
74
|
+
{
|
75
|
+
using namespace Win32;
|
76
|
+
|
77
|
+
if (!hdc || !str || !font) return false;
|
78
|
+
|
79
|
+
if (*str == '\0') return true;
|
80
|
+
|
81
|
+
coord width = 0, height = 0;
|
82
|
+
if (!font.get_extent(&width, &height, str))
|
83
|
+
return false;
|
84
|
+
|
85
|
+
DC dc = hdc;
|
86
|
+
|
87
|
+
RECT rect = {x, y, x + (int) width, y + (int) height};
|
88
|
+
FillRect(dc.handle(), &rect, Brush(0, 0, 0).handle());
|
89
|
+
|
90
|
+
Win32::Font old = dc.font();
|
91
|
+
dc.set_font(font.self->font.handle());
|
92
|
+
BOOL ret = TextOutA(dc.handle(), x, y, str, strlen(str));
|
93
|
+
dc.set_font(old);
|
94
|
+
|
95
|
+
return ret != FALSE;
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
}// Rays
|
data/src/win32/gdi.cpp
ADDED
@@ -0,0 +1,771 @@
|
|
1
|
+
#include "gdi.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include <vector>
|
5
|
+
|
6
|
+
|
7
|
+
namespace Rays
|
8
|
+
{
|
9
|
+
|
10
|
+
|
11
|
+
namespace Win32
|
12
|
+
{
|
13
|
+
|
14
|
+
|
15
|
+
typedef void (*DeleteHandleFunc) (HANDLE);
|
16
|
+
|
17
|
+
|
18
|
+
static void
|
19
|
+
delete_object (HANDLE handle)
|
20
|
+
{
|
21
|
+
DeleteObject(handle);
|
22
|
+
}
|
23
|
+
|
24
|
+
static void
|
25
|
+
delete_dc (HANDLE handle)
|
26
|
+
{
|
27
|
+
DeleteDC((HDC) handle);
|
28
|
+
}
|
29
|
+
|
30
|
+
static void
|
31
|
+
release_dc (HANDLE handle)
|
32
|
+
{
|
33
|
+
ReleaseDC(NULL, (HDC) handle);
|
34
|
+
}
|
35
|
+
|
36
|
+
|
37
|
+
template <typename HANDLE>
|
38
|
+
class HandleObject
|
39
|
+
{
|
40
|
+
|
41
|
+
public:
|
42
|
+
|
43
|
+
typedef HANDLE Handle;
|
44
|
+
|
45
|
+
HandleObject (
|
46
|
+
Handle handle = NULL, bool owner = true,
|
47
|
+
DeleteHandleFunc delfun = delete_object)
|
48
|
+
: handle_(handle), delfun_(delfun)
|
49
|
+
{
|
50
|
+
}
|
51
|
+
|
52
|
+
~HandleObject ()
|
53
|
+
{
|
54
|
+
reset();
|
55
|
+
}
|
56
|
+
|
57
|
+
void reset (
|
58
|
+
Handle handle = NULL, bool owner = true,
|
59
|
+
DeleteHandleFunc delfun = delete_object)
|
60
|
+
{
|
61
|
+
if (handle_ && delfun_) (*delfun_)(handle_);
|
62
|
+
handle_ = handle;
|
63
|
+
delfun_ = owner ? delfun : NULL;
|
64
|
+
}
|
65
|
+
|
66
|
+
Handle handle () const
|
67
|
+
{
|
68
|
+
return handle_;
|
69
|
+
}
|
70
|
+
|
71
|
+
operator bool () const
|
72
|
+
{
|
73
|
+
return !!handle_;
|
74
|
+
}
|
75
|
+
|
76
|
+
bool operator ! () const
|
77
|
+
{
|
78
|
+
return !operator bool();
|
79
|
+
}
|
80
|
+
|
81
|
+
private:
|
82
|
+
|
83
|
+
Handle handle_;
|
84
|
+
|
85
|
+
DeleteHandleFunc delfun_;
|
86
|
+
|
87
|
+
};// HandleObject
|
88
|
+
|
89
|
+
|
90
|
+
struct Pen::Data
|
91
|
+
{
|
92
|
+
|
93
|
+
HandleObject<HPEN> handle;
|
94
|
+
|
95
|
+
};// Pen::Data
|
96
|
+
|
97
|
+
|
98
|
+
Pen::Pen (HPEN handle, bool owner)
|
99
|
+
{
|
100
|
+
if (!handle) return;
|
101
|
+
self->handle.reset(handle, owner);
|
102
|
+
}
|
103
|
+
|
104
|
+
Pen::Pen (int red, int green, int blue, int width, int style)
|
105
|
+
{
|
106
|
+
self->handle.reset(
|
107
|
+
CreatePen(style, width, RGB(red, green, blue)));
|
108
|
+
}
|
109
|
+
|
110
|
+
Pen::~Pen ()
|
111
|
+
{
|
112
|
+
}
|
113
|
+
|
114
|
+
bool
|
115
|
+
Pen::get_color (int* red, int* green, int* blue) const
|
116
|
+
{
|
117
|
+
if (!*this || (!red && !green && !blue))
|
118
|
+
return false;
|
119
|
+
|
120
|
+
LOGPEN logpen;
|
121
|
+
if (!GetObject(handle(), sizeof(logpen), &logpen))
|
122
|
+
return false;
|
123
|
+
|
124
|
+
if (red) *red = GetRValue(logpen.lopnColor);
|
125
|
+
if (green) *green = GetGValue(logpen.lopnColor);
|
126
|
+
if (blue) *blue = GetBValue(logpen.lopnColor);
|
127
|
+
return true;
|
128
|
+
}
|
129
|
+
|
130
|
+
HPEN
|
131
|
+
Pen::handle () const
|
132
|
+
{
|
133
|
+
return self->handle.handle();
|
134
|
+
}
|
135
|
+
|
136
|
+
Pen::operator bool () const
|
137
|
+
{
|
138
|
+
return !!self->handle;
|
139
|
+
}
|
140
|
+
|
141
|
+
bool
|
142
|
+
Pen::operator ! () const
|
143
|
+
{
|
144
|
+
return !operator bool();
|
145
|
+
}
|
146
|
+
|
147
|
+
|
148
|
+
struct Brush::Data
|
149
|
+
{
|
150
|
+
|
151
|
+
HandleObject<HBRUSH> handle;
|
152
|
+
|
153
|
+
};// Brush::Data
|
154
|
+
|
155
|
+
|
156
|
+
Brush::Brush (HBRUSH handle, bool owner)
|
157
|
+
{
|
158
|
+
if (!handle) return;
|
159
|
+
self->handle.reset(handle, owner);
|
160
|
+
}
|
161
|
+
|
162
|
+
Brush::Brush (int red, int green, int blue, int style)
|
163
|
+
{
|
164
|
+
LOGBRUSH logbrush = {0};
|
165
|
+
logbrush.lbStyle = style;
|
166
|
+
logbrush.lbColor = RGB(red, green, blue);
|
167
|
+
logbrush.lbHatch = 0;
|
168
|
+
|
169
|
+
self->handle.reset(CreateBrushIndirect(&logbrush));
|
170
|
+
}
|
171
|
+
|
172
|
+
Brush::~Brush ()
|
173
|
+
{
|
174
|
+
}
|
175
|
+
|
176
|
+
bool
|
177
|
+
Brush::get_color (int* red, int* green, int* blue) const
|
178
|
+
{
|
179
|
+
if (!*this || (!red && !green && !blue))
|
180
|
+
return false;
|
181
|
+
|
182
|
+
LOGBRUSH logbrush;
|
183
|
+
if (!GetObject(handle(), sizeof(logbrush), &logbrush))
|
184
|
+
return false;
|
185
|
+
|
186
|
+
if (red) *red = GetRValue(logbrush.lbColor);
|
187
|
+
if (green) *green = GetGValue(logbrush.lbColor);
|
188
|
+
if (blue) *blue = GetBValue(logbrush.lbColor);
|
189
|
+
return true;
|
190
|
+
}
|
191
|
+
|
192
|
+
HBRUSH
|
193
|
+
Brush::handle () const
|
194
|
+
{
|
195
|
+
return self->handle.handle();
|
196
|
+
}
|
197
|
+
|
198
|
+
Brush::operator bool () const
|
199
|
+
{
|
200
|
+
return !!self->handle;
|
201
|
+
}
|
202
|
+
|
203
|
+
bool
|
204
|
+
Brush::operator ! () const
|
205
|
+
{
|
206
|
+
return !operator bool();
|
207
|
+
}
|
208
|
+
|
209
|
+
|
210
|
+
struct Font::Data
|
211
|
+
{
|
212
|
+
|
213
|
+
HandleObject<HFONT> handle;
|
214
|
+
|
215
|
+
};// Font::Data
|
216
|
+
|
217
|
+
|
218
|
+
static HFONT
|
219
|
+
create_font (const char* name, coord size = 0)
|
220
|
+
{
|
221
|
+
NONCLIENTMETRICSA metrics;
|
222
|
+
memset(&metrics, 0, sizeof(metrics));
|
223
|
+
metrics.cbSize = sizeof(metrics);
|
224
|
+
|
225
|
+
if (!SystemParametersInfoA(
|
226
|
+
SPI_GETNONCLIENTMETRICS, sizeof(metrics), &metrics, 0))
|
227
|
+
{
|
228
|
+
return NULL;
|
229
|
+
}
|
230
|
+
|
231
|
+
LOGFONTA& logfont = metrics.lfMessageFont;
|
232
|
+
|
233
|
+
if (name)
|
234
|
+
strcpy(logfont.lfFaceName, name);
|
235
|
+
|
236
|
+
if (size == 0)
|
237
|
+
logfont.lfHeight = 0;
|
238
|
+
else
|
239
|
+
{
|
240
|
+
logfont.lfHeight = -MulDiv(
|
241
|
+
size,
|
242
|
+
GetDeviceCaps(screen_dc().handle(), LOGPIXELSY),
|
243
|
+
72);
|
244
|
+
}
|
245
|
+
|
246
|
+
return CreateFontIndirectA(&logfont);
|
247
|
+
}
|
248
|
+
|
249
|
+
|
250
|
+
Font::Font (HFONT handle, bool owner)
|
251
|
+
{
|
252
|
+
if (!handle) return;
|
253
|
+
self->handle.reset(handle, owner);
|
254
|
+
}
|
255
|
+
|
256
|
+
Font::Font (const char* name, coord size)
|
257
|
+
{
|
258
|
+
self->handle.reset(create_font(name, size));
|
259
|
+
}
|
260
|
+
|
261
|
+
Font::~Font ()
|
262
|
+
{
|
263
|
+
}
|
264
|
+
|
265
|
+
static bool
|
266
|
+
calc_size (
|
267
|
+
coord* width, coord* height, HDC hdc, const char* str)
|
268
|
+
{
|
269
|
+
if ((!width && !height) || !hdc || !str) return false;
|
270
|
+
|
271
|
+
RECT rect = {0, 0, 0, 0};
|
272
|
+
BOOL ret = DrawTextA(
|
273
|
+
hdc, str, (int) strlen(str), &rect,
|
274
|
+
DT_EXPANDTABS | DT_NOPREFIX | DT_CALCRECT);
|
275
|
+
|
276
|
+
if (!ret) return false;
|
277
|
+
|
278
|
+
if (width) *width = rect.right - rect.left;
|
279
|
+
if (height) *height = rect.bottom - rect.top;
|
280
|
+
|
281
|
+
return true;
|
282
|
+
}
|
283
|
+
|
284
|
+
bool
|
285
|
+
Font::get_extent (
|
286
|
+
coord* width, coord* height, const char* str, HDC hdc)
|
287
|
+
{
|
288
|
+
if (!*this || (!width && !height) || !str)
|
289
|
+
return false;
|
290
|
+
|
291
|
+
DC dc = hdc ? DC(hdc) : screen_dc();
|
292
|
+
if (!dc) return false;
|
293
|
+
|
294
|
+
Font old = dc.font();
|
295
|
+
dc.set_font(*this);
|
296
|
+
bool ret = calc_size(width, height, dc.handle(), str);
|
297
|
+
dc.set_font(old);
|
298
|
+
|
299
|
+
return ret;
|
300
|
+
}
|
301
|
+
|
302
|
+
String
|
303
|
+
Font::name () const
|
304
|
+
{
|
305
|
+
if (!*this) return "";
|
306
|
+
|
307
|
+
LOGFONT logfont;
|
308
|
+
int size = sizeof(logfont);
|
309
|
+
if (GetObject(self->handle.handle(), size, &logfont) != size)
|
310
|
+
return "";
|
311
|
+
|
312
|
+
return logfont.lfFaceName;
|
313
|
+
}
|
314
|
+
|
315
|
+
coord
|
316
|
+
Font::size () const
|
317
|
+
{
|
318
|
+
if (!*this) return 0;
|
319
|
+
|
320
|
+
LOGFONT logfont;
|
321
|
+
int size = sizeof(logfont);
|
322
|
+
if (GetObject(self->handle.handle(), size, &logfont) != size)
|
323
|
+
return 0;
|
324
|
+
|
325
|
+
if (logfont.lfHeight >= 0)
|
326
|
+
return logfont.lfHeight;
|
327
|
+
|
328
|
+
if (logfont.lfHeight < 0)
|
329
|
+
{
|
330
|
+
return -MulDiv(
|
331
|
+
logfont.lfHeight, 72,
|
332
|
+
GetDeviceCaps(screen_dc().handle(), LOGPIXELSY));
|
333
|
+
}
|
334
|
+
else
|
335
|
+
return logfont.lfHeight;
|
336
|
+
}
|
337
|
+
|
338
|
+
HFONT
|
339
|
+
Font::handle () const
|
340
|
+
{
|
341
|
+
return self->handle.handle();
|
342
|
+
}
|
343
|
+
|
344
|
+
Font::operator bool () const
|
345
|
+
{
|
346
|
+
return !!self->handle;
|
347
|
+
}
|
348
|
+
|
349
|
+
bool
|
350
|
+
Font::operator ! () const
|
351
|
+
{
|
352
|
+
return !operator bool();
|
353
|
+
}
|
354
|
+
|
355
|
+
|
356
|
+
struct Bitmap::Data
|
357
|
+
{
|
358
|
+
|
359
|
+
HandleObject<HBITMAP> handle;
|
360
|
+
|
361
|
+
};// Bitmap::Data
|
362
|
+
|
363
|
+
|
364
|
+
#if 0
|
365
|
+
static bool
|
366
|
+
load_bitmap (uint id, HINSTANCE hinst = NULL)
|
367
|
+
{
|
368
|
+
if (!hinst) hinst = (HINSTANCE) GetModuleHandle(NULL);
|
369
|
+
self->handle.reset(LoadBitmap(hinst, MAKEINTRESOURCE(id)));
|
370
|
+
return !!self->handle;
|
371
|
+
}
|
372
|
+
#endif
|
373
|
+
|
374
|
+
Bitmap::Bitmap (HBITMAP handle, bool owner)
|
375
|
+
{
|
376
|
+
if (!handle) return;
|
377
|
+
self->handle.reset(handle, owner);
|
378
|
+
}
|
379
|
+
|
380
|
+
Bitmap::Bitmap (HDC hdc, int width, int height)
|
381
|
+
{
|
382
|
+
self->handle.reset(CreateCompatibleBitmap(hdc, width, height));
|
383
|
+
}
|
384
|
+
|
385
|
+
Bitmap::~Bitmap ()
|
386
|
+
{
|
387
|
+
}
|
388
|
+
|
389
|
+
int
|
390
|
+
Bitmap::width () const
|
391
|
+
{
|
392
|
+
BITMAP bmp;
|
393
|
+
if (!*this || !GetObject(handle(), sizeof(bmp), &bmp))
|
394
|
+
return 0;
|
395
|
+
return bmp.bmWidth;
|
396
|
+
}
|
397
|
+
|
398
|
+
int
|
399
|
+
Bitmap::height () const
|
400
|
+
{
|
401
|
+
BITMAP bmp;
|
402
|
+
if (!*this || !GetObject(handle(), sizeof(bmp), &bmp))
|
403
|
+
return 0;
|
404
|
+
return bmp.bmHeight;
|
405
|
+
}
|
406
|
+
|
407
|
+
HBITMAP
|
408
|
+
Bitmap::handle () const
|
409
|
+
{
|
410
|
+
return self->handle.handle();
|
411
|
+
}
|
412
|
+
|
413
|
+
Bitmap::operator bool () const
|
414
|
+
{
|
415
|
+
return self->handle.handle();
|
416
|
+
}
|
417
|
+
|
418
|
+
bool
|
419
|
+
Bitmap::operator ! () const
|
420
|
+
{
|
421
|
+
return !operator bool();
|
422
|
+
}
|
423
|
+
|
424
|
+
|
425
|
+
struct DCState
|
426
|
+
{
|
427
|
+
|
428
|
+
HPEN hpen;
|
429
|
+
|
430
|
+
Pen pen;
|
431
|
+
|
432
|
+
HBRUSH hbrush;
|
433
|
+
|
434
|
+
Brush brush;
|
435
|
+
|
436
|
+
HFONT hfont;
|
437
|
+
|
438
|
+
Font font;
|
439
|
+
|
440
|
+
HBITMAP hbitmap;
|
441
|
+
|
442
|
+
Bitmap bitmap;
|
443
|
+
|
444
|
+
COLORREF textcolor, backcolor;
|
445
|
+
|
446
|
+
int backmode;
|
447
|
+
|
448
|
+
DCState ()
|
449
|
+
: hpen(NULL), hbrush(NULL), hfont(NULL), hbitmap(NULL),
|
450
|
+
textcolor(RGB(0, 0, 0)), backcolor(RGB(255, 255, 255)),
|
451
|
+
backmode(OPAQUE)
|
452
|
+
{
|
453
|
+
}
|
454
|
+
|
455
|
+
bool init (
|
456
|
+
HDC hdc,
|
457
|
+
const Pen& pen_,
|
458
|
+
const Brush& brush_,
|
459
|
+
const Font& font_,
|
460
|
+
const Bitmap& bitmap_)
|
461
|
+
{
|
462
|
+
if (!hdc) return false;
|
463
|
+
|
464
|
+
pen = pen_;
|
465
|
+
brush = brush_;
|
466
|
+
font = font_;
|
467
|
+
bitmap = bitmap_;
|
468
|
+
hpen = (HPEN) GetCurrentObject(hdc, OBJ_PEN);
|
469
|
+
hbrush = (HBRUSH) GetCurrentObject(hdc, OBJ_BRUSH);
|
470
|
+
hfont = (HFONT) GetCurrentObject(hdc, OBJ_FONT);
|
471
|
+
hbitmap = (HBITMAP) GetCurrentObject(hdc, OBJ_BITMAP);
|
472
|
+
textcolor = GetTextColor(hdc);
|
473
|
+
backcolor = GetBkColor(hdc);
|
474
|
+
backmode = GetBkMode(hdc);
|
475
|
+
return true;
|
476
|
+
}
|
477
|
+
|
478
|
+
};// DCState
|
479
|
+
|
480
|
+
typedef std::vector<DCState> DCStateStack;
|
481
|
+
|
482
|
+
|
483
|
+
struct DC::Data
|
484
|
+
{
|
485
|
+
|
486
|
+
HandleObject<HDC> handle;
|
487
|
+
|
488
|
+
DCStateStack stack;
|
489
|
+
|
490
|
+
Pen pen;
|
491
|
+
|
492
|
+
Brush brush;
|
493
|
+
|
494
|
+
Font font;
|
495
|
+
|
496
|
+
Bitmap bitmap;
|
497
|
+
|
498
|
+
};// DC::Data
|
499
|
+
|
500
|
+
|
501
|
+
DC::DC (HDC handle, bool owner, DeleteType deltype)
|
502
|
+
{
|
503
|
+
if (!handle) return;
|
504
|
+
|
505
|
+
DeleteHandleFunc delfun = NULL;
|
506
|
+
switch (deltype)
|
507
|
+
{
|
508
|
+
case DELETE_DC: delfun = delete_dc; break;
|
509
|
+
case RELEASE_DC: delfun = release_dc; break;
|
510
|
+
}
|
511
|
+
|
512
|
+
self->handle.reset(handle, owner, delfun);
|
513
|
+
}
|
514
|
+
|
515
|
+
DC::~DC ()
|
516
|
+
{
|
517
|
+
assert(self->stack.empty());
|
518
|
+
}
|
519
|
+
|
520
|
+
#if 0
|
521
|
+
bool
|
522
|
+
DC::get_text_size (coord* width, coord* height, const char* text)
|
523
|
+
{
|
524
|
+
return calc_text_size(width, height, text, handle());
|
525
|
+
}
|
526
|
+
#endif
|
527
|
+
|
528
|
+
Pen
|
529
|
+
DC::pen () const
|
530
|
+
{
|
531
|
+
HPEN hpen = (HPEN) GetCurrentObject(handle(), OBJ_PEN);
|
532
|
+
if (hpen == self->pen.handle())
|
533
|
+
return self->pen;
|
534
|
+
else
|
535
|
+
return hpen;
|
536
|
+
}
|
537
|
+
|
538
|
+
bool
|
539
|
+
DC::set_pen (const Pen& pen)
|
540
|
+
{
|
541
|
+
if (!*this) return false;
|
542
|
+
SelectObject(handle(), pen.handle());
|
543
|
+
self->pen = pen;
|
544
|
+
return true;
|
545
|
+
}
|
546
|
+
|
547
|
+
Brush
|
548
|
+
DC::brush () const
|
549
|
+
{
|
550
|
+
HBRUSH hbrush = (HBRUSH) GetCurrentObject(handle(), OBJ_BRUSH);
|
551
|
+
if (hbrush == self->brush.handle())
|
552
|
+
return self->brush;
|
553
|
+
else
|
554
|
+
return hbrush;
|
555
|
+
}
|
556
|
+
|
557
|
+
bool
|
558
|
+
DC::set_brush (const Brush& brush)
|
559
|
+
{
|
560
|
+
if (!*this) return false;
|
561
|
+
SelectObject(handle(), brush.handle());
|
562
|
+
self->brush = brush;
|
563
|
+
return true;
|
564
|
+
}
|
565
|
+
|
566
|
+
Font
|
567
|
+
DC::font () const
|
568
|
+
{
|
569
|
+
HFONT hfont = (HFONT) GetCurrentObject(handle(), OBJ_FONT);
|
570
|
+
if (hfont == self->font.handle())
|
571
|
+
return self->font;
|
572
|
+
else
|
573
|
+
return hfont;
|
574
|
+
}
|
575
|
+
|
576
|
+
bool
|
577
|
+
DC::set_font (const Font& font)
|
578
|
+
{
|
579
|
+
if (!*this) return false;
|
580
|
+
SelectObject(handle(), font.handle());
|
581
|
+
self->font = font;
|
582
|
+
return true;
|
583
|
+
}
|
584
|
+
|
585
|
+
Bitmap
|
586
|
+
DC::bitmap () const
|
587
|
+
{
|
588
|
+
HBITMAP hbmp = (HBITMAP) GetCurrentObject(handle(), OBJ_BITMAP);
|
589
|
+
if (hbmp == self->bitmap.handle())
|
590
|
+
return self->bitmap;
|
591
|
+
else
|
592
|
+
return hbmp;
|
593
|
+
}
|
594
|
+
|
595
|
+
bool
|
596
|
+
DC::set_bitmap (const Bitmap& bitmap)
|
597
|
+
{
|
598
|
+
if (!*this) return false;
|
599
|
+
SelectObject(handle(), bitmap.handle());
|
600
|
+
self->bitmap = bitmap;
|
601
|
+
return true;
|
602
|
+
}
|
603
|
+
|
604
|
+
COLORREF
|
605
|
+
DC::text_color () const
|
606
|
+
{
|
607
|
+
return GetTextColor(handle());
|
608
|
+
}
|
609
|
+
|
610
|
+
bool
|
611
|
+
DC::set_text_color (COLORREF color)
|
612
|
+
{
|
613
|
+
if (!*this) return false;
|
614
|
+
SetTextColor(handle(), color);
|
615
|
+
return true;
|
616
|
+
}
|
617
|
+
|
618
|
+
COLORREF
|
619
|
+
DC::back_color () const
|
620
|
+
{
|
621
|
+
return GetBkColor(handle());
|
622
|
+
}
|
623
|
+
|
624
|
+
bool
|
625
|
+
DC::set_back_color (COLORREF color)
|
626
|
+
{
|
627
|
+
if (!*this) return false;
|
628
|
+
SetBkColor(handle(), color);
|
629
|
+
return true;
|
630
|
+
}
|
631
|
+
|
632
|
+
int
|
633
|
+
DC::back_mode () const
|
634
|
+
{
|
635
|
+
return GetBkMode(handle());
|
636
|
+
}
|
637
|
+
|
638
|
+
bool
|
639
|
+
DC::set_back_mode (int mode)
|
640
|
+
{
|
641
|
+
if (!*this) return false;
|
642
|
+
SetBkMode(handle(), mode);
|
643
|
+
return true;
|
644
|
+
}
|
645
|
+
|
646
|
+
bool
|
647
|
+
DC::push ()
|
648
|
+
{
|
649
|
+
if (!*this) return false;
|
650
|
+
|
651
|
+
self->stack.push_back(DCState());
|
652
|
+
return self->stack.back().init(
|
653
|
+
self->handle.handle(),
|
654
|
+
self->pen,
|
655
|
+
self->brush,
|
656
|
+
self->font,
|
657
|
+
self->bitmap);
|
658
|
+
}
|
659
|
+
|
660
|
+
bool
|
661
|
+
DC::pop ()
|
662
|
+
{
|
663
|
+
if (!*this || self->stack.empty()) return false;
|
664
|
+
|
665
|
+
HDC hdc = self->handle.handle();
|
666
|
+
DCState& state = self->stack.back();
|
667
|
+
|
668
|
+
SelectObject(hdc, state.hpen);
|
669
|
+
SelectObject(hdc, state.hbrush);
|
670
|
+
SelectObject(hdc, state.hfont);
|
671
|
+
SelectObject(hdc, state.hbitmap);
|
672
|
+
SetTextColor(hdc, state.textcolor);
|
673
|
+
SetBkColor(hdc, state.backcolor);
|
674
|
+
SetBkMode(hdc, state.backmode);
|
675
|
+
self->pen = state.pen;
|
676
|
+
self->brush = state.brush;
|
677
|
+
self->font = state.font;
|
678
|
+
self->bitmap = state.bitmap;
|
679
|
+
|
680
|
+
self->stack.pop_back();
|
681
|
+
return true;
|
682
|
+
}
|
683
|
+
|
684
|
+
HDC
|
685
|
+
DC::handle () const
|
686
|
+
{
|
687
|
+
return self->handle.handle();
|
688
|
+
}
|
689
|
+
|
690
|
+
DC::operator bool () const
|
691
|
+
{
|
692
|
+
return !!self->handle;
|
693
|
+
}
|
694
|
+
|
695
|
+
bool
|
696
|
+
DC::operator ! () const
|
697
|
+
{
|
698
|
+
return !operator bool();
|
699
|
+
}
|
700
|
+
|
701
|
+
|
702
|
+
struct MemoryDC::Data
|
703
|
+
{
|
704
|
+
|
705
|
+
Bitmap bitmap, old_bitmap;
|
706
|
+
|
707
|
+
};// MemoryDC::Data
|
708
|
+
|
709
|
+
|
710
|
+
MemoryDC::MemoryDC ()
|
711
|
+
: DC()
|
712
|
+
{
|
713
|
+
}
|
714
|
+
|
715
|
+
MemoryDC::MemoryDC (HDC hdc, int width, int height)
|
716
|
+
: DC(CreateCompatibleDC(hdc), true)
|
717
|
+
{
|
718
|
+
Bitmap bmp = Bitmap(hdc, width, height);
|
719
|
+
if (!bmp) return;
|
720
|
+
|
721
|
+
self->bitmap = bmp;
|
722
|
+
self->old_bitmap = bitmap();
|
723
|
+
|
724
|
+
set_bitmap(self->bitmap);
|
725
|
+
}
|
726
|
+
|
727
|
+
MemoryDC::MemoryDC (HDC hdc, const Bitmap& bmp)
|
728
|
+
: DC(CreateCompatibleDC(hdc), true)
|
729
|
+
{
|
730
|
+
if (!bmp) return;
|
731
|
+
|
732
|
+
self->bitmap = bmp;
|
733
|
+
self->old_bitmap = bitmap();
|
734
|
+
|
735
|
+
set_bitmap(self->bitmap);
|
736
|
+
}
|
737
|
+
|
738
|
+
MemoryDC::~MemoryDC ()
|
739
|
+
{
|
740
|
+
set_bitmap(self->old_bitmap);
|
741
|
+
}
|
742
|
+
|
743
|
+
const Bitmap&
|
744
|
+
MemoryDC::bitmap () const
|
745
|
+
{
|
746
|
+
return self->bitmap;
|
747
|
+
}
|
748
|
+
|
749
|
+
MemoryDC::operator bool () const
|
750
|
+
{
|
751
|
+
return Super::operator bool() && self->bitmap;
|
752
|
+
}
|
753
|
+
|
754
|
+
bool
|
755
|
+
MemoryDC::operator ! () const
|
756
|
+
{
|
757
|
+
return !operator bool();
|
758
|
+
}
|
759
|
+
|
760
|
+
|
761
|
+
DC
|
762
|
+
screen_dc ()
|
763
|
+
{
|
764
|
+
return DC(GetDC(NULL), true, DC::RELEASE_DC);
|
765
|
+
}
|
766
|
+
|
767
|
+
|
768
|
+
}// Win32
|
769
|
+
|
770
|
+
|
771
|
+
}// Rays
|