rays 0.1.25 → 0.1.28
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.
- checksums.yaml +4 -4
- data/.doc/ext/rays/painter.cpp +67 -9
- data/.doc/ext/rays/rays.cpp +47 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/ext/rays/painter.cpp +68 -8
- data/ext/rays/rays.cpp +47 -0
- data/include/rays/defs.h +26 -0
- data/include/rays/painter.h +6 -1
- data/include/rays/ruby/rays.h +2 -0
- data/lib/rays/painter.rb +13 -1
- data/rays.gemspec +2 -2
- data/src/frame_buffer.cpp +2 -3
- data/src/ios/bitmap.mm +18 -1
- data/src/osx/bitmap.mm +18 -1
- data/src/painter.cpp +109 -6
- data/src/render_buffer.cpp +5 -2
- data/test/test_image.rb +45 -10
- data/test/test_painter.rb +168 -1
- data/test/test_painter_shape.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38052c848aef75871de813ae9cc59a956672b1c6b8db25b55916f041ae0df976
|
4
|
+
data.tar.gz: d1f462fce0b73364a015fa1826eef17c3d1a4ac0b4378590f20438d87ce8e1cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e01828d4ac2ad4749a9d050d3890669be7e35dd057cc92b0dae23f645954b44bf7f3775d193ef36d9590d10879175a7937b28ceddf0bf9fd29a84723f0cfdbe
|
7
|
+
data.tar.gz: da8b670d9e704d4cc48070d5d252ec504e433f00222160a5c42ccf7a036eabc1a31580b6318da59672bc8576b0dddf84fce635ce9194f4a462eebfc8d4e03451
|
data/.doc/ext/rays/painter.cpp
CHANGED
@@ -26,15 +26,51 @@ VALUE alloc(VALUE klass)
|
|
26
26
|
}
|
27
27
|
|
28
28
|
static
|
29
|
-
VALUE canvas(VALUE self
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
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
|
-
|
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),
|
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);
|
data/.doc/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
|
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
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
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
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
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
|
-
|
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
|
|
data/include/rays/painter.h
CHANGED
@@ -174,7 +174,8 @@ namespace Rays
|
|
174
174
|
//
|
175
175
|
// states
|
176
176
|
//
|
177
|
-
void set_background (
|
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);
|
data/include/rays/ruby/rays.h
CHANGED
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.
|
32
|
-
s.add_runtime_dependency 'rucy', '~> 0.1.
|
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
|
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,
|
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,
|
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.
|
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(
|
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
|
-
|
643
|
-
|
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 = -
|
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
|
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
|
|
data/src/render_buffer.cpp
CHANGED
@@ -54,8 +54,11 @@ namespace Rays
|
|
54
54
|
#else
|
55
55
|
GL_DEPTH_COMPONENT24,
|
56
56
|
#endif
|
57
|
-
|
58
|
-
|
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
|
-
|
10
|
-
|
9
|
+
def image(*args)
|
10
|
+
Rays::Image.new(*args)
|
11
|
+
end
|
11
12
|
|
12
|
-
def
|
13
|
-
Rays::Image.
|
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
|
26
|
-
assert_equal
|
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
|
43
|
-
assert_equal
|
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
|
-
|
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
|
data/test/test_painter_shape.rb
CHANGED
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.
|
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:
|
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.
|
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.
|
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.
|
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.
|
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.
|
255
|
+
rubygems_version: 3.2.33
|
256
256
|
signing_key:
|
257
257
|
specification_version: 4
|
258
258
|
summary: A Drawing Engine using OpenGL.
|