|
2 | 2 | /// |
3 | 3 | /// # Representation |
4 | 4 | /// |
5 | | -/// This is a set of `u8`'s in the order BGRX (first component blue, second green, third red and |
6 | | -/// last unset). |
| 5 | +/// This is a set of 4 `u8`'s laid out in the order defined by [`PixelFormat::default()`]. |
7 | 6 | /// |
8 | | -/// If you're familiar with [the `rgb` crate](https://docs.rs/rgb/), you can treat this mostly as-if |
9 | | -/// it is `rgb::Bgra<u8>`, except that this type has an alignment of `4` for performance reasons. |
| 7 | +/// This type has an alignment of `4` for performance reasons, as that makes copies faster on many |
| 8 | +/// platforms, and makes this type have the same in-memory representation as `u32`. |
| 9 | +/// |
| 10 | +/// [`PixelFormat::default()`]: crate::PixelFormat#default |
10 | 11 | /// |
11 | 12 | /// # Example |
12 | 13 | /// |
13 | 14 | /// Construct a new pixel. |
14 | 15 | /// |
15 | 16 | /// ``` |
16 | | -/// # use softbuffer::Pixel; |
17 | | -/// # |
| 17 | +/// use softbuffer::Pixel; |
| 18 | +/// |
18 | 19 | /// let red = Pixel::new_rgb(0xff, 0x80, 0); |
19 | 20 | /// assert_eq!(red.r, 255); |
20 | 21 | /// assert_eq!(red.g, 128); |
|
28 | 29 | /// Convert a pixel to an array of `u8`s. |
29 | 30 | /// |
30 | 31 | /// ``` |
31 | | -/// # use softbuffer::Pixel; |
32 | | -/// # |
| 32 | +/// use softbuffer::{Pixel, PixelFormat}; |
| 33 | +/// |
33 | 34 | /// let red = Pixel::new_rgb(0xff, 0, 0); |
34 | 35 | /// // SAFETY: `Pixel` can be reinterpreted as `[u8; 4]`. |
35 | 36 | /// let red = unsafe { core::mem::transmute::<Pixel, [u8; 4]>(red) }; |
36 | 37 | /// |
37 | | -/// // BGRX |
38 | | -/// assert_eq!(red[2], 255); |
| 38 | +/// match PixelFormat::default() { |
| 39 | +/// PixelFormat::Bgrx => assert_eq!(red[2], 255), |
| 40 | +/// PixelFormat::Rgbx => assert_eq!(red[0], 255), |
| 41 | +/// } |
39 | 42 | /// ``` |
40 | 43 | /// |
41 | 44 | /// Convert a pixel to an `u32`. |
42 | 45 | /// |
43 | 46 | /// ``` |
44 | | -/// # use softbuffer::Pixel; |
45 | | -/// # |
| 47 | +/// use softbuffer::{Pixel, PixelFormat}; |
| 48 | +/// |
46 | 49 | /// let red = Pixel::new_rgb(0xff, 0, 0); |
47 | 50 | /// // SAFETY: `Pixel` can be reinterpreted as `u32`. |
48 | 51 | /// let red = unsafe { core::mem::transmute::<Pixel, u32>(red) }; |
49 | 52 | /// |
50 | | -/// // BGRX |
51 | | -/// assert_eq!(red, u32::from_le_bytes([0x00, 0x00, 0xff, 0x00])); |
| 53 | +/// match PixelFormat::default() { |
| 54 | +/// PixelFormat::Bgrx => assert_eq!(red, u32::from_ne_bytes([0x00, 0x00, 0xff, 0x00])), |
| 55 | +/// PixelFormat::Rgbx => assert_eq!(red, u32::from_ne_bytes([0xff, 0x00, 0x00, 0x00])), |
| 56 | +/// } |
52 | 57 | /// ``` |
53 | 58 | #[repr(C)] |
54 | 59 | #[repr(align(4))] // Help the compiler to see that this is a u32 |
55 | 60 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] |
56 | 61 | pub struct Pixel { |
| 62 | + #[cfg_attr(docsrs, doc(auto_cfg = false))] |
| 63 | + #[cfg(any(doc, target_family = "wasm", target_os = "android"))] |
| 64 | + /// The red component. |
| 65 | + pub r: u8, |
| 66 | + #[cfg(not(any(doc, target_family = "wasm", target_os = "android")))] |
57 | 67 | /// The blue component. |
58 | 68 | pub b: u8, |
| 69 | + |
59 | 70 | /// The green component. |
60 | 71 | pub g: u8, |
| 72 | + |
| 73 | + #[cfg_attr(docsrs, doc(auto_cfg = false))] |
| 74 | + #[cfg(any(doc, target_family = "wasm", target_os = "android"))] |
| 75 | + /// The blue component. |
| 76 | + pub b: u8, |
| 77 | + #[cfg(not(any(doc, target_family = "wasm", target_os = "android")))] |
61 | 78 | /// The red component. |
62 | 79 | pub r: u8, |
63 | 80 |
|
@@ -106,3 +123,6 @@ impl Pixel { |
106 | 123 | } |
107 | 124 |
|
108 | 125 | // TODO: Implement `Add`/`Mul`/similar `std::ops` like `rgb` does? |
| 126 | + |
| 127 | +// TODO: Implement `zerocopy` / `bytemuck` traits behind a feature flag? |
| 128 | +// May not be that useful, since the representation is platform-specific. |
0 commit comments