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.
Files changed (66) hide show
  1. data/ChangeLog +8 -0
  2. data/README +4 -0
  3. data/Rakefile +72 -0
  4. data/VERSION +1 -0
  5. data/ext/rays/bitmap.cpp +322 -0
  6. data/ext/rays/extconf.rb +61 -0
  7. data/ext/rays/font.cpp +125 -0
  8. data/ext/rays/image.cpp +166 -0
  9. data/ext/rays/native.cpp +24 -0
  10. data/ext/rays/painter.cpp +573 -0
  11. data/ext/rays/rays.cpp +61 -0
  12. data/ext/rays/rays.h +39 -0
  13. data/ext/rays/texture.cpp +130 -0
  14. data/include/rays.h +20 -0
  15. data/include/rays/bitmap.h +80 -0
  16. data/include/rays/colorspace.h +101 -0
  17. data/include/rays/defs.h +33 -0
  18. data/include/rays/font.h +49 -0
  19. data/include/rays/helpers.h +37 -0
  20. data/include/rays/image.h +68 -0
  21. data/include/rays/opengl.h +15 -0
  22. data/include/rays/painter.h +179 -0
  23. data/include/rays/rays.h +19 -0
  24. data/include/rays/ruby.h +15 -0
  25. data/include/rays/ruby/bitmap.h +39 -0
  26. data/include/rays/ruby/font.h +39 -0
  27. data/include/rays/ruby/image.h +39 -0
  28. data/include/rays/ruby/painter.h +39 -0
  29. data/include/rays/ruby/rays.h +21 -0
  30. data/include/rays/ruby/texture.h +39 -0
  31. data/include/rays/texture.h +56 -0
  32. data/include/rays/transform.h +35 -0
  33. data/lib/rays.rb +9 -0
  34. data/lib/rays/autoinit.rb +10 -0
  35. data/lib/rays/bitmap.rb +25 -0
  36. data/lib/rays/image.rb +15 -0
  37. data/lib/rays/module.rb +30 -0
  38. data/lib/rays/painter.rb +99 -0
  39. data/lib/rays/texture.rb +15 -0
  40. data/rays.gemspec +54 -0
  41. data/src/cocoa/bitmap.mm +286 -0
  42. data/src/cocoa/font.mm +193 -0
  43. data/src/cocoa/helpers.h +26 -0
  44. data/src/cocoa/helpers.mm +25 -0
  45. data/src/cocoa/rays.mm +40 -0
  46. data/src/colorspace.cpp +183 -0
  47. data/src/helpers.cpp +22 -0
  48. data/src/image.cpp +133 -0
  49. data/src/painter.cpp +769 -0
  50. data/src/texture.cpp +360 -0
  51. data/src/transform.cpp +88 -0
  52. data/src/win32/bitmap.cpp +212 -0
  53. data/src/win32/font.cpp +99 -0
  54. data/src/win32/gdi.cpp +771 -0
  55. data/src/win32/gdi.h +226 -0
  56. data/src/win32/rays.cpp +36 -0
  57. data/support.rb +58 -0
  58. data/task/ext.rake +41 -0
  59. data/task/gem.rake +33 -0
  60. data/task/git.rake +22 -0
  61. data/task/lib.rake +54 -0
  62. data/test/helpers.rb +15 -0
  63. data/test/test_painter.rb +11 -0
  64. data/test/test_rays.rb +19 -0
  65. data/test/test_texture.rb +11 -0
  66. metadata +153 -0
@@ -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