rays 0.1.25 → 0.1.28

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6f7cc20d72750eb7d8ff9364831172720065e9f0339f0f865760c56b31e515b
4
- data.tar.gz: dd31681766629607b2fa461ae12d6904d325c0b8babba803faaf0443b0472242
3
+ metadata.gz: 38052c848aef75871de813ae9cc59a956672b1c6b8db25b55916f041ae0df976
4
+ data.tar.gz: d1f462fce0b73364a015fa1826eef17c3d1a4ac0b4378590f20438d87ce8e1cf
5
5
  SHA512:
6
- metadata.gz: f72e8c4cf249c3c7646a8d627e941dca67e7ac29a35d907e0c9ceac7522e3cdfd0df45e9eec8253a92fb70f031d53b5660eab594e50adfe6b8d12e4cb56b9a4e
7
- data.tar.gz: e7f4017fd414def3b492173e6a61f53a9fc2fef18dbe409eb7be6e27840ecbe2a26af60f62d7d507dc6ba12bd740e7606da2871ea218db1e5e5b116a242f8a84
6
+ metadata.gz: 9e01828d4ac2ad4749a9d050d3890669be7e35dd057cc92b0dae23f645954b44bf7f3775d193ef36d9590d10879175a7937b28ceddf0bf9fd29a84723f0cfdbe
7
+ data.tar.gz: da8b670d9e704d4cc48070d5d252ec504e433f00222160a5c42ccf7a036eabc1a31580b6318da59672bc8576b0dddf84fce635ce9194f4a462eebfc8d4e03451
@@ -26,15 +26,51 @@ VALUE alloc(VALUE klass)
26
26
  }
27
27
 
28
28
  static
29
- VALUE canvas(VALUE self, VALUE x, VALUE y, VALUE width, VALUE height)
29
+ VALUE canvas(VALUE self)
30
30
  {
31
31
  CHECK;
32
+ check_arg_count(__FILE__, __LINE__, "Painter#canvas", argc, 4, 5, 6, 7);
32
33
 
33
- coord xx = to<coord>(x);
34
- coord yy = to<coord>(y);
35
- coord ww = to<coord>(width);
36
- coord hh = to<coord>(height);
37
- THIS->canvas(xx, yy, ww, hh);
34
+ switch (argc)
35
+ {
36
+ case 4:
37
+ THIS->canvas(
38
+ to<coord>(argv[0]),
39
+ to<coord>(argv[1]),
40
+ to<coord>(argv[2]),
41
+ to<coord>(argv[3]));
42
+ break;
43
+
44
+ case 5:
45
+ THIS->canvas(
46
+ to<coord>(argv[0]),
47
+ to<coord>(argv[1]),
48
+ to<coord>(argv[2]),
49
+ to<coord>(argv[3]),
50
+ to<float>(argv[4]));
51
+ break;
52
+
53
+ case 6:
54
+ THIS->canvas(
55
+ to<coord>(argv[0]),
56
+ to<coord>(argv[1]),
57
+ to<coord>(argv[2]),
58
+ to<coord>(argv[3]),
59
+ to<coord>(argv[4]),
60
+ to<coord>(argv[5]));
61
+ break;
62
+
63
+ case 7:
64
+ THIS->canvas(
65
+ to<coord>(argv[0]),
66
+ to<coord>(argv[1]),
67
+ to<coord>(argv[2]),
68
+ to<coord>(argv[3]),
69
+ to<coord>(argv[4]),
70
+ to<coord>(argv[5]),
71
+ to<float>(argv[6]));
72
+ break;
73
+ }
38
74
 
39
75
  return self;
40
76
  }
@@ -382,6 +418,21 @@ VALUE get_nsegment(VALUE self)
382
418
  return value(THIS->nsegment());
383
419
  }
384
420
 
421
+ static
422
+ VALUE set_blend_mode(VALUE self, VALUE mode)
423
+ {
424
+ CHECK;
425
+ THIS->set_blend_mode(to<Rays::BlendMode>(mode));
426
+ return self;
427
+ }
428
+
429
+ static
430
+ VALUE get_blend_mode(VALUE self)
431
+ {
432
+ CHECK;
433
+ return value(THIS->blend_mode());
434
+ }
435
+
385
436
  static
386
437
  VALUE set_clip(VALUE self)
387
438
  {
@@ -428,7 +479,10 @@ VALUE set_shader(VALUE self)
428
479
  CHECK;
429
480
  check_arg_count(__FILE__, __LINE__, "Painter#set_shader", argc, 1);
430
481
 
431
- THIS->set_shader(to<Rays::Shader>(argc, argv));
482
+ if (argc >= 1 && !argv[0])
483
+ THIS->no_shader();
484
+ else
485
+ THIS->set_shader(to<Rays::Shader>(argc, argv));
432
486
  return self;
433
487
  }
434
488
 
@@ -436,7 +490,9 @@ static
436
490
  VALUE get_shader(VALUE self)
437
491
  {
438
492
  CHECK;
439
- return value(THIS->shader());
493
+
494
+ const Rays::Shader& shader = THIS->shader();
495
+ return shader ? value(shader) : nil();
440
496
  }
441
497
 
442
498
  static
@@ -553,7 +609,7 @@ Init_painter ()
553
609
  cPainter = rb_define_class_under(mRays, "Painter", rb_cObject);
554
610
  rb_define_alloc_func(cPainter, alloc);
555
611
 
556
- rb_define_method(cPainter, "canvas", RUBY_METHOD_FUNC(canvas), 4);
612
+ rb_define_method(cPainter, "canvas", RUBY_METHOD_FUNC(canvas), -1);
557
613
  rb_define_method(cPainter, "bounds", RUBY_METHOD_FUNC(bounds), 0);
558
614
  rb_define_method(cPainter, "pixel_density", RUBY_METHOD_FUNC(pixel_density), 0);
559
615
 
@@ -589,6 +645,8 @@ Init_painter ()
589
645
  rb_define_method(cPainter, "miter_limit", RUBY_METHOD_FUNC(get_miter_limit), 0);
590
646
  rb_define_method(cPainter, "nsegment=", RUBY_METHOD_FUNC(set_nsegment), 1);
591
647
  rb_define_method(cPainter, "nsegment", RUBY_METHOD_FUNC(get_nsegment), 0);
648
+ rb_define_method(cPainter, "blend_mode=", RUBY_METHOD_FUNC(set_blend_mode), 1);
649
+ rb_define_method(cPainter, "blend_mode", RUBY_METHOD_FUNC(get_blend_mode), 0);
592
650
  rb_define_method(cPainter, "clip=", RUBY_METHOD_FUNC(set_clip), -1);
593
651
  rb_define_method(cPainter, "clip", RUBY_METHOD_FUNC(get_clip), 0);
594
652
  rb_define_method(cPainter, "no_clip", RUBY_METHOD_FUNC(no_clip), 0);
@@ -7,6 +7,7 @@
7
7
 
8
8
  RUCY_DEFINE_CONVERT_TO(Rays::CapType)
9
9
  RUCY_DEFINE_CONVERT_TO(Rays::JoinType)
10
+ RUCY_DEFINE_CONVERT_TO(Rays::BlendMode)
10
11
 
11
12
 
12
13
  template <typename T>
@@ -29,6 +30,18 @@ static std::vector<EnumType<Rays::JoinType>> JOIN_TYPES({
29
30
  {"JOIN_SQUARE", "SQUARE", Rays::JOIN_SQUARE},
30
31
  });
31
32
 
33
+ static std::vector<EnumType<Rays::BlendMode>> BLEND_MODES({
34
+ {"BLEND_NORMAL", "NORMAL", Rays::BLEND_NORMAL},
35
+ {"BLEND_ADD", "ADD", Rays::BLEND_ADD},
36
+ {"BLEND_SUBTRACT", "SUBTRACT", Rays::BLEND_SUBTRACT},
37
+ {"BLEND_LIGHTEST", "LIGHTEST", Rays::BLEND_LIGHTEST},
38
+ {"BLEND_DARKEST", "DARKEST", Rays::BLEND_DARKEST},
39
+ {"BLEND_EXCLUSION", "EXCLUSION", Rays::BLEND_EXCLUSION},
40
+ {"BLEND_MULTIPLY", "MULTIPLY", Rays::BLEND_MULTIPLY},
41
+ {"BLEND_SCREEN", "SCREEN", Rays::BLEND_SCREEN},
42
+ {"BLEND_REPLACE", "REPLACE", Rays::BLEND_REPLACE},
43
+ });
44
+
32
45
 
33
46
  static
34
47
  VALUE init(VALUE self)
@@ -60,6 +73,9 @@ Init_rays ()
60
73
 
61
74
  for (auto it = JOIN_TYPES.begin(); it != JOIN_TYPES.end(); ++it)
62
75
  mRays.define_const(it->name, it->type);
76
+
77
+ for (auto it = BLEND_MODES.begin(); it != BLEND_MODES.end(); ++it)
78
+ mRays.define_const(it->name, it->type);
63
79
  }
64
80
 
65
81
 
@@ -129,6 +145,37 @@ namespace Rucy
129
145
  }
130
146
 
131
147
 
148
+ template <> Rays::BlendMode
149
+ value_to<Rays::BlendMode> (int argc, const Value* argv, bool convert)
150
+ {
151
+ assert(argc > 0 && argv);
152
+
153
+ if (convert)
154
+ {
155
+ if (argv->is_s() || argv->is_sym())
156
+ {
157
+ const char* str = argv->c_str();
158
+ for (auto it = BLEND_MODES.begin(); it != BLEND_MODES.end(); ++it)
159
+ {
160
+ if (
161
+ strcasecmp(str, it->name) == 0 ||
162
+ strcasecmp(str, it->short_name) == 0)
163
+ {
164
+ return it->type;
165
+ }
166
+ }
167
+ argument_error(__FILE__, __LINE__, "invalid blend mode -- %s", str);
168
+ }
169
+ }
170
+
171
+ int type = value_to<int>(*argv, convert);
172
+ if (type < 0 || Rays::BLEND_MAX <= type)
173
+ argument_error(__FILE__, __LINE__, "invalid blend mode -- %d", type);
174
+
175
+ return (Rays::BlendMode) type;
176
+ }
177
+
178
+
132
179
  }// Rucy
133
180
 
134
181
 
data/Rakefile CHANGED
@@ -38,4 +38,4 @@ test_ruby_extension
38
38
  generate_documents
39
39
  build_ruby_gem
40
40
 
41
- task :default => :test
41
+ task :default => :ext
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.25
1
+ 0.1.28
data/ext/rays/painter.cpp CHANGED
@@ -27,15 +27,51 @@ RUCY_DEF_ALLOC(alloc, klass)
27
27
  RUCY_END
28
28
 
29
29
  static
30
- RUCY_DEF4(canvas, x, y, width, height)
30
+ RUCY_DEFN(canvas)
31
31
  {
32
32
  CHECK;
33
+ check_arg_count(__FILE__, __LINE__, "Painter#canvas", argc, 4, 5, 6, 7);
33
34
 
34
- coord xx = to<coord>(x);
35
- coord yy = to<coord>(y);
36
- coord ww = to<coord>(width);
37
- coord hh = to<coord>(height);
38
- THIS->canvas(xx, yy, ww, hh);
35
+ switch (argc)
36
+ {
37
+ case 4:
38
+ THIS->canvas(
39
+ to<coord>(argv[0]),
40
+ to<coord>(argv[1]),
41
+ to<coord>(argv[2]),
42
+ to<coord>(argv[3]));
43
+ break;
44
+
45
+ case 5:
46
+ THIS->canvas(
47
+ to<coord>(argv[0]),
48
+ to<coord>(argv[1]),
49
+ to<coord>(argv[2]),
50
+ to<coord>(argv[3]),
51
+ to<float>(argv[4]));
52
+ break;
53
+
54
+ case 6:
55
+ THIS->canvas(
56
+ to<coord>(argv[0]),
57
+ to<coord>(argv[1]),
58
+ to<coord>(argv[2]),
59
+ to<coord>(argv[3]),
60
+ to<coord>(argv[4]),
61
+ to<coord>(argv[5]));
62
+ break;
63
+
64
+ case 7:
65
+ THIS->canvas(
66
+ to<coord>(argv[0]),
67
+ to<coord>(argv[1]),
68
+ to<coord>(argv[2]),
69
+ to<coord>(argv[3]),
70
+ to<coord>(argv[4]),
71
+ to<coord>(argv[5]),
72
+ to<float>(argv[6]));
73
+ break;
74
+ }
39
75
 
40
76
  return self;
41
77
  }
@@ -417,6 +453,23 @@ RUCY_DEF0(get_nsegment)
417
453
  }
418
454
  RUCY_END
419
455
 
456
+ static
457
+ RUCY_DEF1(set_blend_mode, mode)
458
+ {
459
+ CHECK;
460
+ THIS->set_blend_mode(to<Rays::BlendMode>(mode));
461
+ return self;
462
+ }
463
+ RUCY_END
464
+
465
+ static
466
+ RUCY_DEF0(get_blend_mode)
467
+ {
468
+ CHECK;
469
+ return value(THIS->blend_mode());
470
+ }
471
+ RUCY_END
472
+
420
473
  static
421
474
  RUCY_DEFN(set_clip)
422
475
  {
@@ -468,7 +521,10 @@ RUCY_DEFN(set_shader)
468
521
  CHECK;
469
522
  check_arg_count(__FILE__, __LINE__, "Painter#set_shader", argc, 1);
470
523
 
471
- THIS->set_shader(to<Rays::Shader>(argc, argv));
524
+ if (argc >= 1 && !argv[0])
525
+ THIS->no_shader();
526
+ else
527
+ THIS->set_shader(to<Rays::Shader>(argc, argv));
472
528
  return self;
473
529
  }
474
530
  RUCY_END
@@ -477,7 +533,9 @@ static
477
533
  RUCY_DEF0(get_shader)
478
534
  {
479
535
  CHECK;
480
- return value(THIS->shader());
536
+
537
+ const Rays::Shader& shader = THIS->shader();
538
+ return shader ? value(shader) : nil();
481
539
  }
482
540
  RUCY_END
483
541
 
@@ -641,6 +699,8 @@ Init_painter ()
641
699
  cPainter.define_method("miter_limit", get_miter_limit);
642
700
  cPainter.define_method("nsegment=", set_nsegment);
643
701
  cPainter.define_method("nsegment", get_nsegment);
702
+ cPainter.define_method("blend_mode=", set_blend_mode);
703
+ cPainter.define_method("blend_mode", get_blend_mode);
644
704
  cPainter.define_method( "clip=", set_clip);
645
705
  cPainter.define_method( "clip", get_clip);
646
706
  cPainter.define_method("no_clip", no_clip);
data/ext/rays/rays.cpp CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  RUCY_DEFINE_CONVERT_TO(Rays::CapType)
9
9
  RUCY_DEFINE_CONVERT_TO(Rays::JoinType)
10
+ RUCY_DEFINE_CONVERT_TO(Rays::BlendMode)
10
11
 
11
12
 
12
13
  template <typename T>
@@ -29,6 +30,18 @@ static std::vector<EnumType<Rays::JoinType>> JOIN_TYPES({
29
30
  {"JOIN_SQUARE", "SQUARE", Rays::JOIN_SQUARE},
30
31
  });
31
32
 
33
+ static std::vector<EnumType<Rays::BlendMode>> BLEND_MODES({
34
+ {"BLEND_NORMAL", "NORMAL", Rays::BLEND_NORMAL},
35
+ {"BLEND_ADD", "ADD", Rays::BLEND_ADD},
36
+ {"BLEND_SUBTRACT", "SUBTRACT", Rays::BLEND_SUBTRACT},
37
+ {"BLEND_LIGHTEST", "LIGHTEST", Rays::BLEND_LIGHTEST},
38
+ {"BLEND_DARKEST", "DARKEST", Rays::BLEND_DARKEST},
39
+ {"BLEND_EXCLUSION", "EXCLUSION", Rays::BLEND_EXCLUSION},
40
+ {"BLEND_MULTIPLY", "MULTIPLY", Rays::BLEND_MULTIPLY},
41
+ {"BLEND_SCREEN", "SCREEN", Rays::BLEND_SCREEN},
42
+ {"BLEND_REPLACE", "REPLACE", Rays::BLEND_REPLACE},
43
+ });
44
+
32
45
 
33
46
  static
34
47
  RUCY_DEF0(init)
@@ -62,6 +75,9 @@ Init_rays ()
62
75
 
63
76
  for (auto it = JOIN_TYPES.begin(); it != JOIN_TYPES.end(); ++it)
64
77
  mRays.define_const(it->name, it->type);
78
+
79
+ for (auto it = BLEND_MODES.begin(); it != BLEND_MODES.end(); ++it)
80
+ mRays.define_const(it->name, it->type);
65
81
  }
66
82
 
67
83
 
@@ -131,6 +147,37 @@ namespace Rucy
131
147
  }
132
148
 
133
149
 
150
+ template <> Rays::BlendMode
151
+ value_to<Rays::BlendMode> (int argc, const Value* argv, bool convert)
152
+ {
153
+ assert(argc > 0 && argv);
154
+
155
+ if (convert)
156
+ {
157
+ if (argv->is_s() || argv->is_sym())
158
+ {
159
+ const char* str = argv->c_str();
160
+ for (auto it = BLEND_MODES.begin(); it != BLEND_MODES.end(); ++it)
161
+ {
162
+ if (
163
+ strcasecmp(str, it->name) == 0 ||
164
+ strcasecmp(str, it->short_name) == 0)
165
+ {
166
+ return it->type;
167
+ }
168
+ }
169
+ argument_error(__FILE__, __LINE__, "invalid blend mode -- %s", str);
170
+ }
171
+ }
172
+
173
+ int type = value_to<int>(*argv, convert);
174
+ if (type < 0 || Rays::BLEND_MAX <= type)
175
+ argument_error(__FILE__, __LINE__, "invalid blend mode -- %d", type);
176
+
177
+ return (Rays::BlendMode) type;
178
+ }
179
+
180
+
134
181
  }// Rucy
135
182
 
136
183
 
data/include/rays/defs.h CHANGED
@@ -56,6 +56,32 @@ namespace Rays
56
56
  };// JoinType
57
57
 
58
58
 
59
+ enum BlendMode
60
+ {
61
+
62
+ BLEND_NORMAL = 0,
63
+
64
+ BLEND_ADD,
65
+
66
+ BLEND_SUBTRACT,
67
+
68
+ BLEND_LIGHTEST,
69
+
70
+ BLEND_DARKEST,
71
+
72
+ BLEND_EXCLUSION,
73
+
74
+ BLEND_MULTIPLY,
75
+
76
+ BLEND_SCREEN,
77
+
78
+ BLEND_REPLACE,
79
+
80
+ BLEND_MAX
81
+
82
+ };// BlendMode
83
+
84
+
59
85
  }// Rays
60
86
 
61
87
 
@@ -174,7 +174,8 @@ namespace Rays
174
174
  //
175
175
  // states
176
176
  //
177
- void set_background (float red, float green, float blue, float alpha = 1, bool clear = true);
177
+ void set_background (
178
+ float red, float green, float blue, float alpha = 1, bool clear = true);
178
179
 
179
180
  void set_background (const Color& color, bool clear = true);
180
181
 
@@ -218,6 +219,10 @@ namespace Rays
218
219
 
219
220
  uint nsegment () const;
220
221
 
222
+ void set_blend_mode (BlendMode mode);
223
+
224
+ BlendMode blend_mode () const;
225
+
221
226
  void set_clip (coord x, coord y, coord width, coord height);
222
227
 
223
228
  void set_clip (const Bounds& bounds);
@@ -25,5 +25,7 @@ RUCY_DECLARE_CONVERT_TO(Rays::CapType)
25
25
 
26
26
  RUCY_DECLARE_CONVERT_TO(Rays::JoinType)
27
27
 
28
+ RUCY_DECLARE_CONVERT_TO(Rays::BlendMode)
29
+
28
30
 
29
31
  #endif//EOH
data/lib/rays/painter.rb CHANGED
@@ -108,9 +108,21 @@ module Rays
108
108
  square: JOIN_SQUARE
109
109
  }
110
110
 
111
+ const_symbol_accessor :blend_mode, **{
112
+ normal: BLEND_NORMAL,
113
+ add: BLEND_ADD,
114
+ subtract: BLEND_SUBTRACT,
115
+ lightest: BLEND_LIGHTEST,
116
+ darkest: BLEND_DARKEST,
117
+ exclusion: BLEND_EXCLUSION,
118
+ multiply: BLEND_MULTIPLY,
119
+ screen: BLEND_SCREEN,
120
+ replace: BLEND_REPLACE
121
+ }
122
+
111
123
  universal_accessor :background, :fill, :stroke, :color,
112
124
  :stroke_width, :stroke_cap, :stroke_join, :miter_limit,
113
- :nsegment, :shader, :clip, :font
125
+ :nsegment, :blend_mode, :shader, :clip, :font
114
126
 
115
127
  private
116
128
 
data/rays.gemspec CHANGED
@@ -28,8 +28,8 @@ Gem::Specification.new do |s|
28
28
  s.platform = Gem::Platform::RUBY
29
29
  s.required_ruby_version = '>= 2.6.0'
30
30
 
31
- s.add_runtime_dependency 'xot', '~> 0.1.25'
32
- s.add_runtime_dependency 'rucy', '~> 0.1.25'
31
+ s.add_runtime_dependency 'xot', '~> 0.1.28'
32
+ s.add_runtime_dependency 'rucy', '~> 0.1.28'
33
33
 
34
34
  s.files = `git ls-files`.split $/
35
35
  s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
data/src/frame_buffer.cpp CHANGED
@@ -110,7 +110,7 @@ namespace Rays
110
110
 
111
111
  self->texture = texture;
112
112
 
113
- #if 0
113
+ #if 1
114
114
  int w = texture.reserved_width(), h = texture.reserved_height();
115
115
  if (
116
116
  w != self->render_buffer.width() ||
@@ -119,8 +119,7 @@ namespace Rays
119
119
  RenderBuffer rb = RenderBuffer(w, h);
120
120
 
121
121
  glFramebufferRenderbuffer(
122
- GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
123
- GL_RENDERBUFFER, rb.id());
122
+ GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb.id());
124
123
  OpenGL_check_error(__FILE__, __LINE__);
125
124
 
126
125
  self->render_buffer = rb;
data/src/ios/bitmap.mm CHANGED
@@ -224,9 +224,26 @@ namespace Rays
224
224
  return bitmap.self->modified;
225
225
  }
226
226
 
227
+ static CFStringRef
228
+ get_bitmap_type (const char* path_)
229
+ {
230
+ String path = path_;
231
+ path = path.downcase();
232
+ if (path.ends_with(".png")) return kUTTypePNG;
233
+ if (path.ends_with(".gif")) return kUTTypeGIF;
234
+ if (path.ends_with(".bmp")) return kUTTypeBMP;
235
+ if (path.ends_with(".jpg") || path.ends_with(".jpeg")) return kUTTypeJPEG;
236
+ if (path.ends_with(".tif") || path.ends_with(".tiff")) return kUTTypeTIFF;
237
+ return nil;
238
+ }
239
+
227
240
  void
228
241
  Bitmap_save (const Bitmap& bmp, const char* path_)
229
242
  {
243
+ const CFStringRef type = get_bitmap_type(path_);
244
+ if (!type)
245
+ argument_error(__FILE__, __LINE__, "unknown image file type");
246
+
230
247
  std::shared_ptr<CGImage> img(bmp.self->get_image(), CGImageRelease);
231
248
  if (!img)
232
249
  rays_error(__FILE__, __LINE__, "getting CGImage failed.");
@@ -237,7 +254,7 @@ namespace Rays
237
254
  rays_error(__FILE__, __LINE__, "creating NSURL failed.");
238
255
 
239
256
  std::shared_ptr<CGImageDestination> dest(
240
- CGImageDestinationCreateWithURL((CFURLRef) url, kUTTypePNG, 1, NULL),
257
+ CGImageDestinationCreateWithURL((CFURLRef) url, type, 1, NULL),
241
258
  safe_cfrelease);
242
259
  if (!dest)
243
260
  rays_error(__FILE__, __LINE__, "CGImageDestinationCreateWithURL() failed.");
data/src/osx/bitmap.mm CHANGED
@@ -223,9 +223,26 @@ namespace Rays
223
223
  return bitmap.self->modified;
224
224
  }
225
225
 
226
+ static CFStringRef
227
+ get_bitmap_type (const char* path_)
228
+ {
229
+ String path = path_;
230
+ path = path.downcase();
231
+ if (path.ends_with(".png")) return kUTTypePNG;
232
+ if (path.ends_with(".gif")) return kUTTypeGIF;
233
+ if (path.ends_with(".bmp")) return kUTTypeBMP;
234
+ if (path.ends_with(".jpg") || path.ends_with(".jpeg")) return kUTTypeJPEG;
235
+ if (path.ends_with(".tif") || path.ends_with(".tiff")) return kUTTypeTIFF;
236
+ return nil;
237
+ }
238
+
226
239
  void
227
240
  Bitmap_save (const Bitmap& bmp, const char* path_)
228
241
  {
242
+ const CFStringRef type = get_bitmap_type(path_);
243
+ if (!type)
244
+ argument_error(__FILE__, __LINE__, "unknown image file type");
245
+
229
246
  std::shared_ptr<CGImage> img(bmp.self->get_image(), CGImageRelease);
230
247
  if (!img)
231
248
  rays_error(__FILE__, __LINE__, "getting CGImage failed.");
@@ -236,7 +253,7 @@ namespace Rays
236
253
  rays_error(__FILE__, __LINE__, "creating NSURL failed.");
237
254
 
238
255
  std::shared_ptr<CGImageDestination> dest(
239
- CGImageDestinationCreateWithURL((CFURLRef) url, kUTTypePNG, 1, NULL),
256
+ CGImageDestinationCreateWithURL((CFURLRef) url, type, 1, NULL),
240
257
  safe_cfrelease);
241
258
  if (!dest)
242
259
  rays_error(__FILE__, __LINE__, "CGImageDestinationCreateWithURL() failed.");
data/src/painter.cpp CHANGED
@@ -56,6 +56,8 @@ namespace Rays
56
56
 
57
57
  uint nsegment;
58
58
 
59
+ BlendMode blend_mode;
60
+
59
61
  Bounds clip;
60
62
 
61
63
  Font font;
@@ -72,6 +74,7 @@ namespace Rays
72
74
  stroke_join = JOIN_DEFAULT;
73
75
  miter_limit = JOIN_DEFAULT_MITER_LIMIT;
74
76
  nsegment = 0;
77
+ blend_mode = BLEND_NORMAL;
75
78
  clip .reset(-1);
76
79
  font = default_font();
77
80
  shader = Shader();
@@ -107,7 +110,7 @@ namespace Rays
107
110
  return
108
111
  texture &&
109
112
  texcoord_min.x < texcoord_max.x &&
110
- texcoord_min.x < texcoord_max.y;
113
+ texcoord_min.y < texcoord_max.y;
111
114
  }
112
115
 
113
116
  bool operator ! () const
@@ -125,10 +128,14 @@ namespace Rays
125
128
 
126
129
  GLclampf color_clear[4];
127
130
 
131
+ GLboolean depth_test;
132
+ GLint depth_func;
133
+
128
134
  GLboolean scissor_test;
129
135
  GLint scissor_box[4];
130
136
 
131
137
  GLboolean blend;
138
+ GLint blend_equation_rgb, blend_equation_alpha;
132
139
  GLint blend_src_rgb, blend_src_alpha, blend_dst_rgb, blend_dst_alpha;
133
140
 
134
141
  GLint framebuffer_binding;
@@ -139,10 +146,15 @@ namespace Rays
139
146
 
140
147
  glGetFloatv(GL_COLOR_CLEAR_VALUE, color_clear);
141
148
 
149
+ glGetBooleanv(GL_DEPTH_TEST, &depth_test);
150
+ glGetIntegerv(GL_DEPTH_FUNC, &depth_func);
151
+
142
152
  glGetBooleanv(GL_SCISSOR_TEST, &scissor_test);
143
153
  glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
144
154
 
145
155
  glGetBooleanv(GL_BLEND, &blend);
156
+ glGetIntegerv(GL_BLEND_EQUATION_RGB, &blend_equation_rgb);
157
+ glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blend_equation_alpha);
146
158
  glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb);
147
159
  glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha);
148
160
  glGetIntegerv(GL_BLEND_DST_RGB, &blend_dst_rgb);
@@ -158,10 +170,14 @@ namespace Rays
158
170
  glClearColor(
159
171
  color_clear[0], color_clear[1], color_clear[2], color_clear[3]);
160
172
 
173
+ enable(GL_DEPTH_TEST, depth_test);
174
+ glDepthFunc(depth_func);
175
+
161
176
  enable(GL_SCISSOR_TEST, scissor_test);
162
177
  glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
163
178
 
164
179
  enable(GL_BLEND, blend);
180
+ glBlendEquationSeparate(blend_equation_rgb, blend_equation_alpha);
165
181
  glBlendFuncSeparate(
166
182
  blend_src_rgb, blend_dst_rgb, blend_src_alpha, blend_dst_alpha);
167
183
 
@@ -566,7 +582,7 @@ namespace Rays
566
582
  Painter::canvas (
567
583
  coord x, coord y, coord width, coord height, float pixel_density)
568
584
  {
569
- canvas(Bounds(x, y, -100, width, height, 200), pixel_density);
585
+ canvas(x, y, 0, width, height, 0, pixel_density);
570
586
  }
571
587
 
572
588
  void
@@ -639,10 +655,14 @@ namespace Rays
639
655
  self->opengl_state.push();
640
656
 
641
657
  //glEnable(GL_CULL_FACE);
642
- glEnable(GL_BLEND);
643
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
658
+
659
+ glEnable(GL_DEPTH_TEST);
660
+ glDepthFunc(GL_LEQUAL);
644
661
  OpenGL_check_error(__FILE__, __LINE__);
645
662
 
663
+ glEnable(GL_BLEND);
664
+ set_blend_mode(self->state.blend_mode);
665
+
646
666
  FrameBuffer& fb = self->frame_buffer;
647
667
  if (fb) FrameBuffer_bind(fb.id());
648
668
 
@@ -656,16 +676,23 @@ namespace Rays
656
676
  coord x1 = vp.x, x2 = vp.x + vp.width;
657
677
  coord y1 = vp.y, y2 = vp.y + vp.height;
658
678
  coord z1 = vp.z, z2 = vp.z + vp.depth;
659
- if (z1 == 0 && z2 == 0) {z1 = -100; z2 = 200;}
679
+ if (z1 == 0 && z2 == 0) {z1 = -1000; z2 = 1000;}
660
680
  if (!fb) std::swap(y1, y2);
661
681
 
662
682
  self->position_matrix.reset(1);
663
683
  self->position_matrix *= to_rays(glm::ortho(x1, x2, y1, y2));
684
+
685
+ // map z to 0.0-1.0
686
+ self->position_matrix.scale(1, 1, 1.0 / (z2 - z1));
687
+ self->position_matrix.translate(0, 0, -z2);
688
+
664
689
  //self->position_matrix.translate(0.375f, 0.375f);
665
690
 
666
691
  self->update_clip();
667
692
 
668
693
  self->painting = true;
694
+
695
+ glClear(GL_DEPTH_BUFFER_BIT);
669
696
  }
670
697
 
671
698
  void
@@ -703,7 +730,7 @@ namespace Rays
703
730
 
704
731
  const Color& c = self->state.background;
705
732
  glClearColor(c.red, c.green, c.blue, c.alpha);
706
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
733
+ glClear(GL_COLOR_BUFFER_BIT);
707
734
  OpenGL_check_error(__FILE__, __LINE__);
708
735
  }
709
736
 
@@ -1293,6 +1320,72 @@ namespace Rays
1293
1320
  return self->state.nsegment;
1294
1321
  }
1295
1322
 
1323
+ void
1324
+ Painter::set_blend_mode (BlendMode mode)
1325
+ {
1326
+ self->state.blend_mode = mode;
1327
+ switch (mode)
1328
+ {
1329
+ case BLEND_NORMAL:
1330
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1331
+ glBlendFuncSeparate(
1332
+ GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
1333
+ break;
1334
+
1335
+ case BLEND_ADD:
1336
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1337
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
1338
+ break;
1339
+
1340
+ case BLEND_SUBTRACT:
1341
+ glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD);
1342
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
1343
+ break;
1344
+
1345
+ case BLEND_LIGHTEST:
1346
+ glBlendEquationSeparate(GL_MAX, GL_FUNC_ADD);
1347
+ glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
1348
+ break;
1349
+
1350
+ case BLEND_DARKEST:
1351
+ glBlendEquationSeparate(GL_MIN, GL_FUNC_ADD);
1352
+ glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
1353
+ break;
1354
+
1355
+ case BLEND_EXCLUSION:
1356
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1357
+ glBlendFuncSeparate(
1358
+ GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);
1359
+ break;
1360
+
1361
+ case BLEND_MULTIPLY:
1362
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1363
+ glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ONE, GL_ONE);
1364
+ break;
1365
+
1366
+ case BLEND_SCREEN:
1367
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1368
+ glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR, GL_ONE, GL_ONE, GL_ONE);
1369
+ break;
1370
+
1371
+ case BLEND_REPLACE:
1372
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
1373
+ glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
1374
+ break;
1375
+
1376
+ default:
1377
+ argument_error(__FILE__, __LINE__, "unknown blend mode");
1378
+ break;
1379
+ }
1380
+ OpenGL_check_error(__FILE__, __LINE__);
1381
+ }
1382
+
1383
+ BlendMode
1384
+ Painter::blend_mode () const
1385
+ {
1386
+ return self->state.blend_mode;
1387
+ }
1388
+
1296
1389
  void
1297
1390
  Painter::set_clip (coord x, coord y, coord width, coord height)
1298
1391
  {
@@ -1318,9 +1411,19 @@ namespace Rays
1318
1411
  return self->state.clip;
1319
1412
  }
1320
1413
 
1414
+ static bool
1415
+ has_same_font (const Font& font, const char* name, coord size)
1416
+ {
1417
+ return
1418
+ font.size() == size &&
1419
+ font.name() == (name ? name : default_font().name().c_str());
1420
+ }
1421
+
1321
1422
  void
1322
1423
  Painter::set_font (const char* name, coord size)
1323
1424
  {
1425
+ if (has_same_font(self->state.font, name, size)) return;
1426
+
1324
1427
  set_font(Font(name, size));
1325
1428
  }
1326
1429
 
@@ -54,8 +54,11 @@ namespace Rays
54
54
  #else
55
55
  GL_DEPTH_COMPONENT24,
56
56
  #endif
57
- width,
58
- height);
57
+ width_,
58
+ height_);
59
+ OpenGL_check_error(__FILE__, __LINE__);
60
+
61
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
59
62
  OpenGL_check_error(__FILE__, __LINE__);
60
63
 
61
64
  width = width_;
data/test/test_image.rb CHANGED
@@ -6,11 +6,12 @@ require_relative 'helper'
6
6
 
7
7
  class TestImage < Test::Unit::TestCase
8
8
 
9
- W = 10
10
- H = 10
9
+ def image(*args)
10
+ Rays::Image.new(*args)
11
+ end
11
12
 
12
- def image(w = W, h = H, *args)
13
- Rays::Image.new w, h, *args
13
+ def load(path)
14
+ Rays::Image.load path
14
15
  end
15
16
 
16
17
  def color(r = 0, g = 0, b = 0, a = 0)
@@ -22,12 +23,12 @@ class TestImage < Test::Unit::TestCase
22
23
  end
23
24
 
24
25
  def test_initialize()
25
- assert_equal W, image.width
26
- assert_equal H, image.height
26
+ assert_equal 10, image(10, 20).width
27
+ assert_equal 10, image(20, 10).height
27
28
  end
28
29
 
29
30
  def test_dup()
30
- o = image
31
+ o = image 10, 10
31
32
  assert_equal color(0, 0, 0, 0), o[0, 0]
32
33
  o[0, 0] = color(1, 0, 0, 0)
33
34
  assert_equal color(1, 0, 0, 0), o[0, 0]
@@ -39,12 +40,12 @@ class TestImage < Test::Unit::TestCase
39
40
  end
40
41
 
41
42
  def test_bitmap()
42
- assert_equal W, image.bitmap.width
43
- assert_equal H, image.bitmap.height
43
+ assert_equal 10, image(10, 20).bitmap.width
44
+ assert_equal 10, image(20, 10).bitmap.height
44
45
  end
45
46
 
46
47
  def test_painter()
47
- pa = image.painter
48
+ pa = image(10, 10).painter
48
49
  assert_equal color(0, 0, 0, 0), pa.background
49
50
  assert_equal color(1, 1, 1, 1), pa.fill
50
51
  assert_equal color(1, 1, 1, 0), pa.stroke
@@ -73,4 +74,38 @@ class TestImage < Test::Unit::TestCase
73
74
  assert drawn {|p| p.text "a"}
74
75
  end
75
76
 
77
+ def test_save_load()
78
+ def get_image_type(filename)
79
+ `file #{filename}`.match(/#{filename}: ([^,]+),/)[1]
80
+ end
81
+
82
+ img = image(10, 10).paint {fill 1, 0, 0; ellipse 0, 0, 10}
83
+ pixels = img.bitmap.to_a
84
+ paths = %w[png jpg jpeg gif bmp tif tiff].map {|ext| "#{__dir__}/testimage.#{ext}"}
85
+
86
+ png, jpg, jpeg, gif, bmp, tif, tiff = paths
87
+
88
+ paths.each {|path| img.save path}
89
+
90
+ assert_equal 'PNG image data', get_image_type(png)
91
+ assert_equal 'JPEG image data', get_image_type(jpg)
92
+ assert_equal 'JPEG image data', get_image_type(jpeg)
93
+ assert_equal 'GIF image data', get_image_type(gif)
94
+ assert_equal 'PC bitmap', get_image_type(bmp)
95
+ assert_equal 'TIFF image data', get_image_type(tif)
96
+ assert_equal 'TIFF image data', get_image_type(tiff)
97
+
98
+ assert_equal pixels, load(png) .then {|o| o.bitmap.to_a}
99
+ assert_equal [10, 10], load(jpg) .then {|o| [o.width, o.height]}
100
+ assert_equal [10, 10], load(jpeg).then {|o| [o.width, o.height]}
101
+ assert_equal pixels, load(gif) .then {|o| o.bitmap.to_a}
102
+ assert_equal [10, 10], load(bmp) .then {|o| [o.width, o.height]}
103
+ assert_equal pixels, load(tif) .then {|o| o.bitmap.to_a}
104
+ assert_equal pixels, load(tiff).then {|o| o.bitmap.to_a}
105
+
106
+ paths.each {|path| File.delete path}
107
+
108
+ assert_raise(ArgumentError) {img.save 'testimage.unknown'}
109
+ end
110
+
76
111
  end# TestImage
data/test/test_painter.rb CHANGED
@@ -18,6 +18,28 @@ class TestPainter < Test::Unit::TestCase
18
18
  Rays::Color.new(*args)
19
19
  end
20
20
 
21
+ def image(w = 16, h = 16, bg: 0, &block)
22
+ Rays::Image.new(w, h)
23
+ .paint {background bg}
24
+ .tap {|img| img.paint(&block) if block}
25
+ end
26
+
27
+ def assert_gray(expected, actual)
28
+ assert_in_epsilon expected, actual, 0.02
29
+ end
30
+
31
+ def assert_rgb(expected, actual)
32
+ (0..2).each do |i|
33
+ assert_gray expected[i], actual[i]
34
+ end
35
+ end
36
+
37
+ def assert_rgba(expected, actual)
38
+ (0..3).each do |i|
39
+ assert_gray expected[i], actual[i]
40
+ end
41
+ end
42
+
21
43
  def setup()
22
44
  Rays::Color.set_palette_color :rgb001, color(0, 0, 1)
23
45
  end
@@ -124,6 +146,19 @@ class TestPainter < Test::Unit::TestCase
124
146
  assert_equal 4, pa.miter_limit
125
147
  end
126
148
 
149
+ def test_blend_mode_accessor()
150
+ pa = painter
151
+ assert_equal :normal, pa.blend_mode
152
+ pa.blend_mode = :add
153
+ assert_equal :add, pa.blend_mode
154
+ pa.blend_mode :subtract
155
+ assert_equal :subtract, pa.blend_mode
156
+ pa.push blend_mode: :multiply do |_|
157
+ assert_equal :multiply, pa.blend_mode
158
+ end
159
+ assert_equal :subtract, pa.blend_mode
160
+ end
161
+
127
162
  def test_clip_accessor()
128
163
  pa = painter
129
164
  pa.clip = [1, 2, 3, 4]
@@ -182,6 +217,122 @@ class TestPainter < Test::Unit::TestCase
182
217
  assert_equal color(0, 1, 0), pa.fill
183
218
  end
184
219
 
220
+ def test_blend_mode_normal()
221
+ i = image do
222
+ blend_mode :normal
223
+ fill 0.1, 0.2, 0.3
224
+ rect 0, 0, 2
225
+ fill 0.4, 0.5, 0.6
226
+ rect 1, 0, 2
227
+ end
228
+ assert_rgb [0.1, 0.2, 0.3], i[0, 0]
229
+ assert_rgb [0.4, 0.5, 0.6], i[1, 0]
230
+ assert_rgb [0.4, 0.5, 0.6], i[2, 0]
231
+ end
232
+
233
+ def test_blend_mode_add()
234
+ i = image do
235
+ fill 0.1, 0.2, 0.3
236
+ rect 0, 0, 2
237
+ blend_mode :add
238
+ fill 0.4, 0.5, 0.6
239
+ rect 1, 0, 2
240
+ end
241
+ assert_rgb [0.1, 0.2, 0.3], i[0, 0]
242
+ assert_rgb [0.5, 0.7, 0.9], i[1, 0]
243
+ assert_rgb [0.4, 0.5, 0.6], i[2, 0]
244
+ end
245
+
246
+ def test_blend_mode_subtract()
247
+ i = image bg: 1 do
248
+ fill 0.4, 0.5, 0.6
249
+ rect 0, 0, 2
250
+ blend_mode :subtract
251
+ fill 0.1, 0.2, 0.3
252
+ rect 1, 0, 2
253
+ end
254
+ assert_rgb [0.4, 0.5, 0.6], i[0, 0]
255
+ assert_rgb [0.3, 0.3, 0.3], i[1, 0]
256
+ assert_rgb [0.9, 0.8, 0.7], i[2, 0]
257
+ end
258
+
259
+ def test_blend_mode_lightest()
260
+ i = image do
261
+ fill 0.4, 0.5, 0.6
262
+ rect 0, 0, 2
263
+ blend_mode :lightest
264
+ fill 0.1, 0.2, 0.3
265
+ rect 1, 0, 2
266
+ end
267
+ assert_rgb [0.4, 0.5, 0.6], i[0, 0]
268
+ assert_rgb [0.4, 0.5, 0.6], i[1, 0]
269
+ assert_rgb [0.1, 0.2, 0.3], i[2, 0]
270
+ end
271
+
272
+ def test_blend_mode_darkest()
273
+ i = image bg: 1 do
274
+ fill 0.1, 0.2, 0.3
275
+ rect 0, 0, 2
276
+ blend_mode :darkest
277
+ fill 0.4, 0.5, 0.6
278
+ rect 1, 0, 2
279
+ end
280
+ assert_rgb [0.1, 0.2, 0.3], i[0, 0]
281
+ assert_rgb [0.1, 0.2, 0.3], i[1, 0]
282
+ assert_rgb [0.4, 0.5, 0.6], i[2, 0]
283
+ end
284
+
285
+ def test_blend_mode_exclusion()
286
+ # no tests
287
+ end
288
+
289
+ def test_blend_mode_multiply()
290
+ i = image bg: 1 do
291
+ fill 0.2, 0.4, 0.6
292
+ rect 0, 0, 2
293
+ blend_mode :multiply
294
+ fill 0.5
295
+ rect 1, 0, 2
296
+ end
297
+ assert_rgb [0.2, 0.4, 0.6], i[0, 0]
298
+ assert_rgb [0.1, 0.2, 0.3], i[1, 0]
299
+ assert_rgb [0.5, 0.5, 0.5], i[2, 0]
300
+ end
301
+
302
+ def test_blend_mode_screen()
303
+ i = image bg: 0.8 do
304
+ fill 0.2, 0.4, 0.6
305
+ rect 0, 0, 2
306
+ blend_mode :screen
307
+ fill 0.5
308
+ rect 1, 0, 2
309
+ end
310
+ assert_rgb [0.2, 0.4, 0.6], i[0, 0]
311
+ assert_rgb [0.6, 0.7, 0.8], i[1, 0]
312
+ assert_rgb [0.9, 0.9, 0.9], i[2, 0]
313
+ end
314
+
315
+ def test_blend_mode_replace()
316
+ i = image bg: 1 do
317
+ fill 0.1, 0.2, 0.3, 0.4
318
+ rect 0, 0, 2
319
+ blend_mode :replace
320
+ fill 0.5, 0.6, 0.7, 0.8
321
+ rect 1, 0, 2
322
+ end
323
+ assert_rgba [0.5, 0.6, 0.7, 0.8], i[1, 0]
324
+ assert_rgba [0.5, 0.6, 0.7, 0.8], i[2, 0]
325
+ end
326
+
327
+ def test_blend_mode_invalid()
328
+ assert_raise(ArgumentError) do
329
+ image {blend_mode :invalid}
330
+ end
331
+ assert_raise(ArgumentError) do
332
+ image {blend_mode nil}
333
+ end
334
+ end
335
+
185
336
  def test_push()
186
337
  pa = painter
187
338
  pa.fill = [1, 0, 0]
@@ -224,7 +375,23 @@ class TestPainter < Test::Unit::TestCase
224
375
  end
225
376
 
226
377
  def test_shader()
227
- img = Rays::Image.new(10, 10).paint {
378
+ image.paint do |pa|
379
+ assert_nil pa.shader
380
+
381
+ pa.shader = Rays::Shader.new "void main() {gl_FragColor = vec4(0.0);}"
382
+ assert_instance_of Rays::Shader, pa.shader
383
+
384
+ pa.shader = nil
385
+ assert_nil pa.shader
386
+
387
+ pa.shader = "void main() {gl_FragColor = vec4(0.0);}"
388
+ assert_instance_of Rays::Shader, pa.shader
389
+
390
+ pa.no_shader
391
+ assert_nil pa.shader
392
+ end
393
+
394
+ img = image.paint {
228
395
  shader "void main() {gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);}"
229
396
  fill 1, 0, 0
230
397
  rect bounds
@@ -99,4 +99,4 @@ class TestPainterShape < Test::Unit::TestCase
99
99
  assert_equal 0, img[99, 99].a
100
100
  end
101
101
 
102
- end# TestPainter
102
+ end# TestPainterShape
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rays
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.25
4
+ version: 0.1.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - xordog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-04 00:00:00.000000000 Z
11
+ date: 2022-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xot
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.25
19
+ version: 0.1.28
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.25
26
+ version: 0.1.28
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rucy
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.1.25
33
+ version: 0.1.28
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.1.25
40
+ version: 0.1.28
41
41
  description: This library helps you to develop graphics application with OpenGL.
42
42
  email: xordog@gmail.com
43
43
  executables: []
@@ -252,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
252
252
  - !ruby/object:Gem::Version
253
253
  version: '0'
254
254
  requirements: []
255
- rubygems_version: 3.2.32
255
+ rubygems_version: 3.2.33
256
256
  signing_key:
257
257
  specification_version: 4
258
258
  summary: A Drawing Engine using OpenGL.