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/src/font.cpp
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
#include <string.h>
|
|
5
5
|
#include <assert.h>
|
|
6
|
+
#include <algorithm>
|
|
7
|
+
#include "rays/exception.h"
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
namespace Rays
|
|
@@ -12,53 +14,109 @@ namespace Rays
|
|
|
12
14
|
struct Font::Data
|
|
13
15
|
{
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
String name, path;
|
|
18
|
+
|
|
19
|
+
coord size = 0;
|
|
20
|
+
|
|
21
|
+
int weight = Font::DEFAULT_WEIGHT;
|
|
22
|
+
|
|
23
|
+
bool italic = false;
|
|
16
24
|
|
|
17
25
|
bool smooth = true;
|
|
18
26
|
|
|
27
|
+
RawFont rawfont;
|
|
28
|
+
|
|
19
29
|
mutable RawFont rawfont_for_pixel_density;
|
|
20
30
|
|
|
21
31
|
mutable float for_pixel_density = 1;
|
|
22
32
|
|
|
23
|
-
|
|
33
|
+
RawFont make_rawfont (coord size) const
|
|
24
34
|
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return
|
|
35
|
+
if (!path.empty())
|
|
36
|
+
return RawFont_load(path.c_str(), size);
|
|
37
|
+
else
|
|
38
|
+
return RawFont(name.empty() ? NULL : name.c_str(), size, weight, italic);
|
|
39
|
+
}
|
|
29
40
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
RawFont(rawfont, rawfont.size() * pixel_density);
|
|
34
|
-
for_pixel_density = pixel_density;
|
|
35
|
-
}
|
|
41
|
+
void remake_rawfont ()
|
|
42
|
+
{
|
|
43
|
+
if (!rawfont) return;
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
rawfont = make_rawfont(size);
|
|
46
|
+
for_pixel_density = 1;// drop the cache
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
};// Font::Data
|
|
41
50
|
|
|
42
51
|
|
|
52
|
+
static int
|
|
53
|
+
clamp_weight (int weight)
|
|
54
|
+
{
|
|
55
|
+
return std::clamp(weight, (int) Font::WEIGHT_MIN, (int) Font::WEIGHT_MAX);
|
|
56
|
+
}
|
|
57
|
+
|
|
43
58
|
Font
|
|
44
59
|
load_font (const char* path, coord size)
|
|
45
60
|
{
|
|
46
61
|
Font font;
|
|
62
|
+
font.self->path = path ? path : "";
|
|
63
|
+
font.self->size = size;
|
|
47
64
|
font.self->rawfont = RawFont_load(path, size);
|
|
48
65
|
return font;
|
|
49
66
|
}
|
|
50
67
|
|
|
51
|
-
const
|
|
68
|
+
static constexpr const char* NULL_NAME = "";
|
|
69
|
+
|
|
70
|
+
Font
|
|
52
71
|
get_default_font ()
|
|
53
72
|
{
|
|
54
|
-
static const Font FONT(
|
|
55
|
-
return FONT;
|
|
73
|
+
static const Font FONT(NULL_NAME);
|
|
74
|
+
return FONT.dup();
|
|
56
75
|
}
|
|
57
76
|
|
|
58
77
|
const RawFont&
|
|
59
78
|
Font_get_raw (const Font& font, float pixel_density)
|
|
60
79
|
{
|
|
61
|
-
|
|
80
|
+
if (pixel_density <= 0)
|
|
81
|
+
argument_error(__FILE__, __LINE__);
|
|
82
|
+
|
|
83
|
+
Font::Data* self = font.self.get();
|
|
84
|
+
|
|
85
|
+
if (!self->rawfont || pixel_density == 1)
|
|
86
|
+
return self->rawfont;
|
|
87
|
+
|
|
88
|
+
if (pixel_density != self->for_pixel_density)
|
|
89
|
+
{
|
|
90
|
+
self->rawfont_for_pixel_density = self->make_rawfont(self->size * pixel_density);
|
|
91
|
+
self->for_pixel_density = pixel_density;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return self->rawfont_for_pixel_density;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
bool
|
|
98
|
+
Font_has_same_attributes (
|
|
99
|
+
const Font& font, const char* name, coord size,
|
|
100
|
+
int weight, bool italic, bool smooth)
|
|
101
|
+
{
|
|
102
|
+
if (!font.self->path.empty())
|
|
103
|
+
return false;
|
|
104
|
+
|
|
105
|
+
weight = clamp_weight(weight);
|
|
106
|
+
|
|
107
|
+
if (
|
|
108
|
+
size != font.size() ||
|
|
109
|
+
weight != font.weight() ||
|
|
110
|
+
italic != font.italic() ||
|
|
111
|
+
smooth != font.smooth())
|
|
112
|
+
{
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!name)
|
|
117
|
+
name = NULL_NAME;
|
|
118
|
+
|
|
119
|
+
return name == font.name(false) || name == font.name(true);
|
|
62
120
|
}
|
|
63
121
|
|
|
64
122
|
|
|
@@ -66,10 +124,14 @@ namespace Rays
|
|
|
66
124
|
{
|
|
67
125
|
}
|
|
68
126
|
|
|
69
|
-
Font::Font (const char* name, coord size, bool smooth)
|
|
127
|
+
Font::Font (const char* name, coord size, int weight, bool italic, bool smooth)
|
|
70
128
|
{
|
|
71
|
-
self->
|
|
129
|
+
self->name = name ? name : NULL_NAME;
|
|
130
|
+
self->size = size;
|
|
131
|
+
self->weight = clamp_weight(weight);
|
|
132
|
+
self->italic = italic;
|
|
72
133
|
self->smooth = smooth;
|
|
134
|
+
self->rawfont = self->make_rawfont(size);
|
|
73
135
|
}
|
|
74
136
|
|
|
75
137
|
Font::~Font ()
|
|
@@ -80,27 +142,61 @@ namespace Rays
|
|
|
80
142
|
Font::dup () const
|
|
81
143
|
{
|
|
82
144
|
Font f;
|
|
83
|
-
f.self
|
|
84
|
-
f.self->smooth = self->smooth;
|
|
145
|
+
*f.self = *self;
|
|
85
146
|
return f;
|
|
86
147
|
}
|
|
87
148
|
|
|
88
149
|
String
|
|
89
|
-
Font::name () const
|
|
150
|
+
Font::name (bool resolved) const
|
|
90
151
|
{
|
|
91
|
-
return self->rawfont.name();
|
|
152
|
+
return resolved || self->name.empty() ? self->rawfont.name() : self->name;
|
|
92
153
|
}
|
|
93
154
|
|
|
94
155
|
void
|
|
95
156
|
Font::set_size (coord size)
|
|
96
157
|
{
|
|
97
|
-
|
|
158
|
+
if (size == self->size) return;
|
|
159
|
+
|
|
160
|
+
self->size = size;
|
|
161
|
+
self->remake_rawfont();
|
|
98
162
|
}
|
|
99
163
|
|
|
100
164
|
coord
|
|
101
165
|
Font::size () const
|
|
102
166
|
{
|
|
103
|
-
return self->
|
|
167
|
+
return self->size;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
void
|
|
171
|
+
Font::set_weight (int weight)
|
|
172
|
+
{
|
|
173
|
+
weight = clamp_weight(weight);
|
|
174
|
+
|
|
175
|
+
if (weight == self->weight) return;
|
|
176
|
+
|
|
177
|
+
self->weight = weight;
|
|
178
|
+
self->remake_rawfont();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
int
|
|
182
|
+
Font::weight () const
|
|
183
|
+
{
|
|
184
|
+
return self->weight;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
void
|
|
188
|
+
Font::set_italic (bool italic)
|
|
189
|
+
{
|
|
190
|
+
if (italic == self->italic) return;
|
|
191
|
+
|
|
192
|
+
self->italic = italic;
|
|
193
|
+
self->remake_rawfont();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
bool
|
|
197
|
+
Font::italic () const
|
|
198
|
+
{
|
|
199
|
+
return self->italic;
|
|
104
200
|
}
|
|
105
201
|
|
|
106
202
|
void
|
data/src/font.h
CHANGED
|
@@ -21,9 +21,9 @@ namespace Rays
|
|
|
21
21
|
|
|
22
22
|
RawFont ();
|
|
23
23
|
|
|
24
|
-
RawFont (
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
RawFont (
|
|
25
|
+
const char* name, coord size,
|
|
26
|
+
int weight = Font::DEFAULT_WEIGHT, bool italic = false);
|
|
27
27
|
|
|
28
28
|
~RawFont ();
|
|
29
29
|
|
|
@@ -33,8 +33,6 @@ namespace Rays
|
|
|
33
33
|
|
|
34
34
|
String name () const;
|
|
35
35
|
|
|
36
|
-
coord size () const;
|
|
37
|
-
|
|
38
36
|
coord get_width (const char* str) const;
|
|
39
37
|
|
|
40
38
|
coord get_height (
|
|
@@ -55,6 +53,10 @@ namespace Rays
|
|
|
55
53
|
|
|
56
54
|
const RawFont& Font_get_raw (const Font& font, float pixel_density);
|
|
57
55
|
|
|
56
|
+
bool Font_has_same_attributes (
|
|
57
|
+
const Font& font, const char* name, coord size,
|
|
58
|
+
int weight, bool italic, bool smooth);
|
|
59
|
+
|
|
58
60
|
|
|
59
61
|
RawFont RawFont_load (const char* path, coord size);
|
|
60
62
|
|
data/src/image.cpp
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
#include <math.h>
|
|
5
5
|
#include <assert.h>
|
|
6
|
+
#include <memory>
|
|
6
7
|
#include "rays/exception.h"
|
|
7
8
|
#include "rays/debug.h"
|
|
8
9
|
#include "bitmap.h"
|
|
@@ -10,7 +11,7 @@
|
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
#if 0
|
|
13
|
-
#define PRINT_MODIFIED_FLAGS(message)
|
|
14
|
+
#define PRINT_MODIFIED_FLAGS(message) self->print_modified_flags(message)
|
|
14
15
|
#else
|
|
15
16
|
#define PRINT_MODIFIED_FLAGS(message)
|
|
16
17
|
#endif
|
|
@@ -20,7 +21,19 @@ namespace Rays
|
|
|
20
21
|
{
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
struct
|
|
24
|
+
struct Pixels
|
|
25
|
+
{
|
|
26
|
+
|
|
27
|
+
typedef std::shared_ptr<Pixels> Ptr;
|
|
28
|
+
|
|
29
|
+
mutable Bitmap bitmap;
|
|
30
|
+
|
|
31
|
+
mutable Texture texture;
|
|
32
|
+
|
|
33
|
+
};// Pixels
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
struct Image::Data
|
|
24
37
|
{
|
|
25
38
|
|
|
26
39
|
int width = 0, height = 0;
|
|
@@ -31,50 +44,52 @@ namespace Rays
|
|
|
31
44
|
|
|
32
45
|
ColorSpace color_space;
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
Pixels::Ptr pixels;
|
|
35
48
|
|
|
36
|
-
|
|
49
|
+
std::unique_ptr<Image::Loader> loader;
|
|
50
|
+
|
|
51
|
+
Data ()
|
|
52
|
+
: pixels(new Pixels())
|
|
53
|
+
{
|
|
54
|
+
}
|
|
37
55
|
|
|
38
56
|
void print_modified_flags (const char* message)
|
|
39
57
|
{
|
|
40
58
|
printf("%s: %d %d %d %d \n",
|
|
41
59
|
message,
|
|
42
|
-
bitmap ? 1 : 0,
|
|
43
|
-
Bitmap_get_modified(bitmap) ? 1 : 0,
|
|
44
|
-
texture ? 1 : 0,
|
|
45
|
-
texture.modified() ? 1 : 0);
|
|
60
|
+
pixels->bitmap ? 1 : 0,
|
|
61
|
+
Bitmap_get_modified(pixels->bitmap) ? 1 : 0,
|
|
62
|
+
pixels->texture ? 1 : 0,
|
|
63
|
+
pixels->texture.modified() ? 1 : 0);
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
};// Image::Data
|
|
49
67
|
|
|
50
68
|
|
|
51
|
-
static ImageData*
|
|
52
|
-
get_data (Image* image)
|
|
53
|
-
{
|
|
54
|
-
return (ImageData*) image->self.get();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
static const ImageData*
|
|
58
|
-
get_data (const Image* image)
|
|
59
|
-
{
|
|
60
|
-
return (const ImageData*) image->self.get();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
69
|
static void
|
|
65
70
|
clear_modified_flags (Image* image)
|
|
66
71
|
{
|
|
67
|
-
|
|
72
|
+
Pixels* pixels = image->self->pixels.get();
|
|
68
73
|
|
|
69
|
-
if (
|
|
70
|
-
|
|
74
|
+
if (pixels->bitmap)
|
|
75
|
+
Bitmap_set_modified(&pixels->bitmap, false);
|
|
76
|
+
|
|
77
|
+
if (pixels->texture)
|
|
78
|
+
pixels->texture.set_modified(false);
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
static void
|
|
74
82
|
invalidate_texture (Image* image)
|
|
75
83
|
{
|
|
76
84
|
image->bitmap();// update bitmap
|
|
77
|
-
|
|
85
|
+
image->self->pixels->texture = Texture();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static void
|
|
89
|
+
check_writable (const Image* image)
|
|
90
|
+
{
|
|
91
|
+
if (image->self->loader)
|
|
92
|
+
invalid_state_error(__FILE__, __LINE__, "image is read-only");
|
|
78
93
|
}
|
|
79
94
|
|
|
80
95
|
static Bitmap&
|
|
@@ -82,31 +97,32 @@ namespace Rays
|
|
|
82
97
|
{
|
|
83
98
|
assert(image);
|
|
84
99
|
|
|
85
|
-
|
|
100
|
+
Image::Data* self = image->self.get();
|
|
101
|
+
Pixels* pixels = self->pixels.get();
|
|
86
102
|
|
|
87
103
|
if (!*image)
|
|
88
104
|
{
|
|
89
|
-
assert(!
|
|
90
|
-
return
|
|
105
|
+
assert(!pixels->bitmap);
|
|
106
|
+
return pixels->bitmap;
|
|
91
107
|
}
|
|
92
108
|
|
|
93
|
-
if (!
|
|
109
|
+
if (!pixels->bitmap)
|
|
94
110
|
{
|
|
95
|
-
if (
|
|
111
|
+
if (pixels->texture)
|
|
96
112
|
{
|
|
97
113
|
PRINT_MODIFIED_FLAGS("new bitmap from texture");
|
|
98
|
-
|
|
114
|
+
pixels->bitmap = Bitmap_from(pixels->texture);
|
|
99
115
|
}
|
|
100
116
|
else
|
|
101
117
|
{
|
|
102
118
|
PRINT_MODIFIED_FLAGS("new bitmap");
|
|
103
|
-
|
|
119
|
+
pixels->bitmap = Bitmap(self->width, self->height, self->color_space);
|
|
104
120
|
}
|
|
105
121
|
clear_modified_flags(image);
|
|
106
122
|
}
|
|
107
|
-
else if (
|
|
123
|
+
else if (pixels->texture && pixels->texture.modified())
|
|
108
124
|
{
|
|
109
|
-
if (Bitmap_get_modified(
|
|
125
|
+
if (Bitmap_get_modified(pixels->bitmap))
|
|
110
126
|
{
|
|
111
127
|
invalid_state_error(
|
|
112
128
|
__FILE__, __LINE__, "bitmap and texture modifications conflicted");
|
|
@@ -114,36 +130,42 @@ namespace Rays
|
|
|
114
130
|
else
|
|
115
131
|
{
|
|
116
132
|
PRINT_MODIFIED_FLAGS("bitmap from texture");
|
|
117
|
-
|
|
133
|
+
pixels->bitmap = Bitmap_from(pixels->texture);
|
|
118
134
|
clear_modified_flags(image);
|
|
119
135
|
}
|
|
120
136
|
}
|
|
121
137
|
|
|
122
|
-
|
|
138
|
+
if (self->loader && self->loader->load(&pixels->bitmap))
|
|
139
|
+
Bitmap_set_modified(&pixels->bitmap);
|
|
140
|
+
|
|
141
|
+
return pixels->bitmap;
|
|
123
142
|
}
|
|
124
143
|
|
|
125
144
|
Texture&
|
|
126
145
|
Image_get_texture (Image& image)
|
|
127
146
|
{
|
|
128
|
-
|
|
147
|
+
Image::Data* self = image.self.get();
|
|
148
|
+
Pixels* pixels = self->pixels.get();
|
|
129
149
|
|
|
130
150
|
if (!image)
|
|
131
151
|
{
|
|
132
|
-
assert(!
|
|
133
|
-
return
|
|
152
|
+
assert(!pixels->texture);
|
|
153
|
+
return pixels->texture;
|
|
134
154
|
}
|
|
135
155
|
|
|
136
|
-
if (
|
|
156
|
+
if (self->loader) get_bitmap(&image);
|
|
157
|
+
|
|
158
|
+
if (!pixels->texture)
|
|
137
159
|
{
|
|
138
|
-
if (
|
|
160
|
+
if (pixels->bitmap)
|
|
139
161
|
{
|
|
140
162
|
PRINT_MODIFIED_FLAGS("new texture from bitmap");
|
|
141
|
-
|
|
163
|
+
pixels->texture = Texture(pixels->bitmap, self->smooth);
|
|
142
164
|
}
|
|
143
165
|
else
|
|
144
166
|
{
|
|
145
167
|
PRINT_MODIFIED_FLAGS("new texture");
|
|
146
|
-
|
|
168
|
+
pixels->texture = Texture(
|
|
147
169
|
self->width, self->height, self->color_space, self->smooth);
|
|
148
170
|
|
|
149
171
|
Painter p = image.painter();
|
|
@@ -153,9 +175,9 @@ namespace Rays
|
|
|
153
175
|
}
|
|
154
176
|
clear_modified_flags(&image);
|
|
155
177
|
}
|
|
156
|
-
else if (
|
|
178
|
+
else if (pixels->bitmap && Bitmap_get_modified(pixels->bitmap))
|
|
157
179
|
{
|
|
158
|
-
if (
|
|
180
|
+
if (pixels->texture.modified())
|
|
159
181
|
{
|
|
160
182
|
invalid_state_error(
|
|
161
183
|
__FILE__, __LINE__, "texture and bitmap modifications conflicted");
|
|
@@ -163,12 +185,12 @@ namespace Rays
|
|
|
163
185
|
else
|
|
164
186
|
{
|
|
165
187
|
PRINT_MODIFIED_FLAGS("texture from bitmap");
|
|
166
|
-
|
|
188
|
+
pixels->texture = pixels->bitmap;
|
|
167
189
|
clear_modified_flags(&image);
|
|
168
190
|
}
|
|
169
191
|
}
|
|
170
192
|
|
|
171
|
-
return
|
|
193
|
+
return pixels->texture;
|
|
172
194
|
}
|
|
173
195
|
|
|
174
196
|
const Texture&
|
|
@@ -184,30 +206,22 @@ namespace Rays
|
|
|
184
206
|
}
|
|
185
207
|
|
|
186
208
|
|
|
187
|
-
Image::
|
|
188
|
-
{
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
void
|
|
192
|
-
Image::Data::preprocess (const Image*) const
|
|
209
|
+
Image::Loader::~Loader ()
|
|
193
210
|
{
|
|
194
211
|
}
|
|
195
212
|
|
|
196
213
|
|
|
197
214
|
Image::Image ()
|
|
198
|
-
: self(new ImageData())
|
|
199
215
|
{
|
|
200
216
|
}
|
|
201
217
|
|
|
202
218
|
Image::Image (
|
|
203
219
|
int width, int height, const ColorSpace& cs,
|
|
204
220
|
float pixel_density, bool smooth)
|
|
205
|
-
: self(new ImageData())
|
|
206
221
|
{
|
|
207
222
|
if (pixel_density <= 0)
|
|
208
223
|
argument_error(__FILE__, __LINE__, "invalid pixel_density.");
|
|
209
224
|
|
|
210
|
-
ImageData* self = get_data(this);
|
|
211
225
|
self->width = (int) (width * pixel_density);
|
|
212
226
|
self->height = (int) (height * pixel_density);
|
|
213
227
|
self->color_space = cs;
|
|
@@ -216,23 +230,33 @@ namespace Rays
|
|
|
216
230
|
}
|
|
217
231
|
|
|
218
232
|
Image::Image (const Bitmap& bitmap, float pixel_density, bool smooth)
|
|
219
|
-
: self(new ImageData())
|
|
220
233
|
{
|
|
221
234
|
if (pixel_density <= 0)
|
|
222
235
|
argument_error(__FILE__, __LINE__, "invalid pixel_density.");
|
|
223
236
|
|
|
224
|
-
|
|
225
|
-
self->
|
|
226
|
-
self->
|
|
227
|
-
self->
|
|
228
|
-
self->
|
|
229
|
-
self->
|
|
230
|
-
self->smooth = smooth;
|
|
237
|
+
self->pixels->bitmap = bitmap;
|
|
238
|
+
self->width = bitmap.width();
|
|
239
|
+
self->height = bitmap.height();
|
|
240
|
+
self->color_space = bitmap.color_space();
|
|
241
|
+
self->pixel_density = pixel_density;
|
|
242
|
+
self->smooth = smooth;
|
|
231
243
|
}
|
|
232
244
|
|
|
233
|
-
Image::Image (
|
|
234
|
-
: self(data)
|
|
245
|
+
Image::Image (const Image& pixels, Loader* loader)
|
|
235
246
|
{
|
|
247
|
+
std::unique_ptr<Loader> loader_(loader);
|
|
248
|
+
if (!loader)
|
|
249
|
+
argument_error(__FILE__, __LINE__, "loader is NULL.");
|
|
250
|
+
if (!pixels)
|
|
251
|
+
argument_error(__FILE__, __LINE__, "invalid pixels image.");
|
|
252
|
+
|
|
253
|
+
self->width = pixels.self->width;
|
|
254
|
+
self->height = pixels.self->height;
|
|
255
|
+
self->color_space = pixels.self->color_space;
|
|
256
|
+
self->pixel_density = pixels.self->pixel_density;
|
|
257
|
+
self->smooth = pixels.self->smooth;
|
|
258
|
+
self->pixels = pixels.self->pixels;
|
|
259
|
+
self->loader = std::move(loader_);
|
|
236
260
|
}
|
|
237
261
|
|
|
238
262
|
Image::~Image ()
|
|
@@ -242,16 +266,12 @@ namespace Rays
|
|
|
242
266
|
Image
|
|
243
267
|
Image::dup () const
|
|
244
268
|
{
|
|
245
|
-
self->preprocess(this);
|
|
246
|
-
|
|
247
269
|
return Image(bitmap().dup(), pixel_density());
|
|
248
270
|
}
|
|
249
271
|
|
|
250
272
|
void
|
|
251
273
|
Image::save (const char* path)
|
|
252
274
|
{
|
|
253
|
-
self->preprocess(this);
|
|
254
|
-
|
|
255
275
|
if (!*this)
|
|
256
276
|
invalid_state_error(__FILE__, __LINE__);
|
|
257
277
|
|
|
@@ -261,45 +281,31 @@ namespace Rays
|
|
|
261
281
|
coord
|
|
262
282
|
Image::width () const
|
|
263
283
|
{
|
|
264
|
-
self->preprocess(this);
|
|
265
|
-
|
|
266
|
-
const ImageData* self = get_data(this);
|
|
267
284
|
return self->width / self->pixel_density;
|
|
268
285
|
}
|
|
269
286
|
|
|
270
287
|
coord
|
|
271
288
|
Image::height () const
|
|
272
289
|
{
|
|
273
|
-
self->preprocess(this);
|
|
274
|
-
|
|
275
|
-
const ImageData* self = get_data(this);
|
|
276
290
|
return self->height / self->pixel_density;
|
|
277
291
|
}
|
|
278
292
|
|
|
279
293
|
const ColorSpace&
|
|
280
294
|
Image::color_space () const
|
|
281
295
|
{
|
|
282
|
-
self->preprocess(this);
|
|
283
|
-
|
|
284
|
-
const ImageData* self = get_data(this);
|
|
285
296
|
return self->color_space;
|
|
286
297
|
}
|
|
287
298
|
|
|
288
299
|
float
|
|
289
300
|
Image::pixel_density () const
|
|
290
301
|
{
|
|
291
|
-
self->preprocess(this);
|
|
292
|
-
|
|
293
|
-
const ImageData* self = get_data(this);
|
|
294
302
|
return self->pixel_density;
|
|
295
303
|
}
|
|
296
304
|
|
|
297
305
|
void
|
|
298
306
|
Image::set_smooth (bool smooth)
|
|
299
307
|
{
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
ImageData* self = get_data(this);
|
|
308
|
+
check_writable(this);
|
|
303
309
|
|
|
304
310
|
if (smooth == self->smooth) return;
|
|
305
311
|
self->smooth = smooth;
|
|
@@ -309,16 +315,13 @@ namespace Rays
|
|
|
309
315
|
bool
|
|
310
316
|
Image::smooth () const
|
|
311
317
|
{
|
|
312
|
-
self->preprocess(this);
|
|
313
|
-
|
|
314
|
-
const ImageData* self = get_data(this);
|
|
315
318
|
return self->smooth;
|
|
316
319
|
}
|
|
317
320
|
|
|
318
321
|
Painter
|
|
319
322
|
Image::painter ()
|
|
320
323
|
{
|
|
321
|
-
|
|
324
|
+
check_writable(this);
|
|
322
325
|
|
|
323
326
|
Painter p;
|
|
324
327
|
p.bind(*this);
|
|
@@ -328,15 +331,11 @@ namespace Rays
|
|
|
328
331
|
Bitmap&
|
|
329
332
|
Image::bitmap (bool modify)
|
|
330
333
|
{
|
|
331
|
-
|
|
334
|
+
if (modify) check_writable(this);
|
|
332
335
|
|
|
333
|
-
|
|
334
|
-
if (modify)
|
|
335
|
-
|
|
336
|
-
if (!self->bitmap) get_bitmap(this);
|
|
337
|
-
Bitmap_set_modified(&self->bitmap);
|
|
338
|
-
}
|
|
339
|
-
return get_bitmap(this);
|
|
336
|
+
Bitmap& bitmap = get_bitmap(this);
|
|
337
|
+
if (modify) Bitmap_set_modified(&bitmap);
|
|
338
|
+
return bitmap;
|
|
340
339
|
}
|
|
341
340
|
|
|
342
341
|
const Bitmap&
|
|
@@ -345,11 +344,14 @@ namespace Rays
|
|
|
345
344
|
return const_cast<Image*>(this)->bitmap();
|
|
346
345
|
}
|
|
347
346
|
|
|
348
|
-
Image::
|
|
347
|
+
const Image::Loader*
|
|
348
|
+
Image::loader () const
|
|
349
349
|
{
|
|
350
|
-
self->
|
|
350
|
+
return self->loader.get();
|
|
351
|
+
}
|
|
351
352
|
|
|
352
|
-
|
|
353
|
+
Image::operator bool () const
|
|
354
|
+
{
|
|
353
355
|
return
|
|
354
356
|
self->width > 0 &&
|
|
355
357
|
self->height > 0 &&
|