xref: /DragonOS/kernel/src/driver/video/fbdev/base/render_helper.rs (revision 1ea2daad8121b77ed704e6d7c3a09f478147441d)
1 use core::slice::Iter;
2 
3 pub struct BitIter<'a> {
4     fgcolor: u32,
5     bkcolor: u32,
6     _color_pattern: EndianPattern,
7     _dst_pattern: EndianPattern,
8     src: Iter<'a, u8>,
9     read_mask: u8,
10     byte_per_pixel: u32,
11     buffer: u32,
12     current: u8,
13     left_byte: u32,
14     done: bool,
15     consumed_bit: u32,
16     image_width: u32,
17 }
18 
19 impl<'a> BitIter<'a> {
20     pub fn new(
21         fgcolor: u32,
22         bkcolor: u32,
23         dst_pattern: EndianPattern,
24         color_pattern: EndianPattern,
25         byte_per_pixel: u32,
26         src: Iter<'a, u8>,
27         image_width: u32,
28     ) -> Self {
29         let mut fgcolor = fgcolor;
30         let mut bkcolor = bkcolor;
31         if dst_pattern != color_pattern {
32             fgcolor = Self::reverse(fgcolor, byte_per_pixel);
33             bkcolor = Self::reverse(bkcolor, byte_per_pixel);
34         }
35 
36         let mut ans = Self {
37             fgcolor,
38             bkcolor,
39             _color_pattern: color_pattern,
40             _dst_pattern: dst_pattern,
41             src,
42             read_mask: 0b10000000,
43             byte_per_pixel,
44             buffer: 0,
45             current: 0,
46             left_byte: 0,
47             done: false,
48             consumed_bit: 0,
49             image_width,
50         };
51         ans.current = *ans.src.next().unwrap();
52         return ans;
53     }
54 
55     fn reverse(num: u32, byte_per_pixel: u32) -> u32 {
56         let mask = 0x000000ff;
57         let mut ans = 0;
58         let mut num = num;
59         for _ in 0..3 {
60             ans |= mask & num;
61             ans <<= 8;
62             num >>= 8;
63         }
64         ans |= mask & num;
65         ans >>= (4 - byte_per_pixel) * 8;
66         return ans;
67     }
68 
69     fn move_mask(&mut self) -> bool {
70         self.consumed_bit += 1;
71         self.read_mask >>= 1;
72         if self.read_mask == 0b000000000 {
73             self.read_mask = 0b10000000;
74             self.current = match self.src.next() {
75                 Some(x) => *x,
76                 None => {
77                     return false;
78                 }
79             };
80             return true;
81         } else {
82             return true;
83         }
84     }
85 
86     fn full_buffer(&mut self) -> Result<PixelLineStatus, PixelLineStatus> {
87         let same_endian = if self._dst_pattern == self._color_pattern {
88             1
89         } else {
90             -1
91         };
92         let mut color = self.read_bit() << (self.left_byte << 3);
93         let mut buffer_pointer = if self._dst_pattern == self._color_pattern {
94             0
95         } else {
96             3
97         };
98         let mask = 0x000000ff << ((self.byte_per_pixel - 1) << 3);
99         let mut temp;
100         // while buffer_pointer >= 0 && buffer_pointer <= 3 {
101         while (0..=3).contains(&buffer_pointer) {
102             if self.consumed_bit >= self.image_width {
103                 self.consumed_bit = 0;
104                 return Ok(PixelLineStatus::Full(self.buffer));
105             }
106             temp = color & mask;
107             color <<= 8;
108             temp <<= (4 - self.byte_per_pixel) * 8;
109             temp >>= buffer_pointer * 8;
110             self.buffer |= temp;
111             buffer_pointer += same_endian;
112             self.left_byte += 1;
113             if self.left_byte >= self.byte_per_pixel {
114                 self.left_byte = 0;
115                 if !self.move_mask() {
116                     return Err(PixelLineStatus::Full(self.buffer));
117                 }
118                 color = self.read_bit();
119             }
120         }
121         if self.consumed_bit >= self.image_width {
122             self.consumed_bit = 0;
123             return Ok(PixelLineStatus::Full(self.buffer));
124         }
125         return Ok(PixelLineStatus::NotFull(self.buffer));
126     }
127 
128     fn read_bit(&self) -> u32 {
129         match self.read_mask & self.current {
130             0 => self.bkcolor,
131             _ => self.fgcolor,
132         }
133     }
134 }
135 
136 impl Iterator for BitIter<'_> {
137     type Item = (u32, bool);
138     fn next(&mut self) -> Option<Self::Item> {
139         if self.done {
140             return None;
141         }
142         match self.full_buffer() {
143             Ok(x) => {
144                 self.buffer = 0;
145                 return Some(x.unwarp());
146             }
147             Err(x) => {
148                 self.done = true;
149                 return Some(x.unwarp());
150             }
151         }
152     }
153 }
154 #[derive(PartialEq, PartialOrd)]
155 pub enum EndianPattern {
156     Big,
157     Little,
158 }
159 
160 pub enum PixelLineStatus {
161     Full(u32),
162     NotFull(u32),
163 }
164 
165 impl PixelLineStatus {
166     pub fn unwarp(self) -> (u32, bool) {
167         match self {
168             PixelLineStatus::Full(x) => (x, true),
169             PixelLineStatus::NotFull(x) => (x, false),
170         }
171     }
172 }
173