sfml3-rb 0.2.2 → 0.3.0

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +9 -0
  3. data/CHANGELOG.md +43 -17
  4. data/README.md +97 -29
  5. data/ext/audio/audio_enums.c +58 -20
  6. data/ext/audio/listener.c +89 -6
  7. data/ext/audio/music.c +206 -5
  8. data/ext/audio/sound.c +175 -5
  9. data/ext/audio/sound_buffer.c +189 -47
  10. data/ext/audio/sound_buffer_recorder.c +83 -16
  11. data/ext/audio/sound_recorder.c +172 -52
  12. data/ext/audio/sound_source_cone.c +108 -29
  13. data/ext/audio/sound_stream.c +178 -5
  14. data/ext/core/exceptions.c +10 -8
  15. data/ext/core/unicode.c +12 -2
  16. data/ext/ext.c +4 -0
  17. data/ext/graphics/blend_mode.c +203 -53
  18. data/ext/graphics/circle.c +271 -4
  19. data/ext/graphics/color.c +240 -90
  20. data/ext/graphics/drawable.c +15 -4
  21. data/ext/graphics/font.c +138 -25
  22. data/ext/graphics/glyph.c +31 -8
  23. data/ext/graphics/image.c +180 -37
  24. data/ext/graphics/polygon.c +293 -26
  25. data/ext/graphics/rect.c +211 -54
  26. data/ext/graphics/rectangle.c +279 -26
  27. data/ext/graphics/render_state.c +116 -2
  28. data/ext/graphics/render_texture.c +163 -2
  29. data/ext/graphics/shader.c +283 -17
  30. data/ext/graphics/shape.c +252 -26
  31. data/ext/graphics/sprite.c +216 -25
  32. data/ext/graphics/stencil_mode.c +148 -39
  33. data/ext/graphics/target.c +67 -22
  34. data/ext/graphics/target.h +15 -15
  35. data/ext/graphics/text.c +306 -6
  36. data/ext/graphics/texture.c +257 -3
  37. data/ext/graphics/transform.c +178 -5
  38. data/ext/graphics/transformable.c +126 -2
  39. data/ext/graphics/vertex.c +79 -2
  40. data/ext/graphics/vertex_array.c +128 -16
  41. data/ext/graphics/vertex_buffer.c +124 -2
  42. data/ext/graphics/view.c +130 -2
  43. data/ext/network/ftp.c +249 -10
  44. data/ext/network/http.c +156 -38
  45. data/ext/network/ip_address.c +107 -26
  46. data/ext/network/network_enums.c +248 -141
  47. data/ext/network/packet.c +273 -39
  48. data/ext/network/socket_selector.c +91 -19
  49. data/ext/network/tcp_listener.c +75 -16
  50. data/ext/network/tcp_socket.c +128 -25
  51. data/ext/network/udp_socket.c +122 -26
  52. data/ext/ports.rb +7 -0
  53. data/ext/system/buffer.c +41 -12
  54. data/ext/system/clock.c +68 -9
  55. data/ext/system/input_stream.c +94 -42
  56. data/ext/system/sleep.c +10 -2
  57. data/ext/system/time.c +172 -34
  58. data/ext/system/vec2.c +156 -35
  59. data/ext/system/vec3.c +166 -35
  60. data/ext/window/clipboard.c +47 -17
  61. data/ext/window/context.c +59 -9
  62. data/ext/window/context_settings.c +116 -38
  63. data/ext/window/cursor.c +39 -9
  64. data/ext/window/event.c +163 -42
  65. data/ext/window/joystick.c +69 -3
  66. data/ext/window/keyboard.c +168 -116
  67. data/ext/window/mouse.c +36 -2
  68. data/ext/window/sensor.c +28 -2
  69. data/ext/window/touch.c +20 -2
  70. data/ext/window/video_mode.c +90 -19
  71. data/ext/window/vulkan.c +34 -6
  72. data/ext/window/window.c +340 -16
  73. data/lib/sfml/version.rb +1 -1
  74. data/sig/audio/audio_enums.rbs +30 -0
  75. data/sig/audio/listener.rbs +16 -0
  76. data/sig/audio/music.rbs +56 -0
  77. data/sig/audio/sound.rbs +51 -0
  78. data/sig/audio/sound_buffer.rbs +17 -0
  79. data/sig/audio/sound_buffer_recorder.rbs +14 -0
  80. data/sig/audio/sound_recorder.rbs +17 -0
  81. data/sig/audio/sound_source_cone.rbs +14 -0
  82. data/sig/audio/sound_stream.rbs +51 -0
  83. data/sig/graphics/blend_mode.rbs +29 -0
  84. data/sig/graphics/circle.rbs +44 -0
  85. data/sig/graphics/color.rbs +39 -0
  86. data/sig/graphics/drawable.rbs +5 -0
  87. data/sig/graphics/font.rbs +20 -0
  88. data/sig/graphics/glyph.rbs +7 -0
  89. data/sig/graphics/image.rbs +22 -0
  90. data/sig/graphics/polygon.rbs +42 -0
  91. data/sig/graphics/rect.rbs +33 -0
  92. data/sig/graphics/rectangle.rbs +42 -0
  93. data/sig/graphics/render_state.rbs +21 -0
  94. data/sig/graphics/render_texture.rbs +37 -0
  95. data/sig/graphics/shader.rbs +39 -0
  96. data/sig/graphics/shape.rbs +38 -0
  97. data/sig/graphics/sprite.rbs +34 -0
  98. data/sig/graphics/stencil_mode.rbs +18 -0
  99. data/sig/graphics/target.rbs +10 -0
  100. data/sig/graphics/text.rbs +48 -0
  101. data/sig/graphics/texture.rbs +34 -0
  102. data/sig/graphics/transform.rbs +37 -0
  103. data/sig/graphics/transformable.rbs +25 -0
  104. data/sig/graphics/vertex.rbs +17 -0
  105. data/sig/graphics/vertex_array.rbs +17 -0
  106. data/sig/graphics/vertex_buffer.rbs +22 -0
  107. data/sig/graphics/view.rbs +24 -0
  108. data/sig/network/ftp.rbs +46 -0
  109. data/sig/network/http.rbs +27 -0
  110. data/sig/network/ip_address.rbs +22 -0
  111. data/sig/network/network_enums.rbs +95 -0
  112. data/sig/network/packet.rbs +40 -0
  113. data/sig/network/socket_selector.rbs +14 -0
  114. data/sig/network/tcp_listener.rbs +13 -0
  115. data/sig/network/tcp_socket.rbs +18 -0
  116. data/sig/network/udp_socket.rbs +17 -0
  117. data/sig/system/buffer.rbs +11 -0
  118. data/sig/system/clock.rbs +13 -0
  119. data/sig/system/input_stream.rbs +7 -0
  120. data/sig/system/sleep.rbs +3 -0
  121. data/sig/system/time.rbs +28 -0
  122. data/sig/system/vec2.rbs +26 -0
  123. data/sig/system/vec3.rbs +27 -0
  124. data/sig/window/clipboard.rbs +8 -0
  125. data/sig/window/context.rbs +11 -0
  126. data/sig/window/context_settings.rbs +20 -0
  127. data/sig/window/cursor.rbs +6 -0
  128. data/sig/window/event.rbs +20 -0
  129. data/sig/window/joystick.rbs +15 -0
  130. data/sig/window/keyboard.rbs +10 -0
  131. data/sig/window/mouse.rbs +9 -0
  132. data/sig/window/sensor.rbs +8 -0
  133. data/sig/window/touch.rbs +6 -0
  134. data/sig/window/video_mode.rbs +16 -0
  135. data/sig/window/vulkan.rbs +7 -0
  136. data/sig/window/window.rbs +57 -0
  137. metadata +66 -2
data/ext/graphics/font.c CHANGED
@@ -10,17 +10,16 @@
10
10
 
11
11
  static VALUE rb_cFont;
12
12
 
13
- static void Font_free(void *ptr) {
13
+ static void Font_free(void* ptr) {
14
14
  sfFont_destroy(ptr);
15
15
  }
16
16
 
17
17
  static const rb_data_type_t Font_data_type = {
18
18
  .wrap_struct_name = "SFML::Font",
19
19
  .function = {.dmark = NULL, .dfree = Font_free, .dsize = NULL},
20
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
21
- };
20
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
22
21
 
23
- static VALUE Font_wrap(VALUE klass, sfFont *font) {
22
+ static VALUE Font_wrap(VALUE klass, sfFont* font) {
24
23
  if (font == NULL) {
25
24
  rb_raise(rb_eRuntimeError, "failed to load font");
26
25
  }
@@ -28,30 +27,69 @@ static VALUE Font_wrap(VALUE klass, sfFont *font) {
28
27
  return TypedData_Wrap_Struct(klass, &Font_data_type, font);
29
28
  }
30
29
 
30
+ /* call-seq:
31
+ * Font.from_file(path) -> Font
32
+ *
33
+ * Loads a font from the font file at +filename+.
34
+ *
35
+ * @return [Font]
36
+ * @raise [RuntimeError] if the file cannot be loaded
37
+ */
31
38
  static VALUE Font_from_file(VALUE klass, VALUE rb_path) {
32
39
  return Font_wrap(klass, sfFont_createFromFile(StringValueCStr(rb_path)));
33
40
  }
34
41
 
42
+ /* call-seq:
43
+ * Font.from_memory(data) -> Font
44
+ *
45
+ * Loads a font from an in-memory font file buffer.
46
+ *
47
+ * @return [Font]
48
+ * @raise [RuntimeError] if the font data cannot be parsed
49
+ */
35
50
  static VALUE Font_from_memory(VALUE klass, VALUE rb_data) {
36
51
  StringValue(rb_data);
37
52
 
38
- return Font_wrap(klass, sfFont_createFromMemory(RSTRING_PTR(rb_data), (size_t) RSTRING_LEN(rb_data)));
53
+ return Font_wrap(klass,
54
+ sfFont_createFromMemory(RSTRING_PTR(rb_data), (size_t)RSTRING_LEN(rb_data)));
39
55
  }
40
56
 
57
+ /* call-seq:
58
+ * Font.from_stream(stream) -> Font
59
+ *
60
+ * +stream+ is any object responding to the InputStream protocol (see
61
+ * InputStream).
62
+ *
63
+ * @return [Font]
64
+ * @raise [RuntimeError] if the font cannot be loaded
65
+ */
41
66
  static VALUE Font_from_stream(VALUE klass, VALUE rb_stream) {
42
67
  VALUE holder = Qnil;
43
- sfInputStream *stream = input_stream_from_rb(rb_stream, &holder);
68
+ sfInputStream* stream = input_stream_from_rb(rb_stream, &holder);
44
69
 
45
- (void) holder;
70
+ (void)holder;
46
71
 
47
72
  return Font_wrap(klass, sfFont_createFromStream(stream));
48
73
  }
49
74
 
75
+ /* call-seq: copy -> Font
76
+ *
77
+ * Returns a deep copy of the object.
78
+ *
79
+ * @return [Font] an independent copy
80
+ */
50
81
  static VALUE Font_copy(VALUE self) {
51
82
  return Font_wrap(Get_Klass_Font(), sfFont_copy(Get_Font_Struct(self)));
52
83
  }
53
84
 
54
- static VALUE Font_get_glyph(int argc, VALUE *argv, VALUE self) {
85
+ /* call-seq:
86
+ * glyph(codepoint, size, bold=false, outline_thickness=0) -> Glyph
87
+ *
88
+ * Returns the glyph for +codepoint+ at the given +character_size+.
89
+ *
90
+ * @return [Glyph]
91
+ */
92
+ static VALUE Font_get_glyph(int argc, VALUE* argv, VALUE self) {
55
93
  VALUE rb_codepoint, rb_size, rb_bold, rb_outline;
56
94
  bool bold = false;
57
95
  float outline = 0;
@@ -66,58 +104,133 @@ static VALUE Font_get_glyph(int argc, VALUE *argv, VALUE self) {
66
104
  outline = NUM2DBL(rb_outline);
67
105
  }
68
106
 
69
- return glyph_from_c(sfFont_getGlyph(Get_Font_Struct(self), (uint32_t) NUM2UINT(rb_codepoint),
70
- (unsigned int) NUM2UINT(rb_size), bold, outline));
107
+ return glyph_from_c(sfFont_getGlyph(Get_Font_Struct(self), (uint32_t)NUM2UINT(rb_codepoint),
108
+ (unsigned int)NUM2UINT(rb_size), bold, outline));
71
109
  }
72
110
 
111
+ /* call-seq: has_glyph?(codepoint) -> true or false
112
+ *
113
+ * Returns +true+ if the font contains a glyph for +codepoint+.
114
+ *
115
+ * @return [Boolean] whether this font has a glyph for the given Unicode
116
+ * codepoint
117
+ */
73
118
  static VALUE Font_has_glyph(VALUE self, VALUE rb_codepoint) {
74
- return BOOL2RB(sfFont_hasGlyph(Get_Font_Struct(self), (uint32_t) NUM2UINT(rb_codepoint)));
119
+ return BOOL2RB(sfFont_hasGlyph(Get_Font_Struct(self), (uint32_t)NUM2UINT(rb_codepoint)));
75
120
  }
76
121
 
122
+ /* call-seq: kerning(first, second, size) -> Float
123
+ *
124
+ * Returns the kerning between two code points at the given size.
125
+ *
126
+ * @return [Float] the kerning offset between two consecutive glyphs at the
127
+ * given character size
128
+ */
77
129
  static VALUE Font_get_kerning(VALUE self, VALUE rb_first, VALUE rb_second, VALUE rb_size) {
78
- return DBL2NUM(sfFont_getKerning(Get_Font_Struct(self), (uint32_t) NUM2UINT(rb_first),
79
- (uint32_t) NUM2UINT(rb_second), (unsigned int) NUM2UINT(rb_size)));
130
+ return DBL2NUM(sfFont_getKerning(Get_Font_Struct(self), (uint32_t)NUM2UINT(rb_first),
131
+ (uint32_t)NUM2UINT(rb_second),
132
+ (unsigned int)NUM2UINT(rb_size)));
80
133
  }
81
134
 
135
+ /* call-seq: bold_kerning(first, second, size) -> Float
136
+ *
137
+ * Returns the kerning of the bold variant between two code points.
138
+ *
139
+ * @return [Float] the kerning offset between two consecutive bold glyphs at
140
+ * the given character size
141
+ */
82
142
  static VALUE Font_get_bold_kerning(VALUE self, VALUE rb_first, VALUE rb_second, VALUE rb_size) {
83
- return DBL2NUM(sfFont_getBoldKerning(Get_Font_Struct(self), (uint32_t) NUM2UINT(rb_first),
84
- (uint32_t) NUM2UINT(rb_second), (unsigned int) NUM2UINT(rb_size)));
143
+ return DBL2NUM(sfFont_getBoldKerning(Get_Font_Struct(self), (uint32_t)NUM2UINT(rb_first),
144
+ (uint32_t)NUM2UINT(rb_second),
145
+ (unsigned int)NUM2UINT(rb_size)));
85
146
  }
86
147
 
148
+ /* call-seq: line_spacing(size) -> Float
149
+ *
150
+ * Returns the line spacing for the given character size.
151
+ *
152
+ * @return [Float] the distance between two consecutive lines at the given
153
+ * character size
154
+ */
87
155
  static VALUE Font_get_line_spacing(VALUE self, VALUE rb_size) {
88
- return DBL2NUM(sfFont_getLineSpacing(Get_Font_Struct(self), (unsigned int) NUM2UINT(rb_size)));
156
+ return DBL2NUM(sfFont_getLineSpacing(Get_Font_Struct(self), (unsigned int)NUM2UINT(rb_size)));
89
157
  }
90
158
 
159
+ /* call-seq: underline_position(size) -> Float
160
+ *
161
+ * Returns the position of the underline for the given size.
162
+ *
163
+ * @return [Float] the position of the underline, relative to the baseline,
164
+ * at the given character size
165
+ */
91
166
  static VALUE Font_get_underline_position(VALUE self, VALUE rb_size) {
92
- return DBL2NUM(sfFont_getUnderlinePosition(Get_Font_Struct(self), (unsigned int) NUM2UINT(rb_size)));
167
+ return DBL2NUM(
168
+ sfFont_getUnderlinePosition(Get_Font_Struct(self), (unsigned int)NUM2UINT(rb_size)));
93
169
  }
94
170
 
171
+ /* call-seq: underline_thickness(size) -> Float
172
+ *
173
+ * Returns the thickness of the underline for the given size.
174
+ *
175
+ * @return [Float] the thickness of the underline at the given character size
176
+ */
95
177
  static VALUE Font_get_underline_thickness(VALUE self, VALUE rb_size) {
96
- return DBL2NUM(sfFont_getUnderlineThickness(Get_Font_Struct(self), (unsigned int) NUM2UINT(rb_size)));
178
+ return DBL2NUM(
179
+ sfFont_getUnderlineThickness(Get_Font_Struct(self), (unsigned int)NUM2UINT(rb_size)));
97
180
  }
98
181
 
182
+ /* call-seq: texture(size) -> Texture
183
+ *
184
+ * Returns the texture atlas holding rendered glyphs for the given size.
185
+ *
186
+ * @return [Texture] the texture atlas holding rendered glyphs for the given
187
+ * character size. Owned by the font; do not modify or free it directly.
188
+ */
99
189
  static VALUE Font_get_texture(VALUE self, VALUE rb_size) {
100
- return texture_from_borrowed(sfFont_getTexture((sfFont *) Get_Font_Struct(self),
101
- (unsigned int) NUM2UINT(rb_size)));
190
+ return texture_from_borrowed(
191
+ sfFont_getTexture((sfFont*)Get_Font_Struct(self), (unsigned int)NUM2UINT(rb_size)));
102
192
  }
103
193
 
194
+ /* call-seq:
195
+ * smooth=(value) -> Boolean
196
+ *
197
+ * Enables or disables smooth rendering.
198
+ *
199
+ * @return [Boolean] +value+
200
+ */
104
201
  static VALUE Font_set_smooth(VALUE self, VALUE rb_smooth) {
105
- sfFont_setSmooth((sfFont *) Get_Font_Struct(self), RTEST(rb_smooth));
202
+ sfFont_setSmooth((sfFont*)Get_Font_Struct(self), RTEST(rb_smooth));
106
203
  return rb_smooth;
107
204
  }
108
205
 
206
+ /* call-seq: smooth? -> true or false
207
+ *
208
+ * Returns +true+ if smooth rendering is enabled.
209
+ *
210
+ * @return [Boolean]
211
+ */
109
212
  static VALUE Font_is_smooth(VALUE self) {
110
213
  return BOOL2RB(sfFont_isSmooth(Get_Font_Struct(self)));
111
214
  }
112
215
 
216
+ /* call-seq: info -> String
217
+ *
218
+ * Returns the font's family name.
219
+ *
220
+ * @return [String] the font family name
221
+ */
113
222
  static VALUE Font_get_info(VALUE self) {
114
223
  sfFontInfo info = sfFont_getInfo(Get_Font_Struct(self));
115
224
 
116
225
  return rb_str_new_cstr(info.family != NULL ? info.family : "");
117
226
  }
118
227
 
119
- void Init_Font(VALUE rb_module) {
120
- rb_cFont = rb_define_class_under(rb_module, "Font", rb_cObject);
228
+ /* Document-class: SFML::Font
229
+ * A font face used to render text, loaded from a file, memory buffer or
230
+ * stream. Glyphs are rasterized and cached lazily per character size.
231
+ */
232
+ void Init_Font(VALUE rb_mSFML) {
233
+ rb_cFont = rb_define_class_under(rb_mSFML, "Font", rb_cObject);
121
234
 
122
235
  rb_define_singleton_method(rb_cFont, "from_file", Font_from_file, 1);
123
236
  rb_define_singleton_method(rb_cFont, "from_memory", Font_from_memory, 1);
@@ -141,8 +254,8 @@ VALUE Get_Klass_Font(void) {
141
254
  return rb_cFont;
142
255
  }
143
256
 
144
- const sfFont *Get_Font_Struct(VALUE self) {
145
- sfFont *ptr;
257
+ const sfFont* Get_Font_Struct(VALUE self) {
258
+ sfFont* ptr;
146
259
  TypedData_Get_Struct(self, sfFont, &Font_data_type, ptr);
147
260
  return ptr;
148
261
  }
data/ext/graphics/glyph.c CHANGED
@@ -11,44 +11,67 @@ typedef struct {
11
11
 
12
12
  static VALUE rb_cGlyph;
13
13
 
14
- static void Glyph_free(void *ptr) {
14
+ static void Glyph_free(void* ptr) {
15
15
  free(ptr);
16
16
  }
17
17
 
18
18
  static const rb_data_type_t Glyph_data_type = {
19
19
  .wrap_struct_name = "SFML::Glyph",
20
20
  .function = {.dmark = NULL, .dfree = Glyph_free, .dsize = NULL},
21
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
22
- };
21
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
23
22
 
24
23
  VALUE glyph_from_c(sfGlyph glyph) {
25
- Glyph *ptr = malloc(sizeof(Glyph));
24
+ Glyph* ptr = malloc(sizeof(Glyph));
26
25
 
27
26
  ptr->glyph = glyph;
28
27
 
29
28
  return TypedData_Wrap_Struct(rb_cGlyph, &Glyph_data_type, ptr);
30
29
  }
31
30
 
32
- static Glyph *Get_Glyph(VALUE self) {
33
- Glyph *ptr;
31
+ static Glyph* Get_Glyph(VALUE self) {
32
+ Glyph* ptr;
34
33
  TypedData_Get_Struct(self, Glyph, &Glyph_data_type, ptr);
35
34
  return ptr;
36
35
  }
37
36
 
37
+ /* call-seq: advance -> Float
38
+ *
39
+ * Returns the glyph's horizontal advance.
40
+ *
41
+ * @return [Float] the horizontal offset to advance to the next character
42
+ */
38
43
  static VALUE Glyph_get_advance(VALUE self) {
39
44
  return DBL2NUM(Get_Glyph(self)->glyph.advance);
40
45
  }
41
46
 
47
+ /* call-seq: bounds -> Rect
48
+ *
49
+ * Returns the glyph's bounding box.
50
+ *
51
+ * @return [Rect] the glyph's bounding box, relative to the baseline and
52
+ * the cursor position
53
+ */
42
54
  static VALUE Glyph_get_bounds(VALUE self) {
43
55
  return rect_to_rb(Get_Glyph(self)->glyph.bounds);
44
56
  }
45
57
 
58
+ /* call-seq: texture_rect -> Rect
59
+ *
60
+ * Returns the sub-rectangle of the texture displayed on the object.
61
+ *
62
+ * @return [Rect] the sub-rectangle of the font's texture holding this
63
+ * glyph's pixels
64
+ */
46
65
  static VALUE Glyph_get_texture_rect(VALUE self) {
47
66
  return int_rect_to_rb(Get_Glyph(self)->glyph.textureRect);
48
67
  }
49
68
 
50
- void Init_Glyph(VALUE rb_module) {
51
- rb_cGlyph = rb_define_class_under(rb_module, "Glyph", rb_cObject);
69
+ /* Document-class: SFML::Glyph
70
+ * A single character's rendering metrics and texture location, as returned
71
+ * by Font#glyph. Read-only.
72
+ */
73
+ void Init_Glyph(VALUE rb_mSFML) {
74
+ rb_cGlyph = rb_define_class_under(rb_mSFML, "Glyph", rb_cObject);
52
75
 
53
76
  rb_define_method(rb_cGlyph, "advance", Glyph_get_advance, 0);
54
77
  rb_define_method(rb_cGlyph, "bounds", Glyph_get_bounds, 0);
data/ext/graphics/image.c CHANGED
@@ -1,6 +1,7 @@
1
1
  #include "graphics/image.h"
2
2
 
3
3
  #include <ruby.h>
4
+ #include <stdint.h>
4
5
  #include <stdlib.h>
5
6
 
6
7
  #include "graphics/color.h"
@@ -13,17 +14,16 @@
13
14
 
14
15
  static VALUE rb_cImage;
15
16
 
16
- static void Image_free(void *ptr) {
17
+ static void Image_free(void* ptr) {
17
18
  sfImage_destroy(ptr);
18
19
  }
19
20
 
20
21
  static const rb_data_type_t Image_data_type = {
21
22
  .wrap_struct_name = "SFML::Image",
22
23
  .function = {.dmark = NULL, .dfree = Image_free, .dsize = NULL},
23
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
24
- };
24
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY};
25
25
 
26
- static VALUE Image_wrap(VALUE klass, sfImage *image) {
26
+ static VALUE Image_wrap(VALUE klass, sfImage* image) {
27
27
  if (image == NULL) {
28
28
  rb_raise(rb_eRuntimeError, "failed to create image");
29
29
  }
@@ -31,67 +31,157 @@ static VALUE Image_wrap(VALUE klass, sfImage *image) {
31
31
  return TypedData_Wrap_Struct(klass, &Image_data_type, image);
32
32
  }
33
33
 
34
+ /* call-seq:
35
+ * Image.new(size) -> Image
36
+ *
37
+ * Creates a black, fully-opaque image of the given size. +size+ is a
38
+ * Vector2 or 2-element Array.
39
+ *
40
+ * @return [Image]
41
+ * @raise [RuntimeError] if the image cannot be created
42
+ */
34
43
  static VALUE Image_new(VALUE klass, VALUE rb_size) {
35
44
  return Image_wrap(klass, sfImage_create(vec2u_from_rb(rb_size)));
36
45
  }
37
46
 
47
+ /* call-seq:
48
+ * Image.from_color(size, color) -> Image
49
+ *
50
+ * Creates an image of the given +size+ filled with +color+.
51
+ *
52
+ * @return [Image]
53
+ * @raise [RuntimeError] if the image cannot be created
54
+ */
38
55
  static VALUE Image_from_color(VALUE klass, VALUE rb_size, VALUE rb_color) {
39
- return Image_wrap(klass, sfImage_createFromColor(vec2u_from_rb(rb_size), color_from_rb(rb_color)));
56
+ return Image_wrap(klass,
57
+ sfImage_createFromColor(vec2u_from_rb(rb_size), color_from_rb(rb_color)));
40
58
  }
41
59
 
60
+ /* call-seq:
61
+ * Image.from_pixels(size, pixels) -> Image
62
+ *
63
+ * +pixels+ is a String of raw RGBA bytes, at least +width * height * 4+
64
+ * bytes long.
65
+ *
66
+ * @return [Image]
67
+ * @raise [ArgumentError] if +pixels+ is shorter than required
68
+ * @raise [RuntimeError] if the image cannot be created
69
+ */
42
70
  static VALUE Image_from_pixels(VALUE klass, VALUE rb_size, VALUE rb_pixels) {
43
71
  sfVector2u size = vec2u_from_rb(rb_size);
44
- size_t expected = (size_t) size.x * size.y * 4;
45
- sfImage *image;
72
+ size_t expected;
73
+ sfImage* image;
74
+
75
+ /* size.x * size.y * 4 as a bare size_t multiplication can wrap on the
76
+ 32-bit targets this gem ships, e.g. size.x = size.y = 32768: the true
77
+ product overflows to 0, which would then pass the length check below
78
+ for any input (even an empty string) and hand CSFML a declared size
79
+ far larger than the buffer actually backing it. Check before
80
+ multiplying rather than after. */
81
+ if (size.x != 0 && size.y > (SIZE_MAX / 4) / size.x) {
82
+ rb_raise(rb_eArgError, "image dimensions too large");
83
+ }
84
+ expected = (size_t)size.x * size.y * 4;
46
85
 
47
86
  StringValue(rb_pixels);
48
87
 
49
- if ((size_t) RSTRING_LEN(rb_pixels) < expected) {
50
- rb_raise(rb_eArgError, "pixel data too short: expected %lu bytes", (unsigned long) expected);
88
+ if ((size_t)RSTRING_LEN(rb_pixels) < expected) {
89
+ rb_raise(rb_eArgError, "pixel data too short: expected %lu bytes", (unsigned long)expected);
51
90
  }
52
91
 
53
- image = sfImage_createFromPixels(size, (const uint8_t *) RSTRING_PTR(rb_pixels));
92
+ image = sfImage_createFromPixels(size, (const uint8_t*)RSTRING_PTR(rb_pixels));
54
93
 
55
94
  return Image_wrap(klass, image);
56
95
  }
57
96
 
97
+ /* call-seq:
98
+ * Image.from_file(path) -> Image
99
+ *
100
+ * Loads an image from the image file at +filename+.
101
+ *
102
+ * @return [Image]
103
+ * @raise [RuntimeError] if the file cannot be loaded
104
+ */
58
105
  static VALUE Image_from_file(VALUE klass, VALUE rb_path) {
59
106
  return Image_wrap(klass, sfImage_createFromFile(StringValueCStr(rb_path)));
60
107
  }
61
108
 
109
+ /* call-seq:
110
+ * Image.from_memory(data) -> Image
111
+ *
112
+ * Loads an image from an in-memory image buffer.
113
+ *
114
+ * @return [Image]
115
+ * @raise [RuntimeError] if the image data cannot be decoded
116
+ */
62
117
  static VALUE Image_from_memory(VALUE klass, VALUE rb_data) {
63
118
  StringValue(rb_data);
64
119
 
65
- return Image_wrap(klass, sfImage_createFromMemory(RSTRING_PTR(rb_data), (size_t) RSTRING_LEN(rb_data)));
120
+ return Image_wrap(klass,
121
+ sfImage_createFromMemory(RSTRING_PTR(rb_data), (size_t)RSTRING_LEN(rb_data)));
66
122
  }
67
123
 
124
+ /* call-seq:
125
+ * Image.from_stream(stream) -> Image
126
+ *
127
+ * +stream+ is any object responding to the InputStream protocol (see
128
+ * InputStream).
129
+ *
130
+ * @return [Image]
131
+ * @raise [RuntimeError] if the image cannot be loaded
132
+ */
68
133
  static VALUE Image_from_stream(VALUE klass, VALUE rb_stream) {
69
134
  VALUE holder = Qnil;
70
- sfInputStream *stream = input_stream_from_rb(rb_stream, &holder);
135
+ sfInputStream* stream = input_stream_from_rb(rb_stream, &holder);
71
136
 
72
- (void) holder;
137
+ (void)holder;
73
138
 
74
139
  return Image_wrap(klass, sfImage_createFromStream(stream));
75
140
  }
76
141
 
142
+ /* call-seq: copy -> Image
143
+ *
144
+ * Returns a deep copy of the object.
145
+ *
146
+ * @return [Image] an independent copy
147
+ */
77
148
  static VALUE Image_copy(VALUE self) {
78
149
  return Image_wrap(Get_Klass_Image(), sfImage_copy(Get_Image_Struct(self)));
79
150
  }
80
151
 
152
+ /* call-seq: size -> Vector2
153
+ *
154
+ * Returns the object's size.
155
+ *
156
+ * @return [Vector2] the image's dimensions in pixels
157
+ */
81
158
  static VALUE Image_get_size(VALUE self) {
82
- return vec2f_to_rb((sfVector2f) {
83
- (float) sfImage_getSize(Get_Image_Struct(self)).x,
84
- (float) sfImage_getSize(Get_Image_Struct(self)).y
85
- });
159
+ return vec2f_to_rb((sfVector2f){(float)sfImage_getSize(Get_Image_Struct(self)).x,
160
+ (float)sfImage_getSize(Get_Image_Struct(self)).y});
86
161
  }
87
162
 
163
+ /* call-seq: save_to_file(path) -> true or false
164
+ *
165
+ * The format is deduced from +path+'s extension.
166
+ *
167
+ * @return [Boolean] whether the save succeeded
168
+ */
88
169
  static VALUE Image_save_to_file(VALUE self, VALUE rb_path) {
89
170
  return BOOL2RB(sfImage_saveToFile(Get_Image_Struct(self), StringValueCStr(rb_path)));
90
171
  }
91
172
 
92
- static VALUE Image_save_to_memory(int argc, VALUE *argv, VALUE self) {
173
+ /* call-seq:
174
+ * save_to_memory(format = "png") -> Buffer or nil
175
+ *
176
+ * +format+ is an image file extension without the dot (e.g. +"png"+,
177
+ * +"bmp"+, +"tga"+, +"jpg"+).
178
+ *
179
+ * @return [Buffer, nil] the encoded image data, or +nil+ if encoding failed
180
+ * @raise [ArgumentError] if given more than one argument
181
+ */
182
+ static VALUE Image_save_to_memory(int argc, VALUE* argv, VALUE self) {
93
183
  VALUE rb_buffer;
94
- const char *format = "png";
184
+ const char* format = "png";
95
185
  if (argc > 1) {
96
186
  raise_invalid_arguments_excepted(1, argc);
97
187
  }
@@ -109,12 +199,28 @@ static VALUE Image_save_to_memory(int argc, VALUE *argv, VALUE self) {
109
199
  return Qnil;
110
200
  }
111
201
 
202
+ /* call-seq: create_mask_from_color(color, alpha) -> self
203
+ *
204
+ * Sets the alpha channel of every pixel matching +color+ to +alpha+.
205
+ *
206
+ * @return [self]
207
+ */
112
208
  static VALUE Image_create_mask_from_color(VALUE self, VALUE rb_color, VALUE rb_alpha) {
113
- sfImage_createMaskFromColor((sfImage *) Get_Image_Struct(self), color_from_rb(rb_color), (uint8_t) NUM2INT(rb_alpha));
209
+ sfImage_createMaskFromColor((sfImage*)Get_Image_Struct(self), color_from_rb(rb_color),
210
+ (uint8_t)NUM2INT(rb_alpha));
114
211
  return self;
115
212
  }
116
213
 
117
- static VALUE Image_copy_image(int argc, VALUE *argv, VALUE self) {
214
+ /* call-seq:
215
+ * copy_image(source, dest, source_rect = Rect.new, apply_alpha = true) -> true or false
216
+ *
217
+ * Copies pixels from +source+ (an Image) onto +self+ at position +dest+.
218
+ * +source_rect+ restricts the copied region; an empty/zero rect copies the
219
+ * whole source image.
220
+ *
221
+ * @return [Boolean] whether the copy succeeded
222
+ */
223
+ static VALUE Image_copy_image(int argc, VALUE* argv, VALUE self) {
118
224
  VALUE rb_source, rb_dest, rb_source_rect, rb_apply_alpha;
119
225
  bool apply_alpha = true;
120
226
 
@@ -128,47 +234,84 @@ static VALUE Image_copy_image(int argc, VALUE *argv, VALUE self) {
128
234
  apply_alpha = RTEST(rb_apply_alpha);
129
235
  }
130
236
 
131
- return BOOL2RB(sfImage_copyImage((sfImage *) Get_Image_Struct(self), Get_Image_Struct(rb_source),
132
- vec2u_from_rb(rb_dest), int_rect_from_rb(rb_source_rect), apply_alpha));
237
+ return BOOL2RB(sfImage_copyImage((sfImage*)Get_Image_Struct(self), Get_Image_Struct(rb_source),
238
+ vec2u_from_rb(rb_dest), int_rect_from_rb(rb_source_rect),
239
+ apply_alpha));
133
240
  }
134
241
 
242
+ /* call-seq: pixel(x, y) -> Color
243
+ *
244
+ * Returns the color of the pixel at +x+, +y+.
245
+ *
246
+ * @return [Color] the color of the pixel at (+x+, +y+)
247
+ */
135
248
  static VALUE Image_get_pixel(VALUE self, VALUE rb_x, VALUE rb_y) {
136
- sfColor color = sfImage_getPixel(Get_Image_Struct(self),
137
- (sfVector2u) {(unsigned) NUM2UINT(rb_x), (unsigned) NUM2UINT(rb_y)});
249
+ sfColor color = sfImage_getPixel(
250
+ Get_Image_Struct(self), (sfVector2u){(unsigned)NUM2UINT(rb_x), (unsigned)NUM2UINT(rb_y)});
138
251
 
139
252
  return color_to_rb(color);
140
253
  }
141
254
 
255
+ /* call-seq: set_pixel(x, y, color) -> self
256
+ *
257
+ * Sets the color of the pixel at +x+, +y+.
258
+ *
259
+ * @return [self]
260
+ */
142
261
  static VALUE Image_set_pixel(VALUE self, VALUE rb_x, VALUE rb_y, VALUE rb_color) {
143
- sfImage_setPixel((sfImage *) Get_Image_Struct(self),
144
- (sfVector2u) {(unsigned) NUM2UINT(rb_x), (unsigned) NUM2UINT(rb_y)}, color_from_rb(rb_color));
262
+ sfImage_setPixel((sfImage*)Get_Image_Struct(self),
263
+ (sfVector2u){(unsigned)NUM2UINT(rb_x), (unsigned)NUM2UINT(rb_y)},
264
+ color_from_rb(rb_color));
145
265
  return self;
146
266
  }
147
267
 
268
+ /* call-seq: pixels -> String
269
+ *
270
+ * Returns a flat array of the image's pixels.
271
+ *
272
+ * @return [String] the raw RGBA pixel data, +width * height * 4+ bytes,
273
+ * row-major starting from the top-left
274
+ */
148
275
  static VALUE Image_get_pixels(VALUE self) {
149
- const sfImage *image = Get_Image_Struct(self);
276
+ const sfImage* image = Get_Image_Struct(self);
150
277
  sfVector2u size = sfImage_getSize(image);
151
- const uint8_t *pixels = sfImage_getPixelsPtr(image);
278
+ const uint8_t* pixels = sfImage_getPixelsPtr(image);
152
279
 
153
280
  if (pixels == NULL) {
154
281
  return rb_str_new("", 0);
155
282
  }
156
283
 
157
- return rb_str_new((const char *) pixels, (long) (size.x * size.y * 4));
284
+ return rb_str_new((const char*)pixels, (long)(size.x * size.y * 4));
158
285
  }
159
286
 
287
+ /* call-seq: flip_horizontally! -> self
288
+ *
289
+ * Flips the image horizontally.
290
+ *
291
+ * @return [self]
292
+ */
160
293
  static VALUE Image_flip_horizontally(VALUE self) {
161
- sfImage_flipHorizontally((sfImage *) Get_Image_Struct(self));
294
+ sfImage_flipHorizontally((sfImage*)Get_Image_Struct(self));
162
295
  return self;
163
296
  }
164
297
 
298
+ /* call-seq: flip_vertically! -> self
299
+ *
300
+ * Flips the image vertically.
301
+ *
302
+ * @return [self]
303
+ */
165
304
  static VALUE Image_flip_vertically(VALUE self) {
166
- sfImage_flipVertically((sfImage *) Get_Image_Struct(self));
305
+ sfImage_flipVertically((sfImage*)Get_Image_Struct(self));
167
306
  return self;
168
307
  }
169
308
 
170
- void Init_Image(VALUE rb_module) {
171
- rb_cImage = rb_define_class_under(rb_module, "Image", rb_cObject);
309
+ /* Document-class: SFML::Image
310
+ * A 2D array of RGBA pixels, held in RAM (as opposed to Texture, which is
311
+ * GPU-side). Used for loading, editing and saving raw pixel data.
312
+ */
313
+ void Init_Image(VALUE rb_mSFML) {
314
+ rb_cImage = rb_define_class_under(rb_mSFML, "Image", rb_cObject);
172
315
 
173
316
  rb_define_singleton_method(rb_cImage, "new", Image_new, 1);
174
317
  rb_define_singleton_method(rb_cImage, "from_color", Image_from_color, 2);
@@ -194,12 +337,12 @@ VALUE Get_Klass_Image(void) {
194
337
  return rb_cImage;
195
338
  }
196
339
 
197
- const sfImage *Get_Image_Struct(VALUE self) {
198
- sfImage *ptr;
340
+ const sfImage* Get_Image_Struct(VALUE self) {
341
+ sfImage* ptr;
199
342
  TypedData_Get_Struct(self, sfImage, &Image_data_type, ptr);
200
343
  return ptr;
201
344
  }
202
345
 
203
- VALUE image_from_c(sfImage *image) {
346
+ VALUE image_from_c(sfImage* image) {
204
347
  return Image_wrap(Get_Klass_Image(), image);
205
348
  }