rust/mapgen/src/theme.rs
changeset 14156 3c8a33ba06ba
child 14161 74ca70cb753d
equal deleted inserted replaced
14155:6205a5230d23 14156:3c8a33ba06ba
       
     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