bitmap-plus-plus 1.0.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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +40 -0
  3. data/LICENSE +25 -0
  4. data/README.md +75 -0
  5. data/examples/colormaps.rb +1857 -0
  6. data/examples/draw_primitives.rb +53 -0
  7. data/examples/julia.rb +68 -0
  8. data/examples/mandelbrot.rb +68 -0
  9. data/examples/random_colors.rb +37 -0
  10. data/examples/transformations.rb +84 -0
  11. data/ext/BitmapPlusPlus-rb.cpp +420 -0
  12. data/ext/BitmapPlusPlus-rb.hpp +11 -0
  13. data/ext/BitmapPlusPlus.hpp +659 -0
  14. data/ext/CMakeLists.txt +170 -0
  15. data/ext/CMakePresets.json +209 -0
  16. data/lib/bitmap-plus-plus/version.rb +3 -0
  17. data/lib/bitmap-plus-plus.rb +3 -0
  18. data/sig/Bmp/Bitmap.rbs +39 -0
  19. data/sig/Bmp/BitmapHeader.rbs +22 -0
  20. data/sig/Bmp/Exception.rbs +5 -0
  21. data/sig/Bmp/Pixel.rbs +16 -0
  22. data/sig/Rice/Arg.rbs +6 -0
  23. data/sig/Rice/Buffer/342/211/272Rice/352/236/211/352/236/211detail/352/236/211/352/236/211ParameterAbstract/342/210/227/342/211/273.rbs +15 -0
  24. data/sig/Rice/Buffer/342/211/272char/342/211/273.rbs +16 -0
  25. data/sig/Rice/ModuleRegistry.rbs +5 -0
  26. data/sig/Rice/Native.rbs +9 -0
  27. data/sig/Rice/NativeKind.rbs +20 -0
  28. data/sig/Rice/NativeRegistry.rbs +5 -0
  29. data/sig/Rice/Parameter.rbs +7 -0
  30. data/sig/Rice/Pointer/342/211/272Rice/352/236/211/352/236/211detail/352/236/211/352/236/211ParameterAbstract/342/210/227/342/211/273.rbs +5 -0
  31. data/sig/Rice/Pointer/342/211/272char/342/211/273.rbs +5 -0
  32. data/sig/Rice/Reference/342/211/272char/342/211/273.rbs +6 -0
  33. data/sig/Rice/Reference/342/211/272int/342/211/273.rbs +6 -0
  34. data/sig/Rice/Reference/342/211/272unsigned/302/240Int64/342/211/273.rbs +6 -0
  35. data/sig/Rice/Registries.rbs +8 -0
  36. data/sig/Rice/TypeRegistry.rbs +5 -0
  37. data/sig/Std/Exception.rbs +6 -0
  38. data/sig/Std/Filesystem/Path.rbs +6 -0
  39. data/sig/Std/RuntimeError.rbs +6 -0
  40. data/sig/Std/Vector/342/211/272Rice/352/236/211/352/236/211detail/352/236/211/352/236/211ParameterAbstract/302/240const/342/210/227/342/211/273.rbs +33 -0
  41. metadata +116 -0
@@ -0,0 +1,420 @@
1
+ /**
2
+ * BitmapPlusPlus Ruby Bindings
3
+ *
4
+ * This file demonstrates how to use Rice to create Ruby bindings for a C++ library.
5
+ * Rice is a C++ header-only library that makes it easy to create Ruby extensions.
6
+ *
7
+ * Key Rice concepts demonstrated:
8
+ *
9
+ * 1. MODULES: Use define_module() to create Ruby modules that namespace your classes
10
+ *
11
+ * 2. CLASSES: Use define_class_under<CppClass>(module, "RubyName") to wrap C++ classes
12
+ * - The template parameter is the C++ class being wrapped
13
+ * - The first argument is the parent module
14
+ * - The second argument is the Ruby class name
15
+ *
16
+ * 3. INHERITANCE: Use define_class_under<Derived, Base>() for class hierarchies
17
+ *
18
+ * 4. CONSTRUCTORS: Use define_constructor(Constructor<Class, Args...>())
19
+ * - Multiple constructors can be defined for overloading
20
+ * - Use Arg("name") to provide named parameters for better error messages
21
+ * - Use Arg("name") = default_value for default arguments
22
+ *
23
+ * 5. METHODS: Use define_method("ruby_name", &Class::method)
24
+ * - Methods are automatically wrapped with type conversion
25
+ * - Use Arg("name") for named parameters
26
+ *
27
+ * 6. OVERLOADED METHODS: Use template syntax to disambiguate overloads
28
+ * - define_method<ReturnType(Class::*)(Args...)>("name", &Class::method)
29
+ *
30
+ * 7. ATTRIBUTES: Use define_attr("name", &Class::member) for struct members
31
+ * - Creates both getter and setter methods
32
+ *
33
+ * 8. OPERATORS: Map C++ operators to Ruby methods
34
+ * - "==" for operator==, "!=" for operator!=, "[]" for operator[], etc.
35
+ *
36
+ * 9. LAMBDAS: Use lambdas for custom behavior not directly mappable
37
+ * - Useful for []= operator which doesn't exist in C++
38
+ *
39
+ * 10. CONSTANTS: Use module.define_constant("NAME", value)
40
+ *
41
+ * 11. ITERATORS: Use define_iterator() to make C++ iterators work with Ruby's each
42
+ *
43
+ * 12. EXCEPTION HANDLING: Rice automatically converts C++ exceptions to Ruby exceptions
44
+ * - Use Rice::detail::cpp_protect() to wrap initialization code
45
+ *
46
+ * 13. STL SUPPORT: Include <rice/stl.hpp> for automatic std::string, std::vector, etc. conversion
47
+ */
48
+
49
+ #include "BitmapPlusPlus.hpp"
50
+ #include "BitmapPlusPlus-rb.hpp"
51
+
52
+ using namespace Rice;
53
+
54
+ // Global class references (optional, but useful for cross-referencing)
55
+ Rice::Class rb_cBmpBitmap;
56
+ Rice::Class rb_cBmpBitmapHeader;
57
+ Rice::Class rb_cBmpException;
58
+ Rice::Class rb_cBmpPixel;
59
+
60
+ /**
61
+ * Main initialization function
62
+ *
63
+ * This function defines all the Ruby bindings. It's called from Init_bitmap_plus_plus()
64
+ * which is the entry point that Ruby calls when the extension is loaded.
65
+ */
66
+ void initialize()
67
+ {
68
+ // ============================================================================
69
+ // MODULE DEFINITION
70
+ // ============================================================================
71
+ // Create a Ruby module to namespace all our classes.
72
+ // In Ruby, this creates: module Bmp; end
73
+ Module rb_mBmp = define_module("Bmp");
74
+
75
+ // ============================================================================
76
+ // CONSTANTS
77
+ // ============================================================================
78
+ // Define module-level constants. These become Bmp::BITMAP_BUFFER_MAGIC, etc.
79
+ rb_mBmp.define_constant("BITMAP_BUFFER_MAGIC", bmp::BITMAP_BUFFER_MAGIC);
80
+
81
+ // ============================================================================
82
+ // STRUCT BINDING: BitmapHeader
83
+ // ============================================================================
84
+ // Wrap a simple C++ struct. Use define_attr() to expose struct members.
85
+ // define_attr() creates both getter and setter methods automatically.
86
+ rb_cBmpBitmapHeader = define_class_under<bmp::BitmapHeader>(rb_mBmp, "BitmapHeader")
87
+ // Default constructor
88
+ .define_constructor(Constructor<bmp::BitmapHeader>())
89
+ // Expose all struct members as Ruby attributes
90
+ .define_attr("magic", &bmp::BitmapHeader::magic)
91
+ .define_attr("file_size", &bmp::BitmapHeader::file_size)
92
+ .define_attr("reserved1", &bmp::BitmapHeader::reserved1)
93
+ .define_attr("reserved2", &bmp::BitmapHeader::reserved2)
94
+ .define_attr("offset_bits", &bmp::BitmapHeader::offset_bits)
95
+ .define_attr("size", &bmp::BitmapHeader::size)
96
+ .define_attr("width", &bmp::BitmapHeader::width)
97
+ .define_attr("height", &bmp::BitmapHeader::height)
98
+ .define_attr("planes", &bmp::BitmapHeader::planes)
99
+ .define_attr("bits_per_pixel", &bmp::BitmapHeader::bits_per_pixel)
100
+ .define_attr("compression", &bmp::BitmapHeader::compression)
101
+ .define_attr("size_image", &bmp::BitmapHeader::size_image)
102
+ .define_attr("x_pixels_per_meter", &bmp::BitmapHeader::x_pixels_per_meter)
103
+ .define_attr("y_pixels_per_meter", &bmp::BitmapHeader::y_pixels_per_meter)
104
+ .define_attr("clr_used", &bmp::BitmapHeader::clr_used)
105
+ .define_attr("clr_important", &bmp::BitmapHeader::clr_important);
106
+
107
+ // ============================================================================
108
+ // STRUCT BINDING: Pixel
109
+ // ============================================================================
110
+ // A more complex struct with multiple constructors and operators
111
+ rb_cBmpPixel = define_class_under<bmp::Pixel>(rb_mBmp, "Pixel")
112
+ // Expose RGB components as attributes
113
+ .define_attr("r", &bmp::Pixel::r)
114
+ .define_attr("g", &bmp::Pixel::g)
115
+ .define_attr("b", &bmp::Pixel::b)
116
+
117
+ // MULTIPLE CONSTRUCTORS (overloading)
118
+ // Rice supports multiple constructors with different signatures
119
+ .define_constructor(Constructor<bmp::Pixel>()) // Default: black pixel
120
+
121
+ // Constructor with named argument for better error messages
122
+ // In Ruby: Pixel.new(rgb: 0xFF0000)
123
+ .define_constructor(Constructor<bmp::Pixel, const std::int32_t>(),
124
+ Arg("rgb"))
125
+
126
+ // Constructor with multiple named arguments
127
+ // In Ruby: Pixel.new(red: 255, green: 128, blue: 64)
128
+ .define_constructor(Constructor<bmp::Pixel, const std::uint8_t, const std::uint8_t, const std::uint8_t>(),
129
+ Arg("red"), Arg("green"), Arg("blue"))
130
+
131
+ // OPERATORS
132
+ // Map C++ operators to Ruby methods
133
+ .define_method("==", &bmp::Pixel::operator==,
134
+ Arg("other"))
135
+ .define_method("!=", &bmp::Pixel::operator!=,
136
+ Arg("other"))
137
+
138
+ // LAMBDA for custom functionality
139
+ // The assign method copies values from another pixel
140
+ .define_method("assign", [](bmp::Pixel& self, bmp::Pixel& other)
141
+ {
142
+ self.r = other.r;
143
+ self.g = other.g;
144
+ self.b = other.b;
145
+ })
146
+
147
+ // INSPECT METHOD for debugging in IRB
148
+ .define_method("inspect", [](const bmp::Pixel& self) -> std::string
149
+ {
150
+ return "#<Bmp::Pixel r=" + std::to_string(self.r) +
151
+ " g=" + std::to_string(self.g) +
152
+ " b=" + std::to_string(self.b) + ">";
153
+ })
154
+
155
+ .define_method("to_s", [](const bmp::Pixel& self) -> std::string
156
+ {
157
+ return "Pixel(" + std::to_string(self.r) + ", " +
158
+ std::to_string(self.g) + ", " +
159
+ std::to_string(self.b) + ")";
160
+ });
161
+
162
+ // ============================================================================
163
+ // COLOR CONSTANTS
164
+ // ============================================================================
165
+ // Define predefined colors as module constants
166
+ // In Ruby: Bmp::Red, Bmp::Blue, etc.
167
+ rb_mBmp.define_constant("Aqua", bmp::Aqua);
168
+ rb_mBmp.define_constant("Beige", bmp::Beige);
169
+ rb_mBmp.define_constant("Black", bmp::Black);
170
+ rb_mBmp.define_constant("Blue", bmp::Blue);
171
+ rb_mBmp.define_constant("Brown", bmp::Brown);
172
+ rb_mBmp.define_constant("Chocolate", bmp::Chocolate);
173
+ rb_mBmp.define_constant("Coral", bmp::Coral);
174
+ rb_mBmp.define_constant("Crimson", bmp::Crimson);
175
+ rb_mBmp.define_constant("Cyan", bmp::Cyan);
176
+ rb_mBmp.define_constant("Firebrick", bmp::Firebrick);
177
+ rb_mBmp.define_constant("Gold", bmp::Gold);
178
+ rb_mBmp.define_constant("Gray", bmp::Gray);
179
+ rb_mBmp.define_constant("Green", bmp::Green);
180
+ rb_mBmp.define_constant("Indigo", bmp::Indigo);
181
+ rb_mBmp.define_constant("Lavender", bmp::Lavender);
182
+ rb_mBmp.define_constant("Lime", bmp::Lime);
183
+ rb_mBmp.define_constant("Magenta", bmp::Magenta);
184
+ rb_mBmp.define_constant("Maroon", bmp::Maroon);
185
+ rb_mBmp.define_constant("Navy", bmp::Navy);
186
+ rb_mBmp.define_constant("Olive", bmp::Olive);
187
+ rb_mBmp.define_constant("Orange", bmp::Orange);
188
+ rb_mBmp.define_constant("Pink", bmp::Pink);
189
+ rb_mBmp.define_constant("Purple", bmp::Purple);
190
+ rb_mBmp.define_constant("Red", bmp::Red);
191
+ rb_mBmp.define_constant("Salmon", bmp::Salmon);
192
+ rb_mBmp.define_constant("Silver", bmp::Silver);
193
+ rb_mBmp.define_constant("Snow", bmp::Snow);
194
+ rb_mBmp.define_constant("Teal", bmp::Teal);
195
+ rb_mBmp.define_constant("Tomato", bmp::Tomato);
196
+ rb_mBmp.define_constant("Turquoise", bmp::Turquoise);
197
+ rb_mBmp.define_constant("Violet", bmp::Violet);
198
+ rb_mBmp.define_constant("White", bmp::White);
199
+ rb_mBmp.define_constant("Wheat", bmp::Wheat);
200
+ rb_mBmp.define_constant("Yellow", bmp::Yellow);
201
+
202
+ // ============================================================================
203
+ // EXCEPTION CLASS with INHERITANCE
204
+ // ============================================================================
205
+ // Wrap a C++ exception class that inherits from std::runtime_error
206
+ // The second template parameter specifies the base class
207
+ rb_cBmpException = define_class_under<bmp::Exception, std::runtime_error>(rb_mBmp, "Exception")
208
+ .define_constructor(Constructor<bmp::Exception, const std::string&>(),
209
+ Arg("message"));
210
+
211
+ // ============================================================================
212
+ // MAIN CLASS: Bitmap
213
+ // ============================================================================
214
+ // This demonstrates most Rice features in one comprehensive class binding
215
+ rb_cBmpBitmap = define_class_under<bmp::Bitmap>(rb_mBmp, "Bitmap")
216
+
217
+ // --------------------------------------------------------------------
218
+ // CONSTRUCTORS
219
+ // --------------------------------------------------------------------
220
+ .define_constructor(Constructor<bmp::Bitmap>()) // Empty bitmap
221
+
222
+ .define_constructor(Constructor<bmp::Bitmap, const std::string&>(),
223
+ Arg("filename")) // Load from file
224
+
225
+ .define_constructor(Constructor<bmp::Bitmap, const std::int32_t, const std::int32_t>(),
226
+ Arg("width"), Arg("height")) // Create with dimensions
227
+
228
+ .define_constructor(Constructor<bmp::Bitmap, const bmp::Bitmap&>(),
229
+ Arg("other")) // Copy constructor
230
+
231
+ // --------------------------------------------------------------------
232
+ // DRAWING METHODS
233
+ // --------------------------------------------------------------------
234
+ .define_method("draw_line", &bmp::Bitmap::draw_line,
235
+ Arg("x1"), Arg("y1"), Arg("x2"), Arg("y2"), Arg("color"))
236
+
237
+ .define_method("fill_rect", &bmp::Bitmap::fill_rect,
238
+ Arg("x"), Arg("y"), Arg("width"), Arg("height"), Arg("color"))
239
+
240
+ .define_method("draw_rect", &bmp::Bitmap::draw_rect,
241
+ Arg("x"), Arg("y"), Arg("width"), Arg("height"), Arg("color"))
242
+
243
+ .define_method("draw_triangle", &bmp::Bitmap::draw_triangle,
244
+ Arg("x1"), Arg("y1"), Arg("x2"), Arg("y2"), Arg("x3"), Arg("y3"), Arg("color"))
245
+
246
+ .define_method("fill_triangle", &bmp::Bitmap::fill_triangle,
247
+ Arg("x1"), Arg("y1"), Arg("x2"), Arg("y2"), Arg("x3"), Arg("y3"), Arg("color"))
248
+
249
+ .define_method("draw_circle", &bmp::Bitmap::draw_circle,
250
+ Arg("center_x"), Arg("center_y"), Arg("radius"), Arg("color"))
251
+
252
+ .define_method("fill_circle", &bmp::Bitmap::fill_circle,
253
+ Arg("center_x"), Arg("center_y"), Arg("radius"), Arg("color"))
254
+
255
+ // --------------------------------------------------------------------
256
+ // OVERLOADED METHODS
257
+ // --------------------------------------------------------------------
258
+ // When a C++ class has overloaded methods (same name, different signatures),
259
+ // use template syntax to specify which overload to bind.
260
+ // The template parameter is: ReturnType(Class::*)(ArgTypes...) [const]
261
+
262
+ // Non-const version (returns mutable reference)
263
+ .define_method<bmp::Pixel&(bmp::Bitmap::*)(const std::int32_t, const std::int32_t)>(
264
+ "get", &bmp::Bitmap::get,
265
+ Arg("x"), Arg("y"))
266
+
267
+ // Const version (returns const reference)
268
+ .define_method<const bmp::Pixel&(bmp::Bitmap::*)(const std::int32_t, const std::int32_t) const>(
269
+ "get", &bmp::Bitmap::get,
270
+ Arg("x"), Arg("y"))
271
+
272
+ // --------------------------------------------------------------------
273
+ // SIMPLE ACCESSOR METHODS
274
+ // --------------------------------------------------------------------
275
+ .define_method("width", &bmp::Bitmap::width)
276
+ .define_method("height", &bmp::Bitmap::height)
277
+
278
+ // --------------------------------------------------------------------
279
+ // METHOD WITH DEFAULT ARGUMENT
280
+ // --------------------------------------------------------------------
281
+ // Use Arg("name") = value syntax for default arguments
282
+ .define_method("clear", &bmp::Bitmap::clear,
283
+ Arg("pixel") = static_cast<const bmp::Pixel>(bmp::Black))
284
+
285
+ // --------------------------------------------------------------------
286
+ // OPERATOR[] (array access)
287
+ // --------------------------------------------------------------------
288
+ // Overloaded [] operator - bind both const and non-const versions
289
+ .define_method<const bmp::Pixel&(bmp::Bitmap::*)(const std::size_t) const>(
290
+ "[]", &bmp::Bitmap::operator[],
291
+ Arg("i"))
292
+
293
+ .define_method<bmp::Pixel&(bmp::Bitmap::*)(const std::size_t)>(
294
+ "[]", &bmp::Bitmap::operator[],
295
+ Arg("i"))
296
+
297
+ // --------------------------------------------------------------------
298
+ // OPERATOR[]= (array assignment) - REQUIRES LAMBDA
299
+ // --------------------------------------------------------------------
300
+ // C++ doesn't have a separate []= operator, so we use a lambda
301
+ // This allows: bitmap[index] = pixel
302
+ .define_method("[]=", [](bmp::Bitmap& self, int index, bmp::Pixel& value)
303
+ {
304
+ self[index] = value;
305
+ })
306
+
307
+ // --------------------------------------------------------------------
308
+ // OTHER OPERATORS
309
+ // --------------------------------------------------------------------
310
+ .define_method("!", &bmp::Bitmap::operator!) // Check if empty
311
+
312
+ .define_method("==", &bmp::Bitmap::operator==,
313
+ Arg("image"))
314
+
315
+ .define_method("!=", &bmp::Bitmap::operator!=,
316
+ Arg("image"))
317
+
318
+ // Assignment operator (can't use = in Ruby, so use "assign")
319
+ .define_method<bmp::Bitmap&(bmp::Bitmap::*)(const bmp::Bitmap&)>(
320
+ "assign", &bmp::Bitmap::operator=,
321
+ Arg("image"))
322
+
323
+ .define_method<bmp::Bitmap&(bmp::Bitmap::*)(bmp::Bitmap&&) noexcept>(
324
+ "assign", &bmp::Bitmap::operator=,
325
+ Arg("image"))
326
+
327
+ // --------------------------------------------------------------------
328
+ // ITERATORS
329
+ // --------------------------------------------------------------------
330
+ // Rice can wrap C++ iterators to work with Ruby's each method
331
+ // This allows: bitmap.each { |pixel| ... }
332
+ .define_iterator<std::vector<bmp::Pixel>::iterator(bmp::Bitmap::*)() noexcept>(
333
+ &bmp::Bitmap::begin, &bmp::Bitmap::end, "each")
334
+
335
+ // Const iterator
336
+ .define_iterator<std::vector<bmp::Pixel>::const_iterator(bmp::Bitmap::*)() const noexcept>(
337
+ &bmp::Bitmap::cbegin, &bmp::Bitmap::cend, "each_const")
338
+
339
+ // Reverse iterator: bitmap.each_reverse { |pixel| ... }
340
+ .define_iterator<std::vector<bmp::Pixel>::reverse_iterator(bmp::Bitmap::*)() noexcept>(
341
+ &bmp::Bitmap::rbegin, &bmp::Bitmap::rend, "each_reverse")
342
+
343
+ // Reverse const iterator: bitmap.each_reverse { |pixel| ... }
344
+ .define_iterator<std::vector<bmp::Pixel>::const_reverse_iterator(bmp::Bitmap::*)() const noexcept>(
345
+ &bmp::Bitmap::crbegin, &bmp::Bitmap::crend, "each_const_reverse")
346
+
347
+ // --------------------------------------------------------------------
348
+ // MODIFIER METHODS
349
+ // --------------------------------------------------------------------
350
+ .define_method("set", &bmp::Bitmap::set,
351
+ Arg("x"), Arg("y"), Arg("color"))
352
+
353
+ // --------------------------------------------------------------------
354
+ // TRANSFORMATION METHODS (return new Bitmap)
355
+ // --------------------------------------------------------------------
356
+ .define_method("flip_v", &bmp::Bitmap::flip_v)
357
+ .define_method("flip_h", &bmp::Bitmap::flip_h)
358
+ .define_method("rotate_90_left", &bmp::Bitmap::rotate_90_left)
359
+ .define_method("rotate_90_right", &bmp::Bitmap::rotate_90_right)
360
+
361
+ // --------------------------------------------------------------------
362
+ // FILE I/O METHODS
363
+ // --------------------------------------------------------------------
364
+ // std::filesystem::path is automatically converted from Ruby strings
365
+ .define_method("save", &bmp::Bitmap::save,
366
+ Arg("filename"))
367
+
368
+ .define_method("load", &bmp::Bitmap::load,
369
+ Arg("filename"))
370
+
371
+ // --------------------------------------------------------------------
372
+ // INSPECT AND TO_S for debugging
373
+ // --------------------------------------------------------------------
374
+ .define_method("inspect", [](const bmp::Bitmap& self) -> std::string
375
+ {
376
+ return "#<Bmp::Bitmap " + std::to_string(self.width()) + "x" +
377
+ std::to_string(self.height()) + ">";
378
+ })
379
+
380
+ .define_method("to_s", [](const bmp::Bitmap& self) -> std::string
381
+ {
382
+ return "Bitmap(" + std::to_string(self.width()) + ", " +
383
+ std::to_string(self.height()) + ")";
384
+ })
385
+
386
+ // SIZE method for convenience
387
+ .define_method("size", [](const bmp::Bitmap& self) -> std::size_t
388
+ {
389
+ return static_cast<std::size_t>(self.width()) * static_cast<std::size_t>(self.height());
390
+ })
391
+
392
+ // EMPTY? method
393
+ .define_method("empty?", [](const bmp::Bitmap& self) -> bool
394
+ {
395
+ return !self; // Uses operator!
396
+ });
397
+ }
398
+
399
+ /**
400
+ * Ruby Extension Entry Point
401
+ *
402
+ * This function is called by Ruby when the extension is loaded via 'require'.
403
+ * The function name MUST be Init_<extension_name> where <extension_name>
404
+ * matches the name in create_makefile() in extconf.rb.
405
+ *
406
+ * Rice::detail::cpp_protect() wraps the initialization in exception handling,
407
+ * converting any C++ exceptions to Ruby exceptions.
408
+ */
409
+ extern "C"
410
+ void Init_bitmap_plus_plus_ruby()
411
+ {
412
+ Rice::detail::cpp_protect([]
413
+ {
414
+ // Setup Ruby bindings
415
+ initialize();
416
+
417
+ // Setup introspection support to generate RBS signatures and documentation
418
+ Init_Rice_Api();
419
+ });
420
+ }
@@ -0,0 +1,11 @@
1
+ #include <rice/rice.hpp>
2
+ #include <rice/stl.hpp>
3
+ #include <rice/api.hpp>
4
+
5
+ extern "C"
6
+ #if defined(_WIN32)
7
+ __declspec(dllexport)
8
+ #else
9
+ __attribute__((visibility("default")))
10
+ #endif
11
+ void Init_bitmap_plus_plus_ruby();