Skip to content

Commit 7c68dd3

Browse files
Create RColor type to directly wrap SDL_Color
1 parent 9d26e50 commit 7c68dd3

File tree

4 files changed

+210
-33
lines changed

4 files changed

+210
-33
lines changed

examples/animation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn main() -> Result<(), String> {
2424
.map_err(|e| e.to_string())?;
2525
let texture_creator = canvas.texture_creator();
2626

27-
canvas.set_draw_color(sdl2::pixels::Color::RGBA(0, 0, 0, 255));
27+
canvas.set_draw_color(sdl2::pixels::RColor::RGBA(0, 0, 0, 255));
2828

2929
let timer = sdl_context.timer()?;
3030

src/sdl2/pixels.rs

+168-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::sys;
2-
use std::convert::TryFrom;
2+
use std::convert::{AsMut, AsRef, TryFrom};
3+
use std::hash::{Hash, Hasher};
34
use std::mem::transmute;
5+
use std::ops::{Deref, DerefMut};
46

57
use crate::get_error;
68

@@ -41,15 +43,18 @@ impl Palette {
4143

4244
/// Creates a palette from the provided colors
4345
#[doc(alias = "SDL_SetPaletteColors")]
44-
pub fn with_colors(colors: &[Color]) -> Result<Self, String> {
46+
pub fn with_colors<C>(colors: &[C]) -> Result<Self, String>
47+
where
48+
C: Copy + Into<RColor>,
49+
{
4550
let pal = Self::new(colors.len())?;
4651

4752
// Already validated, so don't check again
4853
let ncolors = colors.len() as ::libc::c_int;
4954

5055
let result = unsafe {
5156
let mut raw_colors: Vec<sys::SDL_Color> =
52-
colors.iter().map(|color| color.raw()).collect();
57+
colors.iter().map(|color| (*color).into().raw).collect();
5358

5459
let pal_ptr = (&mut raw_colors[0]) as *mut sys::SDL_Color;
5560

@@ -85,21 +90,23 @@ impl_raw_accessors!((Palette, *mut sys::SDL_Palette));
8590

8691
#[test]
8792
fn create_palette() {
88-
let colors: Vec<_> = (0..0xff).map(|u| Color::RGB(u, 0, 0xff - u)).collect();
93+
let colors: Vec<_> = (0..0xff).map(|u| RColor::RGB(u, 0, 0xff - u)).collect();
8994

9095
let palette = Palette::with_colors(&colors).unwrap();
9196

9297
assert!(palette.len() == 255);
9398
}
9499

95100
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
101+
#[deprecated(since = "0.35.3", note = "Users should instead use RColor")]
96102
pub struct Color {
97103
pub r: u8,
98104
pub g: u8,
99105
pub b: u8,
100106
pub a: u8,
101107
}
102108

109+
#[allow(deprecated)]
103110
impl Color {
104111
#[inline]
105112
#[allow(non_snake_case)]
@@ -163,30 +170,187 @@ impl Color {
163170
pub const CYAN: Color = Color::RGBA(0, 255, 255, 255);
164171
}
165172

173+
#[allow(deprecated)]
166174
impl Into<sys::SDL_Color> for Color {
167175
fn into(self) -> sys::SDL_Color {
168176
self.raw()
169177
}
170178
}
171179

180+
#[allow(deprecated)]
172181
impl From<sys::SDL_Color> for Color {
173182
fn from(raw: sys::SDL_Color) -> Color {
174183
Color::RGBA(raw.r, raw.g, raw.b, raw.a)
175184
}
176185
}
177186

187+
#[allow(deprecated)]
178188
impl From<(u8, u8, u8)> for Color {
179189
fn from((r, g, b): (u8, u8, u8)) -> Color {
180190
Color::RGB(r, g, b)
181191
}
182192
}
183193

194+
#[allow(deprecated)]
184195
impl From<(u8, u8, u8, u8)> for Color {
185196
fn from((r, g, b, a): (u8, u8, u8, u8)) -> Color {
186197
Color::RGBA(r, g, b, a)
187198
}
188199
}
189200

201+
#[allow(deprecated)]
202+
impl Into<RColor> for Color {
203+
fn into(self) -> RColor {
204+
RColor::RGBA(self.r, self.g, self.b, self.a)
205+
}
206+
}
207+
208+
#[derive(Copy, Clone)]
209+
pub struct RColor {
210+
raw: sys::SDL_Color,
211+
}
212+
213+
impl RColor {
214+
#[inline]
215+
#[allow(non_snake_case)]
216+
pub const fn RGB(r: u8, g: u8, b: u8) -> RColor {
217+
RColor {
218+
raw: sys::SDL_Color { r, g, b, a: 0xff },
219+
}
220+
}
221+
222+
#[inline]
223+
#[allow(non_snake_case)]
224+
pub const fn RGBA(r: u8, g: u8, b: u8, a: u8) -> RColor {
225+
RColor {
226+
raw: sys::SDL_Color { r, g, b, a },
227+
}
228+
}
229+
230+
#[doc(alias = "SDL_MapRGBA")]
231+
pub fn to_u32(self, format: &PixelFormat) -> u32 {
232+
unsafe { sys::SDL_MapRGBA(format.raw, self.raw.r, self.raw.g, self.raw.b, self.raw.a) }
233+
}
234+
235+
#[doc(alias = "SDL_GetRGBA")]
236+
pub fn from_u32(format: &PixelFormat, pixel: u32) -> RColor {
237+
let (mut r, mut g, mut b, mut a) = (0, 0, 0, 0);
238+
239+
unsafe { sys::SDL_GetRGBA(pixel, format.raw, &mut r, &mut g, &mut b, &mut a) };
240+
RColor::RGBA(r, g, b, a)
241+
}
242+
243+
pub fn invert(self) -> RColor {
244+
RColor::RGBA(
245+
255 - self.raw.r,
246+
255 - self.raw.g,
247+
255 - self.raw.b,
248+
255 - self.raw.a,
249+
)
250+
}
251+
252+
#[inline]
253+
pub const fn rgb(self) -> (u8, u8, u8) {
254+
(self.raw.r, self.raw.g, self.raw.b)
255+
}
256+
257+
#[inline]
258+
pub const fn rgba(self) -> (u8, u8, u8, u8) {
259+
(self.raw.r, self.raw.g, self.raw.b, self.raw.a)
260+
}
261+
262+
#[inline]
263+
pub const fn raw(self) -> sys::SDL_Color {
264+
self.raw
265+
}
266+
267+
pub const WHITE: RColor = RColor::RGBA(255, 255, 255, 255);
268+
pub const BLACK: RColor = RColor::RGBA(0, 0, 0, 255);
269+
pub const GRAY: RColor = RColor::RGBA(128, 128, 128, 255);
270+
pub const GREY: RColor = RColor::GRAY;
271+
pub const RED: RColor = RColor::RGBA(255, 0, 0, 255);
272+
pub const GREEN: RColor = RColor::RGBA(0, 255, 0, 255);
273+
pub const BLUE: RColor = RColor::RGBA(0, 0, 255, 255);
274+
pub const MAGENTA: RColor = RColor::RGBA(255, 0, 255, 255);
275+
pub const YELLOW: RColor = RColor::RGBA(255, 255, 0, 255);
276+
pub const CYAN: RColor = RColor::RGBA(0, 255, 255, 255);
277+
}
278+
279+
impl ::std::fmt::Debug for RColor {
280+
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
281+
return write!(
282+
fmt,
283+
"RColor {{ r: {}, g: {}, b: {}, a: {} }}",
284+
self.raw.r, self.raw.g, self.raw.b, self.raw.a
285+
);
286+
}
287+
}
288+
289+
impl PartialEq for RColor {
290+
fn eq(&self, other: &RColor) -> bool {
291+
self.raw.r == other.raw.r
292+
&& self.raw.g == other.raw.g
293+
&& self.raw.b == other.raw.b
294+
&& self.raw.a == other.raw.a
295+
}
296+
}
297+
298+
impl Eq for RColor {}
299+
300+
impl Hash for RColor {
301+
fn hash<H: Hasher>(&self, state: &mut H) {
302+
self.raw.r.hash(state);
303+
self.raw.g.hash(state);
304+
self.raw.b.hash(state);
305+
self.raw.a.hash(state);
306+
}
307+
}
308+
309+
impl Deref for RColor {
310+
type Target = sys::SDL_Color;
311+
312+
fn deref(&self) -> &sys::SDL_Color {
313+
&self.raw
314+
}
315+
}
316+
317+
impl DerefMut for RColor {
318+
fn deref_mut(&mut self) -> &mut sys::SDL_Color {
319+
&mut self.raw
320+
}
321+
}
322+
323+
impl AsRef<sys::SDL_Color> for RColor {
324+
fn as_ref(&self) -> &sys::SDL_Color {
325+
&self.raw
326+
}
327+
}
328+
329+
impl AsMut<sys::SDL_Color> for RColor {
330+
fn as_mut(&mut self) -> &mut sys::SDL_Color {
331+
&mut self.raw
332+
}
333+
}
334+
335+
impl Into<sys::SDL_Color> for RColor {
336+
fn into(self) -> sys::SDL_Color {
337+
self.raw
338+
}
339+
}
340+
341+
impl From<sys::SDL_Color> for RColor {
342+
fn from(raw: sys::SDL_Color) -> RColor {
343+
RColor { raw }
344+
}
345+
}
346+
347+
#[allow(deprecated)]
348+
impl Into<Color> for RColor {
349+
fn into(self) -> Color {
350+
Color::RGBA(self.raw.r, self.raw.g, self.raw.b, self.raw.a)
351+
}
352+
}
353+
190354
pub struct PixelMasks {
191355
/// Bits per pixel; usually 15, 16, or 32
192356
pub bpp: u8,

src/sdl2/render.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -163,18 +163,21 @@ impl Into<sys::SDL_Vertex> for Vertex {
163163
}
164164

165165
impl Vertex {
166-
pub fn new(position: FPoint, color: pixels::Color, tex_coord: FPoint) -> Vertex {
166+
pub fn new<C>(position: FPoint, color: C, tex_coord: FPoint) -> Vertex
167+
where
168+
C: Copy + Into<pixels::RColor>,
169+
{
167170
Vertex {
168171
raw: sys::SDL_Vertex {
169172
position: position.into(),
170-
color: color.into(),
173+
color: color.into().raw(),
171174
tex_coord: tex_coord.into(),
172175
},
173176
}
174177
}
175178

176179
pub fn from_ll(raw: sys::SDL_Vertex) -> Vertex {
177-
Vertex::new(raw.position.into(), raw.color.into(), raw.tex_coord.into())
180+
Vertex::new(raw.position.into(), raw.color, raw.tex_coord.into())
178181
}
179182

180183
#[doc(alias = "SDL_Vertex")]
@@ -192,7 +195,7 @@ impl Vertex {
192195
self.raw.position.into()
193196
}
194197

195-
pub fn color(self) -> pixels::Color {
198+
pub fn color(self) -> pixels::RColor {
196199
self.raw.color.into()
197200
}
198201

@@ -408,7 +411,7 @@ impl<'s> RenderTarget for Surface<'s> {
408411
/// ```rust,no_run
409412
/// # use sdl2::render::Canvas;
410413
/// # use sdl2::video::Window;
411-
/// # use sdl2::pixels::Color;
414+
/// # use sdl2::pixels::RColor;
412415
/// # use sdl2::rect::Rect;
413416
/// # let sdl_context = sdl2::init().unwrap();
414417
/// # let video_subsystem = sdl_context.video().unwrap();
@@ -420,12 +423,12 @@ impl<'s> RenderTarget for Surface<'s> {
420423
/// // render faster than your display rate (usually 60Hz or 144Hz)
421424
/// .build().unwrap();
422425
///
423-
/// canvas.set_draw_color(Color::RGB(0, 0, 0));
426+
/// canvas.set_draw_color(RColor::RGB(0, 0, 0));
424427
/// // fills the canvas with the color we set in `set_draw_color`.
425428
/// canvas.clear();
426429
///
427430
/// // change the color of our drawing with a gold-color ...
428-
/// canvas.set_draw_color(Color::RGB(255, 210, 0));
431+
/// canvas.set_draw_color(RColor::RGB(255, 210, 0));
429432
/// // A draw a rectangle which almost fills our window with it !
430433
/// canvas.fill_rect(Rect::new(10, 10, 780, 580));
431434
///
@@ -609,17 +612,17 @@ impl<T: RenderTarget> Canvas<T> {
609612
/// ```rust,no_run
610613
/// # use sdl2::render::{Canvas, Texture};
611614
/// # use sdl2::video::Window;
612-
/// # use sdl2::pixels::Color;
615+
/// # use sdl2::pixels::RColor;
613616
/// # use sdl2::rect::Rect;
614617
/// # let mut canvas : Canvas<Window> = unimplemented!();
615618
/// let texture_creator = canvas.texture_creator();
616619
/// let mut texture = texture_creator
617620
/// .create_texture_target(texture_creator.default_pixel_format(), 150, 150)
618621
/// .unwrap();
619622
/// let result = canvas.with_texture_canvas(&mut texture, |texture_canvas| {
620-
/// texture_canvas.set_draw_color(Color::RGBA(0, 0, 0, 255));
623+
/// texture_canvas.set_draw_color(RColor::RGBA(0, 0, 0, 255));
621624
/// texture_canvas.clear();
622-
/// texture_canvas.set_draw_color(Color::RGBA(255, 0, 0, 255));
625+
/// texture_canvas.set_draw_color(RColor::RGBA(255, 0, 0, 255));
623626
/// texture_canvas.fill_rect(Rect::new(50, 50, 50, 50)).unwrap();
624627
/// });
625628
/// ```
@@ -665,7 +668,7 @@ impl<T: RenderTarget> Canvas<T> {
665668
/// Let's create two textures, one which will be yellow, and the other will be white
666669
///
667670
/// ```rust,no_run
668-
/// # use sdl2::pixels::Color;
671+
/// # use sdl2::pixels::RColor;
669672
/// # use sdl2::rect::Rect;
670673
/// # use sdl2::video::Window;
671674
/// # use sdl2::render::{Canvas, Texture};
@@ -688,10 +691,10 @@ impl<T: RenderTarget> Canvas<T> {
688691
/// canvas.with_multiple_texture_canvas(textures.iter(), |texture_canvas, user_context| {
689692
/// match *user_context {
690693
/// TextureColor::White => {
691-
/// texture_canvas.set_draw_color(Color::RGB(255, 255, 255));
694+
/// texture_canvas.set_draw_color(RColor::RGB(255, 255, 255));
692695
/// },
693696
/// TextureColor::Yellow => {
694-
/// texture_canvas.set_draw_color(Color::RGB(255, 255, 0));
697+
/// texture_canvas.set_draw_color(RColor::RGB(255, 255, 0));
695698
/// }
696699
/// };
697700
/// texture_canvas.clear();
@@ -1083,7 +1086,7 @@ impl<T: RenderTarget> Canvas<T> {
10831086

10841087
/// Sets the color used for drawing operations (Rect, Line and Clear).
10851088
#[doc(alias = "SDL_SetRenderDrawColor")]
1086-
pub fn set_draw_color<C: Into<pixels::Color>>(&mut self, color: C) {
1089+
pub fn set_draw_color<C: Into<pixels::RColor>>(&mut self, color: C) {
10871090
let (r, g, b, a) = color.into().rgba();
10881091
let ret = unsafe { sys::SDL_SetRenderDrawColor(self.raw, r, g, b, a) };
10891092
// Should only fail on an invalid renderer
@@ -1094,7 +1097,7 @@ impl<T: RenderTarget> Canvas<T> {
10941097

10951098
/// Gets the color used for drawing operations (Rect, Line and Clear).
10961099
#[doc(alias = "SDL_GetRenderDrawColor")]
1097-
pub fn draw_color(&self) -> pixels::Color {
1100+
pub fn draw_color(&self) -> pixels::RColor {
10981101
let (mut r, mut g, mut b, mut a) = (0, 0, 0, 0);
10991102
let ret = unsafe {
11001103
sys::SDL_GetRenderDrawColor(self.context.raw, &mut r, &mut g, &mut b, &mut a)
@@ -1103,7 +1106,7 @@ impl<T: RenderTarget> Canvas<T> {
11031106
if ret != 0 {
11041107
panic!("{}", get_error())
11051108
} else {
1106-
pixels::Color::RGBA(r, g, b, a)
1109+
pixels::RColor::RGBA(r, g, b, a)
11071110
}
11081111
}
11091112

@@ -1602,7 +1605,7 @@ impl<T: RenderTarget> Canvas<T> {
16021605
texture: &Texture,
16031606
xy: &[f32],
16041607
xy_stride: i32,
1605-
color: &[sys::SDL_Color],
1608+
color: &[pixels::RColor],
16061609
color_stride: i32,
16071610
uv: &[f32],
16081611
uv_stride: i32,

0 commit comments

Comments
 (0)