|
1 use std::{ |
|
2 slice, |
|
3 io, |
|
4 io::BufReader, |
|
5 fs::{File, read_dir}, |
|
6 path::Path |
|
7 }; |
|
8 use png::{ |
|
9 BitDepth, |
|
10 ColorType, |
|
11 Decoder, |
|
12 DecodingError |
|
13 }; |
|
14 |
|
15 use integral_geometry::{ |
|
16 Rect, Size |
|
17 }; |
|
18 |
|
19 pub struct ThemeSprite { |
|
20 bounds: Size, |
|
21 pixels: Vec<u32> |
|
22 } |
|
23 |
|
24 pub struct Theme { |
|
25 land_texture: Option<ThemeSprite> |
|
26 } |
|
27 |
|
28 pub enum ThemeLoadError { |
|
29 File(io::Error), |
|
30 Decoding(DecodingError), |
|
31 Format(String) |
|
32 } |
|
33 |
|
34 impl From<io::Error> for ThemeLoadError { |
|
35 fn from(e: io::Error) -> Self { |
|
36 ThemeLoadError::File(e) |
|
37 } |
|
38 } |
|
39 |
|
40 impl From<DecodingError> for ThemeLoadError { |
|
41 fn from(e: DecodingError) -> Self { |
|
42 ThemeLoadError::Decoding(e) |
|
43 } |
|
44 } |
|
45 |
|
46 impl Theme { |
|
47 pub fn new() -> Self { |
|
48 Theme { |
|
49 land_texture: None |
|
50 } |
|
51 } |
|
52 |
|
53 pub fn load(path: &Path) -> Result<Theme, ThemeLoadError> { |
|
54 let mut theme = Self::new(); |
|
55 |
|
56 for entry in read_dir(path)? { |
|
57 let file = entry?; |
|
58 if file.file_name() == "LandTex.png" { |
|
59 let buffer = BufReader::new(File::create(file.path())?); |
|
60 let decoder = Decoder::new(buffer); |
|
61 let (info, mut reader) = decoder.read_info()?; |
|
62 |
|
63 if info.color_type != ColorType::RGBA { |
|
64 return Err(ThemeLoadError::Format( |
|
65 format!("Unexpected format: {:?}", info.color_type))); |
|
66 } |
|
67 let size = Size::new(info.width as usize, info.height as usize); |
|
68 |
|
69 let mut buffer: Vec<u32> = Vec::with_capacity(size.area()); |
|
70 let mut slice_u32 = buffer.as_mut_slice(); |
|
71 let mut slice_u8 = unsafe { |
|
72 slice::from_raw_parts_mut::<u8>( |
|
73 slice.as_mut_ptr() as *mut u8, |
|
74 slice.len() / 4 |
|
75 ) |
|
76 }; |
|
77 reader.next_frame(slice_u8); |
|
78 |
|
79 let land_tex = ThemeSprite { |
|
80 bounds: size, |
|
81 pixels: buffer |
|
82 }; |
|
83 theme.land_texture = Some(land_tex) |
|
84 } |
|
85 } |
|
86 |
|
87 Ok(theme) |
|
88 } |
|
89 } |
|
90 |
|
91 |