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/texture.cpp
ADDED
@@ -0,0 +1,360 @@
|
|
1
|
+
#include "rays/texture.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include <boost/scoped_array.hpp>
|
5
|
+
#include <rays/bitmap.h>
|
6
|
+
|
7
|
+
|
8
|
+
namespace Rays
|
9
|
+
{
|
10
|
+
|
11
|
+
|
12
|
+
struct Texture::Data
|
13
|
+
{
|
14
|
+
|
15
|
+
Bitmap bitmap;
|
16
|
+
|
17
|
+
int id, width, height;
|
18
|
+
|
19
|
+
Data ()
|
20
|
+
: id(-1), width(0), height(0)
|
21
|
+
{
|
22
|
+
}
|
23
|
+
|
24
|
+
~Data ()
|
25
|
+
{
|
26
|
+
clear();
|
27
|
+
}
|
28
|
+
|
29
|
+
void clear ()
|
30
|
+
{
|
31
|
+
if (id >= 0)
|
32
|
+
{
|
33
|
+
GLenum id_ = id;
|
34
|
+
glDeleteTextures(1, &id_);
|
35
|
+
}
|
36
|
+
|
37
|
+
bitmap = Bitmap();
|
38
|
+
id = -1;
|
39
|
+
width = height = 0;
|
40
|
+
}
|
41
|
+
|
42
|
+
};// Texture::Data
|
43
|
+
|
44
|
+
|
45
|
+
static bool
|
46
|
+
get_component_type (GLenum* result, ColorSpace cs)
|
47
|
+
{
|
48
|
+
if (!result || !cs) return false;
|
49
|
+
|
50
|
+
if (cs.is_float())
|
51
|
+
*result = GL_FLOAT;
|
52
|
+
else
|
53
|
+
{
|
54
|
+
switch (cs.bpc())
|
55
|
+
{
|
56
|
+
case 8: *result = GL_UNSIGNED_BYTE; break;
|
57
|
+
case 16: *result = GL_UNSIGNED_SHORT; break;
|
58
|
+
case 32: *result = GL_UNSIGNED_INT; break;
|
59
|
+
default: return false;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
return true;
|
63
|
+
}
|
64
|
+
|
65
|
+
static bool
|
66
|
+
create_texture (Texture::Data* self, GLenum format)
|
67
|
+
{
|
68
|
+
if (!self || !self->bitmap) return false;
|
69
|
+
|
70
|
+
GLenum type;
|
71
|
+
if (!get_component_type(&type, self->bitmap.color_space()))
|
72
|
+
return false;
|
73
|
+
|
74
|
+
GLuint id = 0;
|
75
|
+
glGenTextures(1, &id);
|
76
|
+
glBindTexture(GL_TEXTURE_2D, id);
|
77
|
+
if (glIsTexture(id) == GL_FALSE)
|
78
|
+
return false;
|
79
|
+
|
80
|
+
self->id = id;
|
81
|
+
|
82
|
+
glTexImage2D(
|
83
|
+
GL_TEXTURE_2D, 0, format, self->bitmap.width(), self->bitmap.height(), 0,
|
84
|
+
format, type, self->bitmap.data());
|
85
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//GL_LINEAR);
|
86
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//GL_LINEAR);
|
87
|
+
|
88
|
+
return true;
|
89
|
+
}
|
90
|
+
|
91
|
+
static int
|
92
|
+
min_pow2 (int num)
|
93
|
+
{
|
94
|
+
int n = 1;
|
95
|
+
while (n < num) n *= 2;
|
96
|
+
return n;
|
97
|
+
}
|
98
|
+
|
99
|
+
static bool
|
100
|
+
colorspace_for_alphabitmap (ColorSpace* result, ColorSpace cs)
|
101
|
+
{
|
102
|
+
if (!result || !cs) return false;
|
103
|
+
|
104
|
+
*result = COLORSPACE_UNKNOWN;
|
105
|
+
|
106
|
+
if (cs.is_float())
|
107
|
+
*result = GRAY_float;
|
108
|
+
else
|
109
|
+
{
|
110
|
+
switch (cs.bpc())
|
111
|
+
{
|
112
|
+
case 8: *result = GRAY_8; break;
|
113
|
+
case 16: *result = GRAY_16; break;
|
114
|
+
case 24: *result = GRAY_24; break;
|
115
|
+
case 32: *result = GRAY_32; break;
|
116
|
+
default: return false;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
return true;
|
121
|
+
}
|
122
|
+
|
123
|
+
template <int BytesPerPixel>
|
124
|
+
static inline void
|
125
|
+
copy_pixel (uchar* dest, const uchar* src)
|
126
|
+
{
|
127
|
+
*dest = *src;
|
128
|
+
copy_pixel<BytesPerPixel - 1>(dest + 1, src + 1);
|
129
|
+
}
|
130
|
+
|
131
|
+
template <>
|
132
|
+
inline void
|
133
|
+
copy_pixel<1> (uchar* dest, const uchar* src)
|
134
|
+
{
|
135
|
+
*dest = *src;
|
136
|
+
}
|
137
|
+
|
138
|
+
template <>
|
139
|
+
inline void
|
140
|
+
copy_pixel<2> (uchar* dest, const uchar* src)
|
141
|
+
{
|
142
|
+
assert(sizeof(ushort) == 2);
|
143
|
+
*(ushort*) dest = *(ushort*) src;
|
144
|
+
}
|
145
|
+
|
146
|
+
template <>
|
147
|
+
inline void
|
148
|
+
copy_pixel<4> (uchar* dest, const uchar* src)
|
149
|
+
{
|
150
|
+
assert(sizeof(ulong) == 4);
|
151
|
+
*(ulong*) dest = *(ulong*) src;
|
152
|
+
}
|
153
|
+
|
154
|
+
template <int BytesPerPixel>
|
155
|
+
static inline void
|
156
|
+
copy_pixels (
|
157
|
+
size_t width,
|
158
|
+
uchar* dest, size_t dest_offset, const uchar* src, size_t src_offset)
|
159
|
+
{
|
160
|
+
if (!dest || !src || dest_offset <= 0 || src_offset <= 0)
|
161
|
+
return;
|
162
|
+
|
163
|
+
while (width--)
|
164
|
+
{
|
165
|
+
copy_pixel<BytesPerPixel>(dest, src);
|
166
|
+
dest += dest_offset;
|
167
|
+
src += src_offset;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
static inline void
|
172
|
+
copy_pixels (
|
173
|
+
size_t Bpp, size_t width,
|
174
|
+
uchar* dest, size_t dest_offset, const uchar* src, size_t src_offset)
|
175
|
+
{
|
176
|
+
switch (Bpp)
|
177
|
+
{
|
178
|
+
case 1: copy_pixels<1>(width, dest, dest_offset, src, src_offset); break;
|
179
|
+
case 2: copy_pixels<2>(width, dest, dest_offset, src, src_offset); break;
|
180
|
+
case 3: copy_pixels<3>(width, dest, dest_offset, src, src_offset); break;
|
181
|
+
case 4: copy_pixels<4>(width, dest, dest_offset, src, src_offset); break;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
static bool
|
186
|
+
copy_bitmap (Bitmap* dest, const Bitmap& src, int src_offset = 0)
|
187
|
+
{
|
188
|
+
if (!dest || !src || src_offset < 0)
|
189
|
+
return false;
|
190
|
+
|
191
|
+
int src_Bpp = src.color_space().Bpp();
|
192
|
+
int src_Bpc = src.color_space().Bpc();
|
193
|
+
int dest_Bpp = dest->color_space().Bpp();
|
194
|
+
|
195
|
+
if (src_offset >= (src_Bpp / src_Bpc))
|
196
|
+
return false;
|
197
|
+
|
198
|
+
for (int y = 0; y < dest->height(); ++y)
|
199
|
+
{
|
200
|
+
const uchar* s = src. at<uchar>(0, y) + src_offset * src_Bpc;
|
201
|
+
uchar* d = dest->at<uchar>(0, y);
|
202
|
+
copy_pixels(src_Bpp, dest->width(), d, dest_Bpp, s, src_Bpp);
|
203
|
+
}
|
204
|
+
|
205
|
+
return true;
|
206
|
+
}
|
207
|
+
|
208
|
+
static bool
|
209
|
+
create_alpha_texture (Texture::Data* self)
|
210
|
+
{
|
211
|
+
if (!self || !self->bitmap) return false;
|
212
|
+
|
213
|
+
ColorSpace cs = self->bitmap.color_space();
|
214
|
+
int width_pow2 = min_pow2(self->width);
|
215
|
+
int height_pow2 = min_pow2(self->height);
|
216
|
+
|
217
|
+
if (
|
218
|
+
width_pow2 != self->width ||
|
219
|
+
height_pow2 != self->height ||
|
220
|
+
cs.is_rgb() ||
|
221
|
+
cs.is_bgr())
|
222
|
+
{
|
223
|
+
ColorSpace newcs;
|
224
|
+
if (!colorspace_for_alphabitmap(&newcs, cs))
|
225
|
+
return false;
|
226
|
+
|
227
|
+
Bitmap bmp(width_pow2, height_pow2, newcs);
|
228
|
+
if (!bmp) return false;
|
229
|
+
|
230
|
+
if (!copy_bitmap(&bmp, self->bitmap, cs.alpha_pos()))
|
231
|
+
return false;
|
232
|
+
|
233
|
+
self->bitmap = bmp;
|
234
|
+
cs = self->bitmap.color_space();
|
235
|
+
}
|
236
|
+
|
237
|
+
if (!self->bitmap.color_space().is_gray())
|
238
|
+
return false;
|
239
|
+
|
240
|
+
return create_texture(self, GL_ALPHA);
|
241
|
+
}
|
242
|
+
|
243
|
+
static bool
|
244
|
+
create_color_texture (Texture::Data* self)
|
245
|
+
{
|
246
|
+
if (!self || !self->bitmap) return false;
|
247
|
+
|
248
|
+
int width_pow2 = min_pow2(self->width);
|
249
|
+
int height_pow2 = min_pow2(self->height);
|
250
|
+
|
251
|
+
if (
|
252
|
+
width_pow2 != self->width ||
|
253
|
+
height_pow2 != self->height)
|
254
|
+
{
|
255
|
+
Bitmap bmp(
|
256
|
+
width_pow2, height_pow2, self->bitmap.color_space());
|
257
|
+
if (!bmp) return false;
|
258
|
+
|
259
|
+
if (!copy_bitmap(&bmp, self->bitmap))
|
260
|
+
return false;
|
261
|
+
|
262
|
+
self->bitmap = bmp;
|
263
|
+
}
|
264
|
+
|
265
|
+
ColorSpace cs = self->bitmap.color_space();
|
266
|
+
|
267
|
+
bool alpha = cs.has_alpha();
|
268
|
+
if (cs.is_rgb())
|
269
|
+
return create_texture(self, alpha ? GL_RGBA : GL_RGB);
|
270
|
+
else if (cs.is_bgr())
|
271
|
+
return create_texture(self, alpha ? GL_BGRA : GL_BGR);
|
272
|
+
else if (cs.is_gray())
|
273
|
+
return create_texture(self, GL_LUMINANCE);
|
274
|
+
else
|
275
|
+
return false;
|
276
|
+
}
|
277
|
+
|
278
|
+
static bool
|
279
|
+
setup_texture (
|
280
|
+
Texture::Data* self, const Bitmap& bitmap, bool alphaonly = false)
|
281
|
+
{
|
282
|
+
if (!self || !bitmap) return false;
|
283
|
+
|
284
|
+
self->clear();
|
285
|
+
|
286
|
+
self->bitmap = bitmap;
|
287
|
+
if (!self->bitmap) return false;
|
288
|
+
|
289
|
+
self->width = self->bitmap.width();
|
290
|
+
self->height = self->bitmap.height();
|
291
|
+
|
292
|
+
if (alphaonly)
|
293
|
+
return create_alpha_texture(self);
|
294
|
+
else
|
295
|
+
return create_color_texture(self);
|
296
|
+
}
|
297
|
+
|
298
|
+
|
299
|
+
Texture::Texture ()
|
300
|
+
{
|
301
|
+
}
|
302
|
+
|
303
|
+
Texture::Texture (const Bitmap& bitmap, bool alphaonly)
|
304
|
+
{
|
305
|
+
setup_texture(self.get(), bitmap, alphaonly);
|
306
|
+
}
|
307
|
+
|
308
|
+
Texture::~Texture ()
|
309
|
+
{
|
310
|
+
}
|
311
|
+
|
312
|
+
GLuint
|
313
|
+
Texture::id () const
|
314
|
+
{
|
315
|
+
return self->id;
|
316
|
+
}
|
317
|
+
|
318
|
+
int
|
319
|
+
Texture::width () const
|
320
|
+
{
|
321
|
+
return self->width;
|
322
|
+
}
|
323
|
+
|
324
|
+
int
|
325
|
+
Texture::height () const
|
326
|
+
{
|
327
|
+
return self->height;
|
328
|
+
}
|
329
|
+
|
330
|
+
float
|
331
|
+
Texture::s_max () const
|
332
|
+
{
|
333
|
+
return (float) self->width / (float) self->bitmap.width();
|
334
|
+
}
|
335
|
+
|
336
|
+
float
|
337
|
+
Texture::t_max () const
|
338
|
+
{
|
339
|
+
return (float) self->height / (float) self->bitmap.height();
|
340
|
+
}
|
341
|
+
|
342
|
+
const Bitmap&
|
343
|
+
Texture::bitmap () const
|
344
|
+
{
|
345
|
+
return self->bitmap;
|
346
|
+
}
|
347
|
+
|
348
|
+
Texture::operator bool () const
|
349
|
+
{
|
350
|
+
return self->id >= 0 && self->width > 0 && self->height > 0;
|
351
|
+
}
|
352
|
+
|
353
|
+
bool
|
354
|
+
Texture::operator ! () const
|
355
|
+
{
|
356
|
+
return !operator bool();
|
357
|
+
}
|
358
|
+
|
359
|
+
|
360
|
+
}// Rays
|
data/src/transform.cpp
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#include "rays/painter.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include "rays/opengl.h"
|
5
|
+
|
6
|
+
|
7
|
+
namespace Rays
|
8
|
+
{
|
9
|
+
|
10
|
+
|
11
|
+
static bool
|
12
|
+
is_error ()
|
13
|
+
{
|
14
|
+
GLenum e = glGetError();
|
15
|
+
return e == GL_INVALID_OPERATION;
|
16
|
+
}
|
17
|
+
|
18
|
+
static bool
|
19
|
+
is_error (GLenum error)
|
20
|
+
{
|
21
|
+
GLenum e = glGetError();
|
22
|
+
return e == GL_INVALID_OPERATION || e == error;
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
bool
|
27
|
+
translate (coord x, coord y, coord z)
|
28
|
+
{
|
29
|
+
glTranslatef(x, y, z);
|
30
|
+
return !is_error();
|
31
|
+
}
|
32
|
+
|
33
|
+
bool
|
34
|
+
scale (coord x, coord y, coord z)
|
35
|
+
{
|
36
|
+
glScalef(x, y, z);
|
37
|
+
return !is_error();
|
38
|
+
}
|
39
|
+
|
40
|
+
bool
|
41
|
+
rotate (float angle, coord x, coord y, coord z)
|
42
|
+
{
|
43
|
+
glRotatef(angle, x, y, z);
|
44
|
+
return !is_error();
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
bool
|
49
|
+
set_matrix (coord value)
|
50
|
+
{
|
51
|
+
glLoadIdentity();
|
52
|
+
if (is_error()) return false;
|
53
|
+
if (value == 1) return true;
|
54
|
+
return scale(value, value, value);
|
55
|
+
}
|
56
|
+
|
57
|
+
bool
|
58
|
+
set_matrix (const coord* elements, size_t size)
|
59
|
+
{
|
60
|
+
if (!elements || size != 16) return false;
|
61
|
+
glLoadMatrixf(elements);
|
62
|
+
return !is_error();
|
63
|
+
}
|
64
|
+
|
65
|
+
bool
|
66
|
+
get_matrix (coord* elements, size_t size)
|
67
|
+
{
|
68
|
+
if (!elements || size != 16) return false;
|
69
|
+
glGetFloatv(GL_MODELVIEW_MATRIX, elements);
|
70
|
+
return !is_error(GL_INVALID_ENUM);
|
71
|
+
}
|
72
|
+
|
73
|
+
bool
|
74
|
+
push_matrix ()
|
75
|
+
{
|
76
|
+
glPushMatrix();
|
77
|
+
return !is_error(GL_STACK_OVERFLOW);
|
78
|
+
}
|
79
|
+
|
80
|
+
bool
|
81
|
+
pop_matrix ()
|
82
|
+
{
|
83
|
+
glPopMatrix();
|
84
|
+
return !is_error(GL_STACK_UNDERFLOW);
|
85
|
+
}
|
86
|
+
|
87
|
+
|
88
|
+
}// Rays
|
@@ -0,0 +1,212 @@
|
|
1
|
+
#include "rays/bitmap.h"
|
2
|
+
|
3
|
+
|
4
|
+
#include "gdi.h"
|
5
|
+
|
6
|
+
|
7
|
+
namespace Rays
|
8
|
+
{
|
9
|
+
|
10
|
+
|
11
|
+
struct Bitmap::Data
|
12
|
+
{
|
13
|
+
|
14
|
+
int width, height, pitch;
|
15
|
+
|
16
|
+
ColorSpace colorspace;
|
17
|
+
|
18
|
+
void* pixels;
|
19
|
+
|
20
|
+
Win32::MemoryDC memdc;
|
21
|
+
|
22
|
+
bool dirty;
|
23
|
+
|
24
|
+
Data ()
|
25
|
+
: pixels(NULL), dirty(true)
|
26
|
+
{
|
27
|
+
}
|
28
|
+
|
29
|
+
};// Window::Data
|
30
|
+
|
31
|
+
|
32
|
+
static bool
|
33
|
+
init_bitmap_pixels (Bitmap* bmp)
|
34
|
+
{
|
35
|
+
if (!*bmp) return false;
|
36
|
+
|
37
|
+
memset(bmp->data(), 0, bmp->size());
|
38
|
+
|
39
|
+
if (!bmp->color_space().has_alpha())
|
40
|
+
return true;
|
41
|
+
|
42
|
+
int Bpp = bmp->color_space().Bpp();
|
43
|
+
for (int y = 0; y < bmp->height(); ++y)
|
44
|
+
{
|
45
|
+
unsigned char* p =
|
46
|
+
bmp->at<unsigned char>(0, y) + bmp->color_space().alpha_pos();
|
47
|
+
int w = bmp->width();
|
48
|
+
while (w--)
|
49
|
+
{
|
50
|
+
*p = 255;
|
51
|
+
p += Bpp;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
return true;
|
56
|
+
}
|
57
|
+
|
58
|
+
static bool
|
59
|
+
setup (Bitmap* bmp, int w, int h, const ColorSpace& cs, HDC hdc = NULL)
|
60
|
+
{
|
61
|
+
if (w <= 0 || h <= 0 || !cs || !bmp || *bmp)
|
62
|
+
return false;
|
63
|
+
|
64
|
+
Bitmap::Data* self = bmp->self.get();
|
65
|
+
|
66
|
+
self->width = w;
|
67
|
+
self->height = h;
|
68
|
+
self->colorspace = cs;
|
69
|
+
self->pitch = self->width * self->colorspace.Bpp();
|
70
|
+
|
71
|
+
int padding = 4 - self->pitch % 4;
|
72
|
+
if (padding < 4) self->pitch += padding;
|
73
|
+
|
74
|
+
BITMAPINFO bmpinfo;
|
75
|
+
memset(&bmpinfo, 0, sizeof(bmpinfo));
|
76
|
+
|
77
|
+
BITMAPINFOHEADER& header = bmpinfo.bmiHeader;
|
78
|
+
header.biSize = sizeof(BITMAPINFOHEADER);
|
79
|
+
header.biWidth = self->width;
|
80
|
+
header.biHeight = self->height;
|
81
|
+
header.biPlanes = 1;
|
82
|
+
header.biBitCount = self->colorspace.bpp();
|
83
|
+
header.biCompression = BI_RGB;
|
84
|
+
|
85
|
+
Win32::DC dc = hdc ? Win32::DC(hdc) : Win32::screen_dc();
|
86
|
+
|
87
|
+
HBITMAP hbmp = CreateDIBSection(
|
88
|
+
dc.handle(), &bmpinfo, DIB_RGB_COLORS, (void**) &self->pixels, NULL, 0);
|
89
|
+
if (!hbmp) return false;
|
90
|
+
|
91
|
+
self->memdc = Win32::MemoryDC(dc.handle(), Win32::Bitmap(hbmp, true));
|
92
|
+
if (!self->memdc) return false;
|
93
|
+
|
94
|
+
return init_bitmap_pixels(bmp);
|
95
|
+
}
|
96
|
+
|
97
|
+
|
98
|
+
Bitmap::Bitmap ()
|
99
|
+
{
|
100
|
+
}
|
101
|
+
|
102
|
+
Bitmap::Bitmap (int width, int height, const ColorSpace& cs)
|
103
|
+
{
|
104
|
+
setup(this, width, height, cs);
|
105
|
+
}
|
106
|
+
|
107
|
+
Bitmap::~Bitmap ()
|
108
|
+
{
|
109
|
+
}
|
110
|
+
|
111
|
+
int
|
112
|
+
Bitmap::width () const
|
113
|
+
{
|
114
|
+
return self->width;
|
115
|
+
}
|
116
|
+
|
117
|
+
int
|
118
|
+
Bitmap::height () const
|
119
|
+
{
|
120
|
+
return self->height;
|
121
|
+
}
|
122
|
+
|
123
|
+
const ColorSpace&
|
124
|
+
Bitmap::color_space () const
|
125
|
+
{
|
126
|
+
return self->colorspace;
|
127
|
+
}
|
128
|
+
|
129
|
+
int
|
130
|
+
Bitmap::pitch () const
|
131
|
+
{
|
132
|
+
return self->pitch;
|
133
|
+
}
|
134
|
+
|
135
|
+
size_t
|
136
|
+
Bitmap::size () const
|
137
|
+
{
|
138
|
+
return pitch() * height();
|
139
|
+
}
|
140
|
+
|
141
|
+
bool
|
142
|
+
Bitmap::dirty () const
|
143
|
+
{
|
144
|
+
return self->dirty;
|
145
|
+
}
|
146
|
+
|
147
|
+
void
|
148
|
+
Bitmap::set_dirty (bool b)
|
149
|
+
{
|
150
|
+
self->dirty = b;
|
151
|
+
}
|
152
|
+
|
153
|
+
void*
|
154
|
+
Bitmap::data ()
|
155
|
+
{
|
156
|
+
return self->pixels;
|
157
|
+
}
|
158
|
+
|
159
|
+
const void*
|
160
|
+
Bitmap::data () const
|
161
|
+
{
|
162
|
+
return const_cast<Bitmap*>(this)->data();
|
163
|
+
}
|
164
|
+
|
165
|
+
Bitmap::operator bool () const
|
166
|
+
{
|
167
|
+
return
|
168
|
+
self &&
|
169
|
+
self->width > 0 && self->height > 0 && self->pitch > 0 &&
|
170
|
+
self->colorspace && self->pixels && self->memdc;
|
171
|
+
}
|
172
|
+
|
173
|
+
bool
|
174
|
+
Bitmap::operator ! () const
|
175
|
+
{
|
176
|
+
return !operator bool();
|
177
|
+
}
|
178
|
+
|
179
|
+
|
180
|
+
bool
|
181
|
+
load_bitmap (Bitmap* bitmap, const char* path)
|
182
|
+
{
|
183
|
+
return false;
|
184
|
+
}
|
185
|
+
|
186
|
+
bool
|
187
|
+
save_bitmap (const Bitmap& bitmap, const char* path)
|
188
|
+
{
|
189
|
+
return false;
|
190
|
+
}
|
191
|
+
|
192
|
+
|
193
|
+
bool draw_string (
|
194
|
+
HDC, coord, const char*, coord, coord, const Font&);
|
195
|
+
|
196
|
+
bool
|
197
|
+
draw_string (
|
198
|
+
Bitmap* bmp, const char* str, coord x, coord y, const Font& font)
|
199
|
+
{
|
200
|
+
if (!bmp || !*bmp || !str || !font) return false;
|
201
|
+
|
202
|
+
if (*str == '\0') return true;
|
203
|
+
|
204
|
+
if (!draw_string(bmp->self->memdc.handle(), bmp->height(), str, x, y, font))
|
205
|
+
return false;
|
206
|
+
|
207
|
+
bmp->set_dirty();
|
208
|
+
return true;
|
209
|
+
}
|
210
|
+
|
211
|
+
|
212
|
+
}// Rays
|