| 1 | //! Pixel color types. |
| 2 | //! |
| 3 | //! This module contains structs for commonly used pixel color formats and |
| 4 | //! conversions between them. The [`raw` module] provides additional functions |
| 5 | //! to convert colors to and from raw data for use with images and displays. |
| 6 | //! |
| 7 | //! # Implementing custom color types |
| 8 | //! |
| 9 | //! Custom color types can be added by implementing the [`PixelColor`] trait. |
| 10 | //! The following example shows how to implement a new color type for a |
| 11 | //! 3 color EPD display. |
| 12 | //! |
| 13 | //! ``` |
| 14 | //! use embedded_graphics::{ |
| 15 | //! geometry::Size, prelude::*, primitives::{Rectangle, PrimitiveStyle}, |
| 16 | //! }; |
| 17 | //! |
| 18 | //! /// Color with 3 states. |
| 19 | //! #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] |
| 20 | //! pub enum EpdColor { |
| 21 | //! White, |
| 22 | //! Black, |
| 23 | //! Red, |
| 24 | //! } |
| 25 | //! |
| 26 | //! /// The `Raw` can be is set to `()` because `EpdColor` doesn't need to be |
| 27 | //! /// converted to raw data for the display and isn't stored in images. |
| 28 | //! impl PixelColor for EpdColor { |
| 29 | //! type Raw = (); |
| 30 | //! } |
| 31 | //! |
| 32 | //! /// Mock EPD display. |
| 33 | //! pub struct EpdDisplay {} |
| 34 | //! |
| 35 | //! impl DrawTarget for EpdDisplay { |
| 36 | //! type Color = EpdColor; |
| 37 | //! type Error = core::convert::Infallible; |
| 38 | //! |
| 39 | //! fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error> |
| 40 | //! where |
| 41 | //! I: IntoIterator<Item = Pixel<Self::Color>>, |
| 42 | //! { |
| 43 | //! for Pixel(point, color) in pixels.into_iter() { |
| 44 | //! match color { |
| 45 | //! EpdColor::White => {} // draw white pixel at `point` |
| 46 | //! EpdColor::Black => {} // draw black pixel at `point` |
| 47 | //! EpdColor::Red => {} // draw red pixel at `point` |
| 48 | //! } |
| 49 | //! } |
| 50 | //! |
| 51 | //! Ok(()) |
| 52 | //! } |
| 53 | //! } |
| 54 | //! |
| 55 | //! impl OriginDimensions for EpdDisplay { |
| 56 | //! fn size(&self) -> Size { |
| 57 | //! Size::new(300, 300) |
| 58 | //! } |
| 59 | //! } |
| 60 | //! |
| 61 | //! let mut display = EpdDisplay {}; |
| 62 | //! |
| 63 | //! Rectangle::new(Point::new(0, 0), Size::new(100, 100)) |
| 64 | //! .into_styled(PrimitiveStyle::with_fill(EpdColor::White)) |
| 65 | //! .draw(&mut display)?; |
| 66 | //! |
| 67 | //! Rectangle::new(Point::new(100, 0), Size::new(100, 100)) |
| 68 | //! .into_styled(PrimitiveStyle::with_fill(EpdColor::Black)) |
| 69 | //! .draw(&mut display)?; |
| 70 | //! |
| 71 | //! Rectangle::new(Point::new(200, 0), Size::new(100, 100)) |
| 72 | //! .into_styled(PrimitiveStyle::with_fill(EpdColor::Red)) |
| 73 | //! .draw(&mut display)?; |
| 74 | //! # Ok::<(), core::convert::Infallible>(()) |
| 75 | //! ``` |
| 76 | //! |
| 77 | //! The implementation of the [`DrawTarget`] trait uses a `match` statement to |
| 78 | //! draw the specified color and doesn't depend on the raw data conversions, |
| 79 | //! see the [`raw` module] documentation for an example that uses this feature. |
| 80 | //! |
| 81 | //! [`DrawTarget`]: super::draw_target::DrawTarget |
| 82 | //! [`Raw`]: PixelColor::Raw |
| 83 | //! [`raw` module]: raw |
| 84 | |
| 85 | mod binary_color; |
| 86 | mod conversion; |
| 87 | mod gray_color; |
| 88 | pub mod raw; |
| 89 | mod rgb_color; |
| 90 | mod web_colors; |
| 91 | |
| 92 | pub use binary_color::*; |
| 93 | pub use gray_color::*; |
| 94 | use raw::RawData; |
| 95 | pub use rgb_color::*; |
| 96 | pub use web_colors::WebColors; |
| 97 | |
| 98 | /// Pixel color trait. |
| 99 | /// |
| 100 | /// This trait is used to represent types that can be used in drawing methods. |
| 101 | /// |
| 102 | /// See the [module-level documentation] for more details. |
| 103 | /// |
| 104 | /// [module-level documentation]: self |
| 105 | pub trait PixelColor: Copy + PartialEq { |
| 106 | /// Raw data type. |
| 107 | /// |
| 108 | /// Specifies the raw storage type that can be used to represent this color. |
| 109 | /// |
| 110 | /// See the [`raw` module documentation] for more details. |
| 111 | /// |
| 112 | /// [`raw` module documentation]: raw |
| 113 | type Raw: RawData; |
| 114 | } |
| 115 | |
| 116 | /// Convert a [`PixelColor`] into its underlying storage type |
| 117 | /// |
| 118 | /// This trait provides the `into_storage` method for implementors of [`PixelColor`]. This method |
| 119 | /// exposes the underlying storage value of a pixel color type. |
| 120 | /// |
| 121 | /// # Examples |
| 122 | /// |
| 123 | /// ## Get the `u16` representing an `Rgb565` color |
| 124 | /// |
| 125 | /// This example converts an [`Rgb565`] color into its underlying `u16` representation. |
| 126 | /// |
| 127 | /// ```rust |
| 128 | /// use embedded_graphics::{pixelcolor::Rgb565, prelude::*}; |
| 129 | /// |
| 130 | /// let color = Rgb565::new(0x1f, 0x00, 0x0a); |
| 131 | /// |
| 132 | /// let raw = color.into_storage(); |
| 133 | /// |
| 134 | /// assert_eq!(raw, 0b11111_000000_01010u16); |
| 135 | /// ``` |
| 136 | /// |
| 137 | pub trait IntoStorage { |
| 138 | /// The underlying storage type for the pixel color |
| 139 | type Storage; |
| 140 | |
| 141 | /// Convert the `PixelColor` into its raw storage form |
| 142 | fn into_storage(self) -> Self::Storage; |
| 143 | } |
| 144 | |
| 145 | impl<C> IntoStorage for C |
| 146 | where |
| 147 | C: PixelColor, |
| 148 | C::Raw: From<C>, |
| 149 | { |
| 150 | type Storage = <<C as PixelColor>::Raw as RawData>::Storage; |
| 151 | |
| 152 | fn into_storage(self) -> Self::Storage { |
| 153 | C::Raw::from(self).into_inner() |
| 154 | } |
| 155 | } |
| 156 | |