rays 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/.doc/ext/rays/bitmap.cpp +28 -8
- data/.doc/ext/rays/bounds.cpp +1 -1
- data/.doc/ext/rays/camera.cpp +5 -5
- data/.doc/ext/rays/color.cpp +1 -1
- data/.doc/ext/rays/color_space.cpp +10 -6
- data/.doc/ext/rays/font.cpp +116 -18
- data/.doc/ext/rays/image.cpp +27 -4
- data/.doc/ext/rays/matrix.cpp +1 -1
- data/.doc/ext/rays/painter.cpp +5 -5
- data/.doc/ext/rays/point.cpp +1 -1
- data/.doc/ext/rays/polygon.cpp +4 -4
- data/.doc/ext/rays/polyline.cpp +2 -2
- data/.doc/ext/rays/shader.cpp +2 -2
- data/.github/workflows/release-gem.yml +2 -49
- data/.github/workflows/tag.yml +5 -28
- data/.github/workflows/test.yml +1 -37
- data/ChangeLog.md +21 -0
- data/Gemfile.lock +13 -8
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/ext/rays/bitmap.cpp +28 -8
- data/ext/rays/bounds.cpp +1 -1
- data/ext/rays/camera.cpp +5 -5
- data/ext/rays/color.cpp +1 -1
- data/ext/rays/color_space.cpp +10 -6
- data/ext/rays/defs.h +3 -3
- data/ext/rays/extconf.rb +6 -5
- data/ext/rays/font.cpp +120 -18
- data/ext/rays/image.cpp +27 -4
- data/ext/rays/matrix.cpp +1 -1
- data/ext/rays/painter.cpp +5 -5
- data/ext/rays/point.cpp +1 -1
- data/ext/rays/polygon.cpp +4 -4
- data/ext/rays/polyline.cpp +2 -2
- data/ext/rays/shader.cpp +2 -2
- data/include/rays/bitmap.h +2 -0
- data/include/rays/font.h +46 -4
- data/include/rays/image.h +9 -5
- data/include/rays/painter.h +3 -1
- data/include/rays/ruby/color_space.h +2 -0
- data/include/rays/shader.h +3 -0
- data/lib/rays/font.rb +4 -1
- data/lib/rays/image.rb +2 -0
- data/lib/rays/painter.rb +5 -5
- data/rays.gemspec +3 -3
- data/src/bitmap.cpp +107 -0
- data/src/color.cpp +17 -0
- data/src/font.cpp +121 -25
- data/src/font.h +7 -5
- data/src/image.cpp +102 -100
- data/src/ios/font.mm +77 -24
- data/src/opengl/color_space.cpp +4 -1
- data/src/opengl/painter.cpp +86 -18
- data/src/opengl/shader.cpp +15 -13
- data/src/opengl/texture.cpp +2 -2
- data/src/opengl/win32/opengl.cpp +17 -12
- data/src/osx/font.mm +77 -24
- data/src/painter.cpp +12 -12
- data/src/painter.h +5 -1
- data/src/polygon.cpp +21 -21
- data/src/polyline.cpp +4 -4
- data/src/sdl/bitmap.cpp +16 -10
- data/src/sdl/font.cpp +56 -50
- data/src/win32/bitmap.cpp +22 -13
- data/src/win32/font.cpp +43 -44
- data/src/win32/gdi.cpp +43 -46
- data/src/win32/gdi.h +6 -1
- data/src/win32/rays.cpp +18 -1
- data/test/test_bitmap.rb +28 -10
- data/test/test_font.rb +58 -0
- data/test/test_image.rb +29 -6
- data/test/test_painter.rb +39 -0
- metadata +8 -8
- data/.github/workflows/utils.rb +0 -127
data/ext/rays/matrix.cpp
CHANGED
data/ext/rays/painter.cpp
CHANGED
|
@@ -17,7 +17,7 @@ RUCY_DEFINE_VALUE_FROM_TO(RAYS_EXPORT, Rays::Painter)
|
|
|
17
17
|
|
|
18
18
|
#define THIS to<Rays::Painter*>(self)
|
|
19
19
|
|
|
20
|
-
#define CHECK
|
|
20
|
+
#define CHECK RUCY_CHECK_OBJ(Rays::Painter, self)
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
static
|
|
@@ -172,7 +172,7 @@ RUCY_DEFN(point)
|
|
|
172
172
|
std::vector<Rays::Point> points;
|
|
173
173
|
get_points(&points, argc, argv);
|
|
174
174
|
|
|
175
|
-
THIS->points(
|
|
175
|
+
THIS->points(points.data(), points.size());
|
|
176
176
|
return self;
|
|
177
177
|
}
|
|
178
178
|
RUCY_END
|
|
@@ -185,7 +185,7 @@ RUCY_DEF2(line, args, loop)
|
|
|
185
185
|
std::vector<Rays::Point> points;
|
|
186
186
|
get_points(&points, args.size(), args.as_array());
|
|
187
187
|
|
|
188
|
-
THIS->line(
|
|
188
|
+
THIS->line(points.data(), points.size(), loop);
|
|
189
189
|
return self;
|
|
190
190
|
}
|
|
191
191
|
RUCY_END
|
|
@@ -247,7 +247,7 @@ RUCY_DEF2(curve, args, loop)
|
|
|
247
247
|
std::vector<Rays::Point> points;
|
|
248
248
|
get_points(&points, args.size(), args.as_array());
|
|
249
249
|
|
|
250
|
-
THIS->curve(
|
|
250
|
+
THIS->curve(points.data(), points.size(), loop);
|
|
251
251
|
return self;
|
|
252
252
|
}
|
|
253
253
|
RUCY_END
|
|
@@ -263,7 +263,7 @@ RUCY_DEF2(bezier, args, loop)
|
|
|
263
263
|
std::vector<Rays::Point> points;
|
|
264
264
|
get_points(&points, args.size(), args.as_array());
|
|
265
265
|
|
|
266
|
-
THIS->bezier(
|
|
266
|
+
THIS->bezier(points.data(), points.size(), loop);
|
|
267
267
|
return self;
|
|
268
268
|
}
|
|
269
269
|
RUCY_END
|
data/ext/rays/point.cpp
CHANGED
data/ext/rays/polygon.cpp
CHANGED
|
@@ -12,7 +12,7 @@ RUCY_DEFINE_VALUE_OR_ARRAY_FROM_TO(RAYS_EXPORT, Rays::Polygon)
|
|
|
12
12
|
|
|
13
13
|
#define THIS to<Rays::Polygon*>(self)
|
|
14
14
|
|
|
15
|
-
#define CHECK
|
|
15
|
+
#define CHECK RUCY_CHECK_OBJ(Rays::Polygon, self)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
static
|
|
@@ -165,7 +165,7 @@ RUCY_DEF1(op_add, obj)
|
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
return value(Rays::Polygon(
|
|
168
|
+
return value(Rays::Polygon(polylines.data(), polylines.size()));
|
|
169
169
|
}
|
|
170
170
|
RUCY_END
|
|
171
171
|
|
|
@@ -428,14 +428,14 @@ namespace Rucy
|
|
|
428
428
|
polylines.reserve(argc);
|
|
429
429
|
for (int i = 0; i < argc; ++i)
|
|
430
430
|
polylines.emplace_back(to<Rays::Polyline&>(argv[i]));
|
|
431
|
-
return Rays::Polygon(
|
|
431
|
+
return Rays::Polygon(polylines.data(), polylines.size());
|
|
432
432
|
}
|
|
433
433
|
}
|
|
434
434
|
else if (argv->is_num() || argv->is_array())
|
|
435
435
|
{
|
|
436
436
|
std::vector<Rays::Point> points;
|
|
437
437
|
get_points(&points, argc, argv);
|
|
438
|
-
return Rays::Polygon(
|
|
438
|
+
return Rays::Polygon(points.data(), points.size());
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
441
|
|
data/ext/rays/polyline.cpp
CHANGED
|
@@ -13,7 +13,7 @@ RUCY_DEFINE_VALUE_OR_ARRAY_FROM_TO(RAYS_EXPORT, Rays::Polyline)
|
|
|
13
13
|
|
|
14
14
|
#define THIS to<Rays::Polyline*>(self)
|
|
15
15
|
|
|
16
|
-
#define CHECK
|
|
16
|
+
#define CHECK RUCY_CHECK_OBJ(Rays::Polyline, self)
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
static
|
|
@@ -243,7 +243,7 @@ namespace Rucy
|
|
|
243
243
|
{
|
|
244
244
|
std::vector<Rays::Point> points;
|
|
245
245
|
get_points(&points, argc, argv);
|
|
246
|
-
return Rays::Polyline(
|
|
246
|
+
return Rays::Polyline(points.data(), points.size());
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
|
data/ext/rays/shader.cpp
CHANGED
|
@@ -10,7 +10,7 @@ RUCY_DEFINE_VALUE_OR_ARRAY_FROM_TO(RAYS_EXPORT, Rays::Shader)
|
|
|
10
10
|
|
|
11
11
|
#define THIS to<Rays::Shader*>(self)
|
|
12
12
|
|
|
13
|
-
#define CHECK
|
|
13
|
+
#define CHECK RUCY_CHECK_OBJ(Rays::Shader, self)
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
static
|
|
@@ -93,7 +93,7 @@ RUCY_DEF4(initialize,
|
|
|
93
93
|
fragment_shader_source, vertex_shader_source,
|
|
94
94
|
builtin_variable_names, ignore_no_uniform_location_error)
|
|
95
95
|
{
|
|
96
|
-
|
|
96
|
+
RUCY_CHECK_PTR(Rays::Shader, self);
|
|
97
97
|
|
|
98
98
|
if (fragment_shader_source.is_nil())
|
|
99
99
|
argument_error(__FILE__, __LINE__);
|
data/include/rays/bitmap.h
CHANGED
data/include/rays/font.h
CHANGED
|
@@ -19,22 +19,64 @@ namespace Rays
|
|
|
19
19
|
|
|
20
20
|
public:
|
|
21
21
|
|
|
22
|
-
enum
|
|
22
|
+
enum
|
|
23
|
+
{
|
|
24
|
+
|
|
25
|
+
WEIGHT_MIN = 0,
|
|
26
|
+
|
|
27
|
+
WEIGHT_THIN = 100,
|
|
28
|
+
|
|
29
|
+
WEIGHT_EXTRALIGHT = 200,
|
|
30
|
+
|
|
31
|
+
WEIGHT_LIGHT = 300,
|
|
32
|
+
|
|
33
|
+
WEIGHT_NORMAL = 400,
|
|
34
|
+
|
|
35
|
+
WEIGHT_MEDIUM = 500,
|
|
36
|
+
|
|
37
|
+
WEIGHT_SEMIBOLD = 600,
|
|
38
|
+
|
|
39
|
+
WEIGHT_BOLD = 700,
|
|
40
|
+
|
|
41
|
+
WEIGHT_EXTRABOLD = 800,
|
|
42
|
+
|
|
43
|
+
WEIGHT_BLACK = 900,
|
|
44
|
+
|
|
45
|
+
WEIGHT_MAX = 1000,
|
|
46
|
+
|
|
47
|
+
DEFAULT_SIZE = 12,
|
|
48
|
+
|
|
49
|
+
DEFAULT_WEIGHT = WEIGHT_NORMAL,
|
|
50
|
+
|
|
51
|
+
};
|
|
23
52
|
|
|
24
53
|
Font ();
|
|
25
54
|
|
|
26
|
-
Font (
|
|
55
|
+
Font (
|
|
56
|
+
const char* name,
|
|
57
|
+
coord size = DEFAULT_SIZE,
|
|
58
|
+
int weight = DEFAULT_WEIGHT,
|
|
59
|
+
bool italic = false,
|
|
60
|
+
bool smooth = true);
|
|
27
61
|
|
|
28
62
|
~Font ();
|
|
29
63
|
|
|
30
64
|
Font dup () const;
|
|
31
65
|
|
|
32
|
-
String name () const;
|
|
66
|
+
String name (bool resolved = false) const;
|
|
33
67
|
|
|
34
68
|
void set_size (coord size);
|
|
35
69
|
|
|
36
70
|
coord size () const;
|
|
37
71
|
|
|
72
|
+
void set_weight (int weight);
|
|
73
|
+
|
|
74
|
+
int weight () const;
|
|
75
|
+
|
|
76
|
+
void set_italic (bool italic);
|
|
77
|
+
|
|
78
|
+
bool italic () const;
|
|
79
|
+
|
|
38
80
|
void set_smooth (bool smooth);
|
|
39
81
|
|
|
40
82
|
bool smooth () const;
|
|
@@ -63,7 +105,7 @@ namespace Rays
|
|
|
63
105
|
|
|
64
106
|
Font load_font (const char* path, coord size = Font::DEFAULT_SIZE);
|
|
65
107
|
|
|
66
|
-
|
|
108
|
+
Font get_default_font ();
|
|
67
109
|
|
|
68
110
|
|
|
69
111
|
}// Rays
|
data/include/rays/image.h
CHANGED
|
@@ -65,15 +65,19 @@ namespace Rays
|
|
|
65
65
|
|
|
66
66
|
friend bool operator != (const This& lhs, const This& rhs);
|
|
67
67
|
|
|
68
|
-
struct
|
|
68
|
+
struct Loader
|
|
69
69
|
{
|
|
70
|
-
virtual ~
|
|
71
|
-
virtual
|
|
70
|
+
virtual ~Loader ();
|
|
71
|
+
virtual bool load (Bitmap* bitmap) = 0;
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
Image (const Image& pixels, Loader* loader);
|
|
75
|
+
|
|
76
|
+
const Loader* loader () const;
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
struct Data;
|
|
79
|
+
|
|
80
|
+
Xot::PSharedImpl<Data> self;
|
|
77
81
|
|
|
78
82
|
};// Image
|
|
79
83
|
|
data/include/rays/painter.h
CHANGED
|
@@ -267,7 +267,9 @@ namespace Rays
|
|
|
267
267
|
|
|
268
268
|
const Bounds& clip () const;
|
|
269
269
|
|
|
270
|
-
void set_font (
|
|
270
|
+
void set_font (
|
|
271
|
+
const char* name, coord size = 0,
|
|
272
|
+
int weight = -1, bool italic = false, bool smooth = true);
|
|
271
273
|
|
|
272
274
|
void set_font (const Font& font);
|
|
273
275
|
|
data/include/rays/shader.h
CHANGED
|
@@ -20,6 +20,9 @@ namespace Rays
|
|
|
20
20
|
|
|
21
21
|
class Shader
|
|
22
22
|
{
|
|
23
|
+
// A fragment shader sees premultiplied alpha and must produce it too:
|
|
24
|
+
// samples from the texture uniform are premultiplied, and gl_FragColor
|
|
25
|
+
// is blended as premultiplied. The vertex color is straight.
|
|
23
26
|
|
|
24
27
|
typedef Shader This;
|
|
25
28
|
|
data/lib/rays/font.rb
CHANGED
|
@@ -11,13 +11,16 @@ module Rays
|
|
|
11
11
|
alias w width
|
|
12
12
|
alias h height
|
|
13
13
|
|
|
14
|
+
alias italic? italic
|
|
15
|
+
alias smooth? smooth
|
|
16
|
+
|
|
14
17
|
def <=>(o)
|
|
15
18
|
ret = name <=> o.name; return ret if ret != 0
|
|
16
19
|
size <=> o.size
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def inspect()
|
|
20
|
-
"#<Rays::Font name='#{name}', size=#{size}>"
|
|
23
|
+
"#<Rays::Font name='#{name}', size=#{size}, weight=#{weight}#{italic? ? ', italic' : ''}>"
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
end# Font
|
data/lib/rays/image.rb
CHANGED
data/lib/rays/painter.rb
CHANGED
|
@@ -135,11 +135,11 @@ module Rays
|
|
|
135
135
|
|
|
136
136
|
private
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
def each_type(types, reverse: false, &block)
|
|
139
|
+
types = [:state, :matrix] if types.empty? || types.include?(:all)
|
|
140
|
+
types = types.reverse if reverse
|
|
141
|
+
types.each(&block)
|
|
142
|
+
end
|
|
143
143
|
|
|
144
144
|
end# Painter
|
|
145
145
|
|
data/rays.gemspec
CHANGED
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
|
11
11
|
|
|
12
12
|
ext = Rays::Extension
|
|
13
13
|
name = ext.name true
|
|
14
|
-
rdocs = glob.call
|
|
14
|
+
rdocs = glob.call(*%w[README .doc/ext/**/*.cpp])
|
|
15
15
|
|
|
16
16
|
s.name = name
|
|
17
17
|
s.version = ext.version
|
|
@@ -25,8 +25,8 @@ Gem::Specification.new do |s|
|
|
|
25
25
|
s.platform = Gem::Platform::RUBY
|
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
|
27
27
|
|
|
28
|
-
s.add_dependency 'xot', '~> 0.
|
|
29
|
-
s.add_dependency 'rucy', '~> 0.
|
|
28
|
+
s.add_dependency 'xot', '~> 0.5.0'
|
|
29
|
+
s.add_dependency 'rucy', '~> 0.5.0'
|
|
30
30
|
|
|
31
31
|
s.files = `git ls-files`.split $/
|
|
32
32
|
s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
|
data/src/bitmap.cpp
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#include "bitmap.h"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#include <algorithm>
|
|
5
|
+
#include "rays/exception.h"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
namespace Rays
|
|
9
|
+
{
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
template <typename Fun>
|
|
13
|
+
static void
|
|
14
|
+
each_alpha_pixel (Bitmap* bitmap, Fun fun)
|
|
15
|
+
{
|
|
16
|
+
if (!bitmap)
|
|
17
|
+
argument_error(__FILE__, __LINE__);
|
|
18
|
+
if (!*bitmap)
|
|
19
|
+
argument_error(__FILE__, __LINE__);
|
|
20
|
+
|
|
21
|
+
const ColorSpace& cs = bitmap->color_space();
|
|
22
|
+
if (!cs.has_alpha() || cs.is_alpha())
|
|
23
|
+
return;
|
|
24
|
+
|
|
25
|
+
int width = bitmap->width();
|
|
26
|
+
int height = bitmap->height();
|
|
27
|
+
int Bpp = cs.Bpp();
|
|
28
|
+
int apos = cs.alpha_pos();
|
|
29
|
+
|
|
30
|
+
for (int y = 0; y < height; ++y)
|
|
31
|
+
{
|
|
32
|
+
uchar* p = bitmap->at<uchar>(0, y);
|
|
33
|
+
for (int x = 0; x < width; ++x, p += Bpp)
|
|
34
|
+
fun(p, apos);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static void
|
|
39
|
+
premultiply (Bitmap* bitmap)
|
|
40
|
+
{
|
|
41
|
+
if (bitmap && bitmap->color_space().is_float())
|
|
42
|
+
{
|
|
43
|
+
each_alpha_pixel(bitmap, [](uchar* p, int apos)
|
|
44
|
+
{
|
|
45
|
+
float* f = (float*) p;
|
|
46
|
+
float a = f[apos];
|
|
47
|
+
if (a == 1) return;
|
|
48
|
+
for (int i = 0; i < 4; ++i)
|
|
49
|
+
if (i != apos) f[i] *= a;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else
|
|
53
|
+
{
|
|
54
|
+
each_alpha_pixel(bitmap, [](uchar* p, int apos)
|
|
55
|
+
{
|
|
56
|
+
uint a = p[apos];
|
|
57
|
+
if (a == 255) return;
|
|
58
|
+
for (int i = 0; i < 4; ++i)
|
|
59
|
+
if (i != apos) p[i] = (uchar) ((p[i] * a + 127) / 255);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static void
|
|
65
|
+
unpremultiply (Bitmap* bitmap)
|
|
66
|
+
{
|
|
67
|
+
if (bitmap && bitmap->color_space().is_float())
|
|
68
|
+
{
|
|
69
|
+
each_alpha_pixel(bitmap, [](uchar* p, int apos)
|
|
70
|
+
{
|
|
71
|
+
float* f = (float*) p;
|
|
72
|
+
float a = f[apos];
|
|
73
|
+
if (a <= 0 || a == 1) return;
|
|
74
|
+
for (int i = 0; i < 4; ++i)
|
|
75
|
+
if (i != apos) f[i] = std::min(f[i] / a, 1.f);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
else
|
|
79
|
+
{
|
|
80
|
+
each_alpha_pixel(bitmap, [](uchar* p, int apos)
|
|
81
|
+
{
|
|
82
|
+
uint a = p[apos];
|
|
83
|
+
if (a == 0 || a == 255) return;
|
|
84
|
+
for (int i = 0; i < 4; ++i)
|
|
85
|
+
if (i != apos) p[i] = (uchar) std::min<uint>((p[i] * 255 + a / 2) / a, 255);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Bitmap
|
|
91
|
+
Bitmap::dup (bool premult) const
|
|
92
|
+
{
|
|
93
|
+
const ColorSpace& cs = color_space();
|
|
94
|
+
|
|
95
|
+
Bitmap bitmap(width(), height(), ColorSpace(cs.type(), premult), pixels());
|
|
96
|
+
if (premult != cs.is_premult())
|
|
97
|
+
{
|
|
98
|
+
if (premult)
|
|
99
|
+
premultiply(&bitmap);
|
|
100
|
+
else
|
|
101
|
+
unpremultiply(&bitmap);
|
|
102
|
+
}
|
|
103
|
+
return bitmap;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
}// Rays
|
data/src/color.cpp
CHANGED
|
@@ -159,6 +159,13 @@ namespace Rays
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
if (cs.has_alpha() && cs.is_premult() && alpha > 0)
|
|
163
|
+
{
|
|
164
|
+
red = std::min(red / alpha, 1.f);
|
|
165
|
+
green = std::min(green / alpha, 1.f);
|
|
166
|
+
blue = std::min(blue / alpha, 1.f);
|
|
167
|
+
}
|
|
168
|
+
|
|
162
169
|
return *this;
|
|
163
170
|
}
|
|
164
171
|
|
|
@@ -211,6 +218,16 @@ namespace Rays
|
|
|
211
218
|
argument_error(__FILE__, __LINE__);
|
|
212
219
|
|
|
213
220
|
const float* c = array;
|
|
221
|
+
float premult[4];
|
|
222
|
+
if (cs.has_alpha() && cs.is_premult())
|
|
223
|
+
{
|
|
224
|
+
premult[0] = red * alpha;
|
|
225
|
+
premult[1] = green * alpha;
|
|
226
|
+
premult[2] = blue * alpha;
|
|
227
|
+
premult[3] = alpha;
|
|
228
|
+
c = premult;
|
|
229
|
+
}
|
|
230
|
+
|
|
214
231
|
if (cs.is_float())
|
|
215
232
|
{
|
|
216
233
|
float* p = (float*) pixel;
|