@@ -33,6 +33,7 @@ pub struct Pattern {
33
33
flags : PatternFlags ,
34
34
}
35
35
36
+ /// Where a raster image pattern comes from.
36
37
#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
37
38
pub enum PatternSource {
38
39
Image ( Image ) ,
@@ -42,9 +43,10 @@ pub enum PatternSource {
42
43
}
43
44
}
44
45
45
- /// RGBA, non-premultiplied.
46
+ /// A raster image, in 32-bit RGBA (8 bits per channel) , non-premultiplied form .
46
47
// FIXME(pcwalton): Hash the pixel contents so that we don't have to compare every pixel!
47
48
// TODO(pcwalton): Should the pixels be premultiplied?
49
+ // TODO(pcwalton): Color spaces.
48
50
#[ derive( Clone , PartialEq , Eq ) ]
49
51
pub struct Image {
50
52
size : Vector2I ,
@@ -58,9 +60,15 @@ pub struct Image {
58
60
pub struct ImageHash ( pub u64 ) ;
59
61
60
62
bitflags ! {
63
+ /// Various flags that determine behavior of a pattern.
61
64
pub struct PatternFlags : u8 {
65
+ /// If set, the pattern repeats in the X direction. If unset, the base color is used.
62
66
const REPEAT_X = 0x01 ;
67
+ /// If set, the pattern repeats in the Y direction. If unset, the base color is used.
63
68
const REPEAT_Y = 0x02 ;
69
+ /// If set, nearest-neighbor interpolation is used when compositing this pattern (i.e. the
70
+ /// image will be pixelated). If unset, bilinear interpolation is used when compositing
71
+ /// this pattern (i.e. the image will be smooth).
64
72
const NO_SMOOTHING = 0x04 ;
65
73
}
66
74
}
@@ -76,26 +84,37 @@ impl Pattern {
76
84
}
77
85
}
78
86
87
+ /// Creates a new pattern from the given image.
88
+ ///
89
+ /// The transform is initialized to the identity transform. There is no filter.
79
90
#[ inline]
80
91
pub fn from_image ( image : Image ) -> Pattern {
81
92
Pattern :: from_source ( PatternSource :: Image ( image) )
82
93
}
83
94
95
+ /// Creates a new pattern from the given render target with the given size.
96
+ ///
97
+ /// The transform is initialized to the identity transform. There is no filter.
84
98
#[ inline]
85
99
pub fn from_render_target ( id : RenderTargetId , size : Vector2I ) -> Pattern {
86
100
Pattern :: from_source ( PatternSource :: RenderTarget { id, size } )
87
101
}
88
102
103
+ /// Returns the affine transform applied to this pattern.
89
104
#[ inline]
90
105
pub fn transform ( & self ) -> Transform2F {
91
106
self . transform
92
107
}
93
108
109
+ /// Applies the given transform to this pattern.
110
+ ///
111
+ /// The transform is applied after any existing transform.
94
112
#[ inline]
95
113
pub fn apply_transform ( & mut self , transform : Transform2F ) {
96
114
self . transform = transform * self . transform ;
97
115
}
98
116
117
+ /// Returns the underlying pixel size of this pattern, not taking transforms into account.
99
118
#[ inline]
100
119
pub fn size ( & self ) -> Vector2I {
101
120
match self . source {
@@ -104,58 +123,81 @@ impl Pattern {
104
123
}
105
124
}
106
125
126
+ /// Returns the filter attached to this pattern, if any.
107
127
#[ inline]
108
128
pub fn filter ( & self ) -> Option < PatternFilter > {
109
129
self . filter
110
130
}
111
131
132
+ /// Applies a filter to this pattern, replacing any previous filter if any.
112
133
#[ inline]
113
134
pub fn set_filter ( & mut self , filter : Option < PatternFilter > ) {
114
135
self . filter = filter;
115
136
}
116
137
138
+ /// Returns true if this pattern repeats in the X direction or false if the base color will be
139
+ /// used when sampling beyond the coordinates of the image.
117
140
#[ inline]
118
141
pub fn repeat_x ( & self ) -> bool {
119
142
self . flags . contains ( PatternFlags :: REPEAT_X )
120
143
}
121
144
145
+ /// Set to true if the pattern should repeat in the X direction or false if the base color
146
+ /// should be used when sampling beyond the coordinates of the image.
122
147
#[ inline]
123
148
pub fn set_repeat_x ( & mut self , repeat_x : bool ) {
124
149
self . flags . set ( PatternFlags :: REPEAT_X , repeat_x) ;
125
150
}
126
151
152
+ /// Returns true if this pattern repeats in the Y direction or false if the base color will be
153
+ /// used when sampling beyond the coordinates of the image.
127
154
#[ inline]
128
155
pub fn repeat_y ( & self ) -> bool {
129
156
self . flags . contains ( PatternFlags :: REPEAT_Y )
130
157
}
131
158
159
+ /// Set to true if the pattern should repeat in the Y direction or false if the base color
160
+ /// should be used when sampling beyond the coordinates of the image.
132
161
#[ inline]
133
162
pub fn set_repeat_y ( & mut self , repeat_y : bool ) {
134
163
self . flags . set ( PatternFlags :: REPEAT_Y , repeat_y) ;
135
164
}
136
165
166
+ /// Returns true if this pattern should use bilinear interpolation (i.e. the image will be
167
+ /// smooth) when scaled or false if this pattern should use nearest-neighbor interpolation
168
+ /// (i.e. the image will be pixelated).
137
169
#[ inline]
138
170
pub fn smoothing_enabled ( & self ) -> bool {
139
171
!self . flags . contains ( PatternFlags :: NO_SMOOTHING )
140
172
}
141
173
174
+ /// Set to true if the pattern should use bilinear interpolation (i.e. should be smooth) when
175
+ /// scaled or false if this pattern should use nearest-neighbor interpolation (i.e. should be
176
+ /// pixelated).
142
177
#[ inline]
143
178
pub fn set_smoothing_enabled ( & mut self , enable : bool ) {
144
179
self . flags . set ( PatternFlags :: NO_SMOOTHING , !enable) ;
145
180
}
146
181
182
+ /// Returns true if this pattern is obviously fully opaque.
183
+ ///
184
+ /// This is a best-effort quick check, so it might return false even if the image is actually
185
+ /// opaque.
147
186
#[ inline]
148
187
pub fn is_opaque ( & self ) -> bool {
149
188
self . source . is_opaque ( )
150
189
}
151
190
191
+ /// Returns the underlying source of the pattern.
152
192
#[ inline]
153
193
pub fn source ( & self ) -> & PatternSource {
154
194
& self . source
155
195
}
156
196
}
157
197
158
198
impl Image {
199
+ /// Creates a new image with the given device pixel size and pixel store, as 32-bit RGBA (8
200
+ /// bits per channel), RGBA, linear color space, nonpremultiplied.
159
201
#[ inline]
160
202
pub fn new ( size : Vector2I , pixels : Arc < Vec < ColorU > > ) -> Image {
161
203
assert_eq ! ( size. x( ) as usize * size. y( ) as usize , pixels. len( ) ) ;
@@ -168,28 +210,37 @@ impl Image {
168
210
Image { size, pixels, pixels_hash, is_opaque }
169
211
}
170
212
213
+ /// A convenience function to create a new image with the given image from the `image` crate.
171
214
#[ cfg( feature = "pf-image" ) ]
172
215
pub fn from_image_buffer ( image_buffer : RgbaImage ) -> Image {
173
216
let ( width, height) = image_buffer. dimensions ( ) ;
174
217
let pixels = color:: u8_vec_to_color_vec ( image_buffer. into_raw ( ) ) ;
175
218
Image :: new ( vec2i ( width as i32 , height as i32 ) , Arc :: new ( pixels) )
176
219
}
177
220
221
+ /// Returns the device pixel size of the image.
178
222
#[ inline]
179
223
pub fn size ( & self ) -> Vector2I {
180
224
self . size
181
225
}
182
226
227
+ /// Returns the pixel buffer of this image as 32-bit RGBA (8 bits per channel), RGBA, linear
228
+ /// color space, nonpremultiplied.
183
229
#[ inline]
184
230
pub fn pixels ( & self ) -> & Arc < Vec < ColorU > > {
185
231
& self . pixels
186
232
}
187
233
234
+ /// Returns true if this image is obviously opaque.
235
+ ///
236
+ /// This is a best-guess quick check, and as such it might return false even if the image is
237
+ /// fully opaque.
188
238
#[ inline]
189
239
pub fn is_opaque ( & self ) -> bool {
190
240
self . is_opaque
191
241
}
192
242
243
+ /// Returns a non-cryptographic hash of the image, which should be globally unique.
193
244
#[ inline]
194
245
pub fn get_hash ( & self ) -> ImageHash {
195
246
let mut hasher = DefaultHasher :: new ( ) ;
@@ -199,6 +250,10 @@ impl Image {
199
250
}
200
251
201
252
impl PatternSource {
253
+ /// Returns true if this pattern is obviously opaque.
254
+ ///
255
+ /// This is a best-guess quick check, and as such it might return false even if the pattern is
256
+ /// fully opaque.
202
257
#[ inline]
203
258
pub fn is_opaque ( & self ) -> bool {
204
259
match * self {
0 commit comments