--- a/rust/mapgen/src/theme.rs Tue Jun 04 23:19:18 2019 +0300
+++ b/rust/mapgen/src/theme.rs Tue Jun 04 22:34:42 2019 +0200
@@ -1,194 +1,194 @@
-use png::{ColorType, Decoder, DecodingError};
-use std::{
- fs::{read_dir, File},
- io,
- io::BufReader,
- path::Path,
- slice::{from_raw_parts, from_raw_parts_mut},
-};
-
-use integral_geometry::Size;
-use vec2d::Vec2D;
-
-pub struct ThemeSprite {
- pixels: Vec2D<u32>,
-}
-
-impl ThemeSprite {
- #[inline]
- pub fn size(&self) -> Size {
- self.pixels.size()
- }
-
- #[inline]
- pub fn width(&self) -> usize {
- self.size().width
- }
-
- #[inline]
- pub fn height(&self) -> usize {
- self.size().height
- }
-
- #[inline]
- pub fn rows(&self) -> impl DoubleEndedIterator<Item = &[u32]> {
- self.pixels.rows()
- }
-
- #[inline]
- pub fn get_row(&self, index: usize) -> &[u32] {
- &self.pixels[index]
- }
-
- #[inline]
- pub fn get_pixel(&self, x: usize, y: usize) -> u32 {
- self.pixels[y][x]
- }
-
- pub fn to_transposed(&self) -> ThemeSprite {
- let size = self.size().transpose();
- let mut pixels = Vec2D::new(size, 0u32);
- for (y, row) in self.pixels.rows().enumerate() {
- for (x, v) in row.iter().enumerate() {
- pixels[x][y] = *v;
- }
- }
- ThemeSprite { pixels }
- }
-
- pub fn to_tiled(&self) -> TiledSprite {
- let size = self.size();
- assert!(size.is_power_of_two());
- let tile_width_shift = size.width.trailing_zeros() as usize + 2;
- let mut pixels = vec![0u32; size.area()];
-
- for (y, row) in self.pixels.rows().enumerate() {
- for (x, v) in row.iter().enumerate() {
- pixels[get_tiled_index(x, y, tile_width_shift)] = *v;
- }
- }
-
- TiledSprite {
- tile_width_shift,
- size,
- pixels,
- }
- }
-}
-
-#[inline]
-fn get_tiled_index(x: usize, y: usize, tile_width_shift: usize) -> usize {
- (((y >> 2) << tile_width_shift) + ((x >> 2) << 4)) + ((y & 0b11) << 2) + (x & 0b11)
-}
-
-pub struct TiledSprite {
- tile_width_shift: usize,
- size: Size,
- pixels: Vec<u32>,
-}
-
-impl TiledSprite {
- #[inline]
- pub fn size(&self) -> Size {
- self.size
- }
-
- #[inline]
- pub fn width(&self) -> usize {
- self.size().width
- }
-
- #[inline]
- pub fn height(&self) -> usize {
- self.size().height
- }
-
- #[inline]
- pub fn get_pixel(&self, x: usize, y: usize) -> u32 {
- self.pixels[get_tiled_index(x, y, self.tile_width_shift)]
- }
-}
-
-pub struct Theme {
- land_texture: Option<ThemeSprite>,
- border_texture: Option<ThemeSprite>,
-}
-
-impl Theme {
- pub fn land_texture(&self) -> Option<&ThemeSprite> {
- self.land_texture.as_ref()
- }
-
- pub fn border_texture(&self) -> Option<&ThemeSprite> {
- self.border_texture.as_ref()
- }
-}
-
-#[derive(Debug)]
-pub enum ThemeLoadError {
- File(io::Error),
- Decoding(DecodingError),
- Format(String),
-}
-
-impl From<io::Error> for ThemeLoadError {
- fn from(e: io::Error) -> Self {
- ThemeLoadError::File(e)
- }
-}
-
-impl From<DecodingError> for ThemeLoadError {
- fn from(e: DecodingError) -> Self {
- ThemeLoadError::Decoding(e)
- }
-}
-
-impl Theme {
- pub fn new() -> Self {
- Theme {
- land_texture: None,
- border_texture: None,
- }
- }
-
- pub fn load(path: &Path) -> Result<Theme, ThemeLoadError> {
- let mut theme = Self::new();
-
- for entry in read_dir(path)? {
- let file = entry?;
- if file.file_name() == "LandTex.png" {
- theme.land_texture = Some(load_sprite(&file.path())?)
- } else if file.file_name() == "Border.png" {
- theme.border_texture = Some(load_sprite(&file.path())?)
- }
- }
-
- Ok(theme)
- }
-}
-
-fn load_sprite(path: &Path) -> Result<ThemeSprite, ThemeLoadError> {
- let decoder = Decoder::new(BufReader::new(File::open(path)?));
- let (info, mut reader) = decoder.read_info()?;
-
- if info.color_type != ColorType::RGBA {
- return Err(ThemeLoadError::Format(format!(
- "Unexpected format: {:?}",
- info.color_type
- )));
- }
- let size = Size::new(info.width as usize, info.height as usize);
-
- let mut pixels: Vec2D<u32> = Vec2D::new(size, 0);
- reader.next_frame(slice_u32_to_u8_mut(pixels.as_mut_slice()))?;
-
- Ok(ThemeSprite { pixels })
-}
-
-pub fn slice_u32_to_u8(slice_u32: &[u32]) -> &[u8] {
- unsafe { from_raw_parts::<u8>(slice_u32.as_ptr() as *const u8, slice_u32.len() * 4) }
-}
-
-pub fn slice_u32_to_u8_mut(slice_u32: &mut [u32]) -> &mut [u8] {
- unsafe { from_raw_parts_mut::<u8>(slice_u32.as_mut_ptr() as *mut u8, slice_u32.len() * 4) }
-}
+use png::{ColorType, Decoder, DecodingError};
+use std::{
+ fs::{read_dir, File},
+ io,
+ io::BufReader,
+ path::Path,
+ slice::{from_raw_parts, from_raw_parts_mut},
+};
+
+use integral_geometry::Size;
+use vec2d::Vec2D;
+
+pub struct ThemeSprite {
+ pixels: Vec2D<u32>,
+}
+
+impl ThemeSprite {
+ #[inline]
+ pub fn size(&self) -> Size {
+ self.pixels.size()
+ }
+
+ #[inline]
+ pub fn width(&self) -> usize {
+ self.size().width
+ }
+
+ #[inline]
+ pub fn height(&self) -> usize {
+ self.size().height
+ }
+
+ #[inline]
+ pub fn rows(&self) -> impl DoubleEndedIterator<Item = &[u32]> {
+ self.pixels.rows()
+ }
+
+ #[inline]
+ pub fn get_row(&self, index: usize) -> &[u32] {
+ &self.pixels[index]
+ }
+
+ #[inline]
+ pub fn get_pixel(&self, x: usize, y: usize) -> u32 {
+ self.pixels[y][x]
+ }
+
+ pub fn to_transposed(&self) -> ThemeSprite {
+ let size = self.size().transpose();
+ let mut pixels = Vec2D::new(size, 0u32);
+ for (y, row) in self.pixels.rows().enumerate() {
+ for (x, v) in row.iter().enumerate() {
+ pixels[x][y] = *v;
+ }
+ }
+ ThemeSprite { pixels }
+ }
+
+ pub fn to_tiled(&self) -> TiledSprite {
+ let size = self.size();
+ assert!(size.is_power_of_two());
+ let tile_width_shift = size.width.trailing_zeros() as usize + 2;
+ let mut pixels = vec![0u32; size.area()];
+
+ for (y, row) in self.pixels.rows().enumerate() {
+ for (x, v) in row.iter().enumerate() {
+ pixels[get_tiled_index(x, y, tile_width_shift)] = *v;
+ }
+ }
+
+ TiledSprite {
+ tile_width_shift,
+ size,
+ pixels,
+ }
+ }
+}
+
+#[inline]
+fn get_tiled_index(x: usize, y: usize, tile_width_shift: usize) -> usize {
+ (((y >> 2) << tile_width_shift) + ((x >> 2) << 4)) + ((y & 0b11) << 2) + (x & 0b11)
+}
+
+pub struct TiledSprite {
+ tile_width_shift: usize,
+ size: Size,
+ pixels: Vec<u32>,
+}
+
+impl TiledSprite {
+ #[inline]
+ pub fn size(&self) -> Size {
+ self.size
+ }
+
+ #[inline]
+ pub fn width(&self) -> usize {
+ self.size().width
+ }
+
+ #[inline]
+ pub fn height(&self) -> usize {
+ self.size().height
+ }
+
+ #[inline]
+ pub fn get_pixel(&self, x: usize, y: usize) -> u32 {
+ self.pixels[get_tiled_index(x, y, self.tile_width_shift)]
+ }
+}
+
+pub struct Theme {
+ land_texture: Option<ThemeSprite>,
+ border_texture: Option<ThemeSprite>,
+}
+
+impl Theme {
+ pub fn land_texture(&self) -> Option<&ThemeSprite> {
+ self.land_texture.as_ref()
+ }
+
+ pub fn border_texture(&self) -> Option<&ThemeSprite> {
+ self.border_texture.as_ref()
+ }
+}
+
+#[derive(Debug)]
+pub enum ThemeLoadError {
+ File(io::Error),
+ Decoding(DecodingError),
+ Format(String),
+}
+
+impl From<io::Error> for ThemeLoadError {
+ fn from(e: io::Error) -> Self {
+ ThemeLoadError::File(e)
+ }
+}
+
+impl From<DecodingError> for ThemeLoadError {
+ fn from(e: DecodingError) -> Self {
+ ThemeLoadError::Decoding(e)
+ }
+}
+
+impl Theme {
+ pub fn new() -> Self {
+ Theme {
+ land_texture: None,
+ border_texture: None,
+ }
+ }
+
+ pub fn load(path: &Path) -> Result<Theme, ThemeLoadError> {
+ let mut theme = Self::new();
+
+ for entry in read_dir(path)? {
+ let file = entry?;
+ if file.file_name() == "LandTex.png" {
+ theme.land_texture = Some(load_sprite(&file.path())?)
+ } else if file.file_name() == "Border.png" {
+ theme.border_texture = Some(load_sprite(&file.path())?)
+ }
+ }
+
+ Ok(theme)
+ }
+}
+
+fn load_sprite(path: &Path) -> Result<ThemeSprite, ThemeLoadError> {
+ let decoder = Decoder::new(BufReader::new(File::open(path)?));
+ let (info, mut reader) = decoder.read_info()?;
+
+ if info.color_type != ColorType::RGBA {
+ return Err(ThemeLoadError::Format(format!(
+ "Unexpected format: {:?}",
+ info.color_type
+ )));
+ }
+ let size = Size::new(info.width as usize, info.height as usize);
+
+ let mut pixels: Vec2D<u32> = Vec2D::new(size, 0);
+ reader.next_frame(slice_u32_to_u8_mut(pixels.as_mut_slice()))?;
+
+ Ok(ThemeSprite { pixels })
+}
+
+pub fn slice_u32_to_u8(slice_u32: &[u32]) -> &[u8] {
+ unsafe { from_raw_parts::<u8>(slice_u32.as_ptr() as *const u8, slice_u32.len() * 4) }
+}
+
+pub fn slice_u32_to_u8_mut(slice_u32: &mut [u32]) -> &mut [u8] {
+ unsafe { from_raw_parts_mut::<u8>(slice_u32.as_mut_ptr() as *mut u8, slice_u32.len() * 4) }
+}