cranpose_render_common/
rgb565.rs1use crate::byte_blend::{blend_byte_pixel, mix_byte};
5
6#[repr(transparent)]
8#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, bytemuck::Pod, bytemuck::Zeroable)]
9pub struct Rgb565Le(pub u16);
10
11#[repr(transparent)]
14#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, bytemuck::Pod, bytemuck::Zeroable)]
15pub struct Rgb565Be(pub u16);
16
17#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19pub enum Rgb565Order {
20 LittleEndian,
22 BigEndian,
24}
25
26pub trait Rgb565: Copy {
28 fn from_rgb(bytes: [u8; 4]) -> Self;
31
32 fn to_rgba(self) -> [u8; 4];
35}
36
37fn pack(bytes: [u8; 4]) -> u16 {
38 (u16::from(bytes[0] >> 3) << 11) | (u16::from(bytes[1] >> 2) << 5) | u16::from(bytes[2] >> 3)
39}
40
41fn unpack(value: u16) -> [u8; 4] {
42 let red = (value >> 11) as u8;
43 let green = ((value >> 5) & 0x3F) as u8;
44 let blue = (value & 0x1F) as u8;
45 [
46 (red << 3) | (red >> 2),
47 (green << 2) | (green >> 4),
48 (blue << 3) | (blue >> 2),
49 255,
50 ]
51}
52
53impl Rgb565 for Rgb565Le {
54 fn from_rgb(bytes: [u8; 4]) -> Self {
55 Self(pack(bytes).to_le())
56 }
57
58 fn to_rgba(self) -> [u8; 4] {
59 unpack(u16::from_le(self.0))
60 }
61}
62
63impl Rgb565 for Rgb565Be {
64 fn from_rgb(bytes: [u8; 4]) -> Self {
65 Self(pack(bytes).to_be())
66 }
67
68 fn to_rgba(self) -> [u8; 4] {
69 unpack(u16::from_be(self.0))
70 }
71}
72
73pub trait GlyphPixel: Copy {
75 fn blend_bytes(&mut self, src: [u8; 4]);
77}
78
79impl GlyphPixel for [u8; 4] {
80 fn blend_bytes(&mut self, src: [u8; 4]) {
81 blend_byte_pixel(self, src);
82 }
83}
84
85#[inline]
88fn blend_bytes_565<P: Rgb565>(pixel: &mut P, src: [u8; 4]) {
89 match src[3] {
90 0 => {}
91 255 => *pixel = P::from_rgb(src),
92 alpha => {
93 let under = pixel.to_rgba();
94 let alpha = u32::from(alpha);
95 *pixel = P::from_rgb([
96 mix_byte(src[0], under[0], alpha),
97 mix_byte(src[1], under[1], alpha),
98 mix_byte(src[2], under[2], alpha),
99 255,
100 ]);
101 }
102 }
103}
104
105impl GlyphPixel for Rgb565Le {
106 #[inline]
107 fn blend_bytes(&mut self, src: [u8; 4]) {
108 blend_bytes_565(self, src);
109 }
110}
111
112impl GlyphPixel for Rgb565Be {
113 #[inline]
114 fn blend_bytes(&mut self, src: [u8; 4]) {
115 blend_bytes_565(self, src);
116 }
117}
118
119#[cfg(test)]
120#[path = "tests/rgb565_tests.rs"]
121mod tests;