rays 0.3.9 → 0.3.11

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/rays/bounds.cpp +1 -1
  3. data/.doc/ext/rays/font.cpp +23 -5
  4. data/.doc/ext/rays/image.cpp +1 -1
  5. data/.doc/ext/rays/native.cpp +1 -5
  6. data/.doc/ext/rays/painter.cpp +1 -1
  7. data/.doc/ext/rays/polygon.cpp +1 -1
  8. data/.github/workflows/release-gem.yml +1 -1
  9. data/.github/workflows/test.yml +4 -4
  10. data/CLAUDE.md +25 -0
  11. data/ChangeLog.md +17 -0
  12. data/Gemfile.lock +6 -5
  13. data/Rakefile +4 -2
  14. data/VERSION +1 -1
  15. data/ext/rays/bounds.cpp +1 -1
  16. data/ext/rays/extconf.rb +4 -3
  17. data/ext/rays/font.cpp +27 -7
  18. data/ext/rays/image.cpp +1 -1
  19. data/ext/rays/native.cpp +1 -5
  20. data/ext/rays/painter.cpp +1 -1
  21. data/ext/rays/polygon.cpp +1 -1
  22. data/include/rays/font.h +5 -1
  23. data/include/rays/painter.h +1 -1
  24. data/lib/rays/ext.rb +1 -1
  25. data/lib/rays/image.rb +5 -0
  26. data/rays.gemspec +2 -2
  27. data/src/bitmap.h +6 -1
  28. data/src/color_space.cpp +1 -41
  29. data/src/font.cpp +17 -1
  30. data/src/image.cpp +0 -1
  31. data/src/ios/bitmap.mm +20 -35
  32. data/src/ios/rays.mm +3 -3
  33. data/src/opengl/bitmap.cpp +41 -0
  34. data/src/opengl/color_space.cpp +51 -0
  35. data/src/{color_space.h → opengl/color_space.h} +2 -2
  36. data/src/{frame_buffer.cpp → opengl/frame_buffer.cpp} +1 -1
  37. data/src/{frame_buffer.h → opengl/frame_buffer.h} +2 -2
  38. data/src/{ios → opengl/ios}/opengl.mm +3 -3
  39. data/src/{opengl.h → opengl/opengl.h} +3 -7
  40. data/src/{osx → opengl/osx}/opengl.mm +3 -3
  41. data/src/opengl/painter.cpp +756 -0
  42. data/src/{render_buffer.h → opengl/render_buffer.h} +2 -2
  43. data/src/opengl/sdl/opengl.cpp +103 -0
  44. data/src/{shader.cpp → opengl/shader.cpp} +1 -2
  45. data/src/{shader.h → opengl/shader.h} +2 -2
  46. data/src/{shader_program.cpp → opengl/shader_program.cpp} +3 -3
  47. data/src/{shader_program.h → opengl/shader_program.h} +2 -2
  48. data/src/{shader_source.h → opengl/shader_source.h} +2 -2
  49. data/src/{texture.cpp → opengl/texture.cpp} +2 -3
  50. data/src/opengl/texture.h +21 -0
  51. data/src/{win32 → opengl/win32}/opengl.cpp +4 -4
  52. data/src/osx/bitmap.mm +20 -36
  53. data/src/osx/rays.mm +3 -3
  54. data/src/painter.cpp +28 -910
  55. data/src/painter.h +210 -11
  56. data/src/polygon.cpp +38 -13
  57. data/src/renderer.h +22 -0
  58. data/src/sdl/bitmap.cpp +304 -0
  59. data/src/sdl/camera.cpp +119 -0
  60. data/src/sdl/font.cpp +93 -0
  61. data/src/sdl/rays.cpp +50 -0
  62. data/src/texture.h +0 -3
  63. data/src/win32/bitmap.cpp +8 -35
  64. data/src/win32/rays.cpp +3 -3
  65. data/test/test_image.rb +1 -0
  66. metadata +34 -35
  67. /data/src/{opengl.cpp → opengl/opengl.cpp} +0 -0
  68. /data/src/{render_buffer.cpp → opengl/render_buffer.cpp} +0 -0
  69. /data/src/{shader_source.cpp → opengl/shader_source.cpp} +0 -0
data/src/painter.h CHANGED
@@ -4,26 +4,225 @@
4
4
  #define __RAYS_SRC_PAINTER_H__
5
5
 
6
6
 
7
+ #include <vector>
7
8
  #include "rays/painter.h"
8
- #include "opengl.h"
9
+ #include "rays/bounds.h"
10
+ #include "rays/color.h"
11
+ #include "rays/font.h"
12
+ #include "rays/image.h"
13
+ #include "rays/shader.h"
14
+ #include "matrix.h"
15
+ #include "texture.h"
9
16
 
10
17
 
11
18
  namespace Rays
12
19
  {
13
20
 
14
21
 
15
- void Painter_draw (
16
- Painter* painter, GLenum mode, const Color& color,
17
- const Coord3* points, size_t npoints,
18
- const uint* indices = NULL, size_t nindices = 0,
19
- const Coord3* texcoords = NULL);
22
+ enum ColorType
23
+ {
24
+
25
+ FILL = 0,
26
+
27
+ STROKE,
28
+
29
+ COLOR_TYPE_MAX
30
+
31
+ };// ColorType
32
+
33
+
34
+ enum PrimitiveMode
35
+ {
36
+
37
+ MODE_NONE = -1,
38
+
39
+ MODE_POINTS = 0x0,
40
+
41
+ MODE_LINES = 0x1,
42
+
43
+ MODE_LINE_LOOP = 0x2,
44
+
45
+ MODE_LINE_STRIP = 0x3,
46
+
47
+ MODE_TRIANGLES = 0x4,
48
+
49
+ MODE_TRIANGLE_STRIP = 0x5,
50
+
51
+ MODE_TRIANGLE_FAN = 0x6,
52
+
53
+ MODE_QUADS = 0x7,
54
+
55
+ MODE_QUAD_STRIP = 0x8,
56
+
57
+ MODE_POLYGON = 0x9,
58
+
59
+ };// PrimitiveMode
60
+
61
+
62
+ struct State
63
+ {
64
+
65
+ Color background, colors[COLOR_TYPE_MAX];
66
+
67
+ bool nocolors[COLOR_TYPE_MAX];
68
+
69
+ coord stroke_width;
70
+
71
+ float stroke_outset;
72
+
73
+ CapType stroke_cap;
74
+
75
+ JoinType stroke_join;
76
+
77
+ coord miter_limit;
78
+
79
+ uint nsegment;
80
+
81
+ coord line_height;
82
+
83
+ BlendMode blend_mode;
84
+
85
+ Bounds clip;
86
+
87
+ Font font;
88
+
89
+ Image texture;
90
+
91
+ TexCoordMode texcoord_mode;
92
+
93
+ TexCoordWrap texcoord_wrap;
94
+
95
+ Shader shader;
96
+
97
+ void init ()
98
+ {
99
+ background .reset(0, 0);
100
+ colors[FILL] .reset(1, 1);
101
+ colors[STROKE] .reset(1, 0);
102
+ nocolors[FILL] = false;
103
+ nocolors[STROKE] = true;
104
+ stroke_width = 0;
105
+ stroke_outset = 0;
106
+ stroke_cap = CAP_DEFAULT;
107
+ stroke_join = JOIN_DEFAULT;
108
+ miter_limit = JOIN_DEFAULT_MITER_LIMIT;
109
+ nsegment = 0;
110
+ line_height = -1;
111
+ blend_mode = BLEND_NORMAL;
112
+ clip .reset(-1);
113
+ font = get_default_font();
114
+ texture = Image();
115
+ texcoord_mode = TEXCOORD_IMAGE;
116
+ texcoord_wrap = TEXCOORD_CLAMP;
117
+ shader = Shader();
118
+ }
119
+
120
+ bool get_color (Color* color, ColorType type) const
121
+ {
122
+ const Color& c = colors[type];
123
+ if (blend_mode == BLEND_REPLACE ? nocolors[type] : !c)
124
+ return false;
125
+
126
+ *color = c;
127
+ return true;
128
+ }
129
+
130
+ bool has_color () const
131
+ {
132
+ if (blend_mode == BLEND_REPLACE)
133
+ return !nocolors[FILL] || !nocolors[STROKE];
134
+ else
135
+ return colors[FILL] || colors[STROKE];
136
+ }
137
+
138
+ };// State
139
+
140
+
141
+ struct TextureInfo
142
+ {
143
+
144
+ const Texture& texture;
145
+
146
+ Point min, max;
147
+
148
+ TextureInfo (
149
+ const Texture& texture,
150
+ coord x_min, coord y_min,
151
+ coord x_max, coord y_max)
152
+ : texture(texture)
153
+ {
154
+ min.reset(x_min, y_min);
155
+ max.reset(x_max, y_max);
156
+ }
157
+
158
+ operator bool () const
159
+ {
160
+ return
161
+ texture &&
162
+ min.x < max.x &&
163
+ min.y < max.y;
164
+ }
165
+
166
+ bool operator ! () const
167
+ {
168
+ return !operator bool();
169
+ }
170
+
171
+ };// TextureInfo
172
+
173
+
174
+ struct Painter::Data
175
+ {
176
+
177
+ bool painting = false;
178
+
179
+ float pixel_density = 1;
180
+
181
+ Bounds viewport;
182
+
183
+ State state;
184
+
185
+ std::vector<State> state_stack;
186
+
187
+ Matrix position_matrix;
188
+
189
+ std::vector<Matrix> position_matrix_stack;
190
+
191
+ Image text_image;
192
+
193
+ Data ()
194
+ {
195
+ state.init();
196
+ }
197
+
198
+ virtual ~Data () = default;
199
+
200
+ void set_pixel_density (float density);
201
+
202
+ };// Painter::Data
203
+
204
+
205
+ void Painter_update_clip (Painter* painter);
20
206
 
21
207
  void Painter_draw (
22
- Painter* painter, GLenum mode,
23
- const Coord3* points, size_t npoints,
24
- const uint* indices = NULL, size_t nindices = 0,
25
- const Color* colors = NULL,
26
- const Coord3* texcoords = NULL);
208
+ Painter* painter, PrimitiveMode mode, const Color* color,
209
+ const Coord3* points, size_t npoints,
210
+ const uint* indices = NULL, size_t nindices = 0,
211
+ const Color* colors = NULL,
212
+ const Coord3* texcoords = NULL,
213
+ const TextureInfo* texinfo = NULL,
214
+ const Shader* shader = NULL);
215
+
216
+ void Painter_draw_image (
217
+ Painter* painter, const Image& image,
218
+ coord src_x, coord src_y, coord src_w, coord src_h,
219
+ coord dst_x, coord dst_y, coord dst_w, coord dst_h,
220
+ bool nofill = false, bool nostroke = false,
221
+ const Shader* shader = NULL);
222
+
223
+ void Painter_draw_text_line (
224
+ Painter* painter, const Font& font, const char* line, coord x, coord y,
225
+ coord width = 0, coord height = 0);
27
226
 
28
227
 
29
228
  }// Rays
data/src/polygon.cpp CHANGED
@@ -50,6 +50,32 @@ namespace Rays
50
50
  {
51
51
 
52
52
 
53
+ static void
54
+ draw_polygon (
55
+ Painter* painter, PrimitiveMode mode, const Color& color,
56
+ const Coord3* points, size_t npoints,
57
+ const uint* indices = NULL, size_t nindices = 0,
58
+ const Coord3* texcoords = NULL)
59
+ {
60
+ Painter_draw(
61
+ painter, mode, &color, points, npoints, indices, nindices,
62
+ NULL, texcoords);
63
+ }
64
+
65
+ static void
66
+ draw_polygon (
67
+ Painter* painter, PrimitiveMode mode,
68
+ const Coord3* points, size_t npoints,
69
+ const uint* indices = NULL, size_t nindices = 0,
70
+ const Color* colors = NULL,
71
+ const Coord3* texcoords = NULL)
72
+ {
73
+ Painter_draw(
74
+ painter, mode, NULL, points, npoints, indices, nindices,
75
+ colors, texcoords);
76
+ }
77
+
78
+
53
79
  class Triangles
54
80
  {
55
81
 
@@ -119,8 +145,8 @@ namespace Rays
119
145
 
120
146
  if (pcolors)
121
147
  {
122
- Painter_draw(
123
- painter, GL_TRIANGLES,
148
+ draw_polygon(
149
+ painter, MODE_TRIANGLES,
124
150
  &points[0], points.size(),
125
151
  &indices[0], indices.size(),
126
152
  &(*pcolors)[0],
@@ -128,8 +154,8 @@ namespace Rays
128
154
  }
129
155
  else
130
156
  {
131
- Painter_draw(
132
- painter, GL_TRIANGLES, color,
157
+ draw_polygon(
158
+ painter, MODE_TRIANGLES, color,
133
159
  &points[0], points.size(),
134
160
  &indices[0], indices.size(),
135
161
  ptexcoords ? &(*ptexcoords)[0] : NULL);
@@ -383,8 +409,8 @@ namespace Rays
383
409
 
384
410
  for (const auto& polyline : polylines)
385
411
  {
386
- Painter_draw(
387
- painter, polyline.loop() ? GL_LINE_LOOP : GL_LINE_STRIP, color,
412
+ draw_polygon(
413
+ painter, polyline.loop() ? MODE_LINE_LOOP : MODE_LINE_STRIP, color,
388
414
  &polyline[0], polyline.size());
389
415
  }
390
416
  }
@@ -666,8 +692,7 @@ namespace Rays
666
692
  invalid_state_error(__FILE__, __LINE__);
667
693
 
668
694
  const auto& outline = polylines[0];
669
- Painter_draw(
670
- painter, GL_TRIANGLE_FAN, color, &outline[0], outline.size());
695
+ draw_polygon(painter, MODE_TRIANGLE_FAN, color, &outline[0], outline.size());
671
696
  }
672
697
 
673
698
  private:
@@ -802,7 +827,7 @@ namespace Rays
802
827
 
803
828
  typedef Polygon::Data Super;
804
829
 
805
- GLenum mode = 0;
830
+ PrimitiveMode mode = MODE_NONE;
806
831
 
807
832
  EllipseData (
808
833
  coord x, coord y, coord width, coord height,
@@ -826,7 +851,7 @@ namespace Rays
826
851
  if (polylines.size() <= 0)
827
852
  invalid_state_error(__FILE__, __LINE__);
828
853
 
829
- if (mode == 0)
854
+ if (mode == MODE_NONE)
830
855
  {
831
856
  Super::fill(painter, color);
832
857
  return;
@@ -836,7 +861,7 @@ namespace Rays
836
861
  invalid_state_error(__FILE__, __LINE__);
837
862
 
838
863
  const auto& outline = polylines[0];
839
- Painter_draw(painter, mode, color, &outline[0], outline.size());
864
+ draw_polygon(painter, mode, color, &outline[0], outline.size());
840
865
  }
841
866
 
842
867
  private:
@@ -867,7 +892,7 @@ namespace Rays
867
892
  float radian_from = Xot::deg2rad(0);
868
893
  float radian_to = Xot::deg2rad(360);
869
894
 
870
- if (!has_hole) mode = GL_TRIANGLE_FAN;
895
+ if (!has_hole) mode = MODE_TRIANGLE_FAN;
871
896
 
872
897
  std::vector<Point> points;
873
898
  points.reserve(nsegment);
@@ -915,7 +940,7 @@ namespace Rays
915
940
  if (!has_hole)
916
941
  {
917
942
  points.emplace_back(x + width / 2, y + height / 2);
918
- mode = GL_TRIANGLE_FAN;
943
+ mode = MODE_TRIANGLE_FAN;
919
944
  }
920
945
 
921
946
  for (uint seg = 0; seg <= nsegment; ++seg)
data/src/renderer.h ADDED
@@ -0,0 +1,22 @@
1
+ // -*- c++ -*-
2
+ #pragma once
3
+ #ifndef __RAYS_SRC_RENDERER_H__
4
+ #define __RAYS_SRC_RENDERER_H__
5
+
6
+
7
+ #include "rays/defs.h"
8
+
9
+
10
+ namespace Rays
11
+ {
12
+
13
+
14
+ void Renderer_init ();
15
+
16
+ void Renderer_fin ();
17
+
18
+
19
+ }// Rays
20
+
21
+
22
+ #endif//EOH
@@ -0,0 +1,304 @@
1
+ #include "../bitmap.h"
2
+
3
+
4
+ #define STB_IMAGE_IMPLEMENTATION
5
+ #include <stb_image.h>
6
+ #define STB_IMAGE_WRITE_IMPLEMENTATION
7
+ #include <stb_image_write.h>
8
+
9
+ #include <SDL.h>
10
+ #include <xot/util.h>
11
+ #include "rays/exception.h"
12
+ #include "../font.h"
13
+ #include "../texture.h"
14
+
15
+
16
+ namespace Rays
17
+ {
18
+
19
+
20
+ struct Bitmap::Data
21
+ {
22
+
23
+ SDL_Surface* surface = NULL;
24
+
25
+ ColorSpace color_space;
26
+
27
+ bool modified;
28
+
29
+ Data ()
30
+ {
31
+ clear();
32
+ }
33
+
34
+ ~Data ()
35
+ {
36
+ clear();
37
+ }
38
+
39
+ void clear ()
40
+ {
41
+ if (surface) SDL_FreeSurface(surface);
42
+
43
+ surface = NULL;
44
+ color_space = COLORSPACE_UNKNOWN;
45
+ modified = false;
46
+ }
47
+
48
+ };// Bitmap::Data
49
+
50
+
51
+ void
52
+ Bitmap_setup (
53
+ Bitmap* bitmap, int w, int h, const ColorSpace& cs,
54
+ const void* pixels, bool clear_pixels)
55
+ {
56
+ if (w <= 0)
57
+ argument_error(__FILE__, __LINE__);
58
+ if (h <= 0)
59
+ argument_error(__FILE__, __LINE__);
60
+ if (!cs)
61
+ argument_error(__FILE__, __LINE__);
62
+
63
+ Bitmap::Data* self = bitmap->self.get();
64
+ self->clear();
65
+
66
+ Uint32 r = 0, g = 0, b = 0, a = 0;
67
+ int depth = 0;
68
+ switch (cs.type())
69
+ {
70
+ case RGB_888:
71
+ case RGBA_8888:
72
+ depth = cs.bpp();
73
+ r = 0x000000FF;
74
+ g = 0x0000FF00;
75
+ b = 0x00FF0000;
76
+ if (depth == 32) a = 0xFF000000;
77
+ break;
78
+
79
+ case GRAY_8:
80
+ depth = 8;
81
+ break;
82
+
83
+ default:
84
+ not_implemented_error(__FILE__, __LINE__, "unsupported color space");
85
+ }
86
+
87
+ self->surface = SDL_CreateRGBSurface(0, w, h, depth, r, g, b, a);
88
+ if (!self->surface)
89
+ rays_error(__FILE__, __LINE__, SDL_GetError());
90
+
91
+ self->color_space = cs;
92
+ self->modified = true;
93
+
94
+ if (pixels)
95
+ {
96
+ SDL_LockSurface(self->surface);
97
+ memcpy(self->surface->pixels, pixels, self->surface->pitch * h);
98
+ SDL_UnlockSurface(self->surface);
99
+ }
100
+ else if (clear_pixels)
101
+ SDL_FillRect(self->surface, NULL, 0);
102
+ }
103
+
104
+ void
105
+ Bitmap_draw_string (
106
+ Bitmap* bitmap, const RawFont& font,
107
+ const char* str, coord x, coord y, bool smooth)
108
+ {
109
+ if (!bitmap)
110
+ argument_error(__FILE__, __LINE__);
111
+ if (!*bitmap)
112
+ argument_error(__FILE__, __LINE__);
113
+ if (!font)
114
+ argument_error(__FILE__, __LINE__);
115
+ if (!str)
116
+ argument_error(__FILE__, __LINE__);
117
+
118
+ if (*str == '\0') return;
119
+
120
+ font.draw_string(bitmap->self->surface, bitmap->height(), str, x, y);
121
+ Bitmap_set_modified(bitmap);
122
+ }
123
+
124
+ void
125
+ Bitmap_set_modified (Bitmap* bitmap, bool modified)
126
+ {
127
+ bitmap->self->modified = modified;
128
+ }
129
+
130
+ bool
131
+ Bitmap_get_modified (const Bitmap& bitmap)
132
+ {
133
+ return bitmap.self->modified;
134
+ }
135
+
136
+ static const char*
137
+ get_ext (const char* path)
138
+ {
139
+ if (!path)
140
+ return NULL;
141
+
142
+ return strrchr(path, '.');
143
+ }
144
+
145
+ void
146
+ Bitmap_save (const Bitmap& bmp, const char* path)
147
+ {
148
+ const char* extension = get_ext(path);
149
+ if (!extension)
150
+ {
151
+ argument_error(
152
+ __FILE__, __LINE__, "invalid image file extension: '%s'", path);
153
+ }
154
+
155
+ const auto& cs = bmp.color_space();
156
+ int w = bmp.width();
157
+ int h = bmp.height();
158
+ int pitch = w * cs.Bpp();
159
+
160
+ std::unique_ptr<uchar[]> pixels(new uchar[h * pitch]);
161
+ for (int y = 0; y < h; ++y)
162
+ memcpy(pixels.get() + pitch * y, bmp.at<uchar>(0, y), pitch);
163
+
164
+ String ext = extension;
165
+ ext.downcase();
166
+
167
+ int ret = 0;
168
+ if (ext == ".bmp")
169
+ ret = stbi_write_bmp(path, w, h, cs.Bpp(), pixels.get());
170
+ else if (ext == ".png")
171
+ ret = stbi_write_png(path, w, h, cs.Bpp(), pixels.get(), 0);
172
+ else if (ext == ".jpg" || ext == ".jpeg")
173
+ ret = stbi_write_jpg(path, w, h, cs.Bpp(), pixels.get(), 90);
174
+ else if (ext == ".tga")
175
+ ret = stbi_write_tga(path, w, h, cs.Bpp(), pixels.get());
176
+ else
177
+ argument_error(__FILE__, __LINE__, "unknown image file type");
178
+
179
+ if (!ret)
180
+ rays_error(__FILE__, __LINE__, "failed to save: '%s'", path);
181
+ }
182
+
183
+ Bitmap
184
+ Bitmap_load (const char* path)
185
+ {
186
+ if (!path)
187
+ argument_error(__FILE__, __LINE__);
188
+
189
+ int w = 0, h = 0, Bpp = 0;
190
+ uchar* pixels = stbi_load(path, &w, &h, &Bpp, 0);
191
+ if (!pixels)
192
+ rays_error(__FILE__, __LINE__, "failed to load: '%s'", path);
193
+
194
+ ColorSpace cs;
195
+ switch (Bpp)
196
+ {
197
+ case 1: cs = GRAY_8; break;
198
+ case 3: cs = RGB_888; break;
199
+ case 4: cs = RGBA_8888; break;
200
+ default:
201
+ rays_error(__FILE__, __LINE__, "unsupported image file: '%s'", path);
202
+ }
203
+
204
+ Bitmap bmp(w, h, cs);
205
+ if (!bmp)
206
+ rays_error(__FILE__, __LINE__, "failed to create Bitmap object");
207
+
208
+ int pitch = Bpp * w;
209
+ for (int y = 0; y < h; ++y)
210
+ memcpy(bmp.at<uchar>(0, y), pixels + pitch * y, pitch);
211
+
212
+ return bmp;
213
+ }
214
+
215
+
216
+ Bitmap::Bitmap ()
217
+ {
218
+ }
219
+
220
+ Bitmap::Bitmap (
221
+ int width, int height, const ColorSpace& color_space, const void* pixels)
222
+ {
223
+ Bitmap_setup(this, width, height, color_space, pixels);
224
+ }
225
+
226
+ Bitmap::~Bitmap ()
227
+ {
228
+ }
229
+
230
+ Bitmap
231
+ Bitmap::dup () const
232
+ {
233
+ return Bitmap(width(), height(), color_space(), pixels());
234
+ }
235
+
236
+ int
237
+ Bitmap::width () const
238
+ {
239
+ if (!*this) return 0;
240
+ return self->surface->w;
241
+ }
242
+
243
+ int
244
+ Bitmap::height () const
245
+ {
246
+ if (!*this) return 0;
247
+ return self->surface->h;
248
+ }
249
+
250
+ const ColorSpace&
251
+ Bitmap::color_space () const
252
+ {
253
+ if (!*this)
254
+ {
255
+ static const ColorSpace UNKNOWN = COLORSPACE_UNKNOWN;
256
+ return UNKNOWN;
257
+ }
258
+ return self->color_space;
259
+ }
260
+
261
+ int
262
+ Bitmap::pitch () const
263
+ {
264
+ if (!*this) return 0;
265
+ return self->surface->pitch;
266
+ }
267
+
268
+ size_t
269
+ Bitmap::size () const
270
+ {
271
+ return pitch() * height();
272
+ }
273
+
274
+ void*
275
+ Bitmap::pixels ()
276
+ {
277
+ if (!*this) return NULL;
278
+ return self->surface->pixels;
279
+ }
280
+
281
+ const void*
282
+ Bitmap::pixels () const
283
+ {
284
+ return const_cast<This*>(this)->pixels();
285
+ }
286
+
287
+ Bitmap::operator bool () const
288
+ {
289
+ return
290
+ self->surface &&
291
+ self->surface->w > 0 &&
292
+ self->surface->h > 0 &&
293
+ self->surface->pixels &&
294
+ self->color_space;
295
+ }
296
+
297
+ bool
298
+ Bitmap::operator ! () const
299
+ {
300
+ return !operator bool();
301
+ }
302
+
303
+
304
+ }// Rays