mindustry logic execution, map- and schematic- parsing and rendering
rework imageholder and use dynimages
| -rw-r--r-- | mindus/Cargo.toml | 5 | ||||
| -rw-r--r-- | mindus/build.rs | 4 | ||||
| -rw-r--r-- | mindus/src/block/distribution.rs | 3 | ||||
| -rw-r--r-- | mindus/src/block/logic.rs | 15 | ||||
| -rw-r--r-- | mindus/src/block/mod.rs | 18 | ||||
| -rw-r--r-- | mindus/src/data/map.rs | 20 | ||||
| -rw-r--r-- | mindus/src/data/renderer.rs | 83 | ||||
| -rw-r--r-- | mindus/src/data/schematic.rs | 4 | ||||
| -rw-r--r-- | mindus/src/lib.rs | 1 | ||||
| -rw-r--r-- | mindus/src/unit.rs | 2 | ||||
| -rw-r--r-- | mindus/src/utils/image/holder.rs | 140 | ||||
| -rw-r--r-- | mindus/src/utils/image/mod.rs | 6 | ||||
| -rw-r--r-- | mindus/src/utils/mod.rs | 2 |
13 files changed, 109 insertions, 194 deletions
diff --git a/mindus/Cargo.toml b/mindus/Cargo.toml index 093008d..c69b6b8 100644 --- a/mindus/Cargo.toml +++ b/mindus/Cargo.toml @@ -29,11 +29,12 @@ fimg = { version = "0.4.33", features = [ "scale", "blur", "save", -], default-features = false } +], default-features = false, path = "../../fimg" } atools = "0.1.6" either = "1.15.0" implicit-fn = "0.1.0" lower = "0.2.0" +car = "0.1.3" [features] bin = ["fimg/save"] @@ -45,7 +46,7 @@ fimg = { version = "0.4.33", features = [ "scale", "blur", "save", -], default-features = false } +], default-features = false, path = "../../fimg" } walkdir = "2" [[bin]] diff --git a/mindus/build.rs b/mindus/build.rs index b2dc4a2..3494c0d 100644 --- a/mindus/build.rs +++ b/mindus/build.rs @@ -1,4 +1,3 @@ -#![feature(let_chains)] use fimg::DynImage; use std::fs::File; use std::io::Write as _; @@ -81,7 +80,7 @@ fn main() { { continue; } - let rgb = path.components().any(|c| c.as_os_str() == "floors"); + // let rgb = path.components().any(|c| c.as_os_str() == "floors"); let env = path.components().any(|c| c.as_os_str() == "environment"); let path = kebab2bigsnek( path.with_extension("") @@ -136,6 +135,7 @@ fn main() { } else { p.scale::<fimg::scale::Nearest>(mx / $scale, my / $scale) }; + let rgb = env && matches!(p, DynImage::Rgb(_)); let x = new.width(); let y = new.height(); if rgb { diff --git a/mindus/src/block/distribution.rs b/mindus/src/block/distribution.rs index fd7064e..b2c67f1 100644 --- a/mindus/src/block/distribution.rs +++ b/mindus/src/block/distribution.rs @@ -208,7 +208,8 @@ impl BlockLogic for ItemBlock { unsafe { p.overlay(top.tint(item.color())) }; if name == "duct-unloader" { unsafe { - p.overlay(&load!("duct-unloader-arrows", s).rotate(rot.rotated(false).count())); + let mut x = load!("duct-unloader-arrows", s); + p.overlay(&*x.rotate(rot.rotated(false).count())); } } return p; diff --git a/mindus/src/block/logic.rs b/mindus/src/block/logic.rs index 6e4a110..126dfcd 100644 --- a/mindus/src/block/logic.rs +++ b/mindus/src/block/logic.rs @@ -4,7 +4,7 @@ use std::string::FromUtf8Error; use crate::block::simple::*; use crate::data::dynamic::DynType; -use crate::{block::*, Serializable}; +use crate::{Serializable, block::*}; use crate::data::{self, CompressError, DataRead, DataWrite}; @@ -143,7 +143,7 @@ impl BlockLogic for CanvasBlock { (s * self.size as u32) - offset * 2, ); let mut borders = load!("canvas", s); - unsafe { borders.overlay_at(&ImageHolder::from(img), offset, offset) }; + unsafe { borders.overlay_at(&img, offset, offset) }; return borders; } @@ -153,7 +153,7 @@ impl BlockLogic for CanvasBlock { (*r, *g, *b) = PALETTE[0]; *a = 255; } - ImageHolder::from(def) + unsafe { def.mapped(crate::utils::Cow::Own) } } /// format: @@ -601,14 +601,13 @@ make_simple!(TileableDisplay, |_, use std::simd::prelude::*; let mut b = load!("tile-logic-display", s); unsafe { - b.overlay(&ImageHolder::from( - BITMASKS[u8x8::from_array( + b.overlay( + &BITMASKS[u8x8::from_array( swizzled.map(|x| x.is_some_and(|x| x.0.name() == "tile-logic-display") as u8), ) .simd_eq(u8x8::splat(1)) - .to_bitmask() as usize][s as usize] - .copy(), - )) + .to_bitmask() as usize][s as usize], + ) }; b }); diff --git a/mindus/src/block/mod.rs b/mindus/src/block/mod.rs index 05fe780..6ebf7a6 100644 --- a/mindus/src/block/mod.rs +++ b/mindus/src/block/mod.rs @@ -2,6 +2,7 @@ //! //! different block types are organized into modules use bobbin_bits::U4::{self, B0000, B0001, B0010, B0100, B1000}; +use fimg::DynImage; use std::error::Error; use std::fmt; @@ -10,6 +11,7 @@ use crate::data::map::Build; use crate::data::{self, CompressError, renderer::*}; use crate::data::{DataRead, GridPos, ReadError as DataReadError}; use crate::item::storage::ItemStorage; +use crate::utils::Cow; macro_rules! mods { ($($mod:ident)*) => { @@ -304,7 +306,7 @@ impl SerializeError { /// a block. put it in stuff! pub struct Block { - image: Option<[Image<&'static [u8], 4>; 3]>, + image: Option<[DynImage<&'static [u8]>; 3]>, name: &'static str, logic: BlockLogicEnum, } @@ -322,7 +324,7 @@ impl Block { pub(crate) const fn new( name: &'static str, logic: BlockLogicEnum, - image: Option<[Image<&'static [u8], 4>; 3]>, + image: Option<[DynImage<&'static [u8]>; 3]>, ) -> Self { Self { image, name, logic } } @@ -365,11 +367,11 @@ impl Block { context: Option<&RenderingContext>, rot: Rotation, scale: Scale, - ) -> ImageHolder<4> { + ) -> DynImage<Cow> { if let Some(imgs) = &self.image { - return ImageHolder::from((imgs[scale as usize]).copy()); + return unsafe { imgs[scale as usize].mapped(Cow::Ref) }; } - self.logic.draw(self.name, state, context, rot, scale) + DynImage::Rgba(self.logic.draw(self.name, state, context, rot, scale)) } /// size. @@ -617,18 +619,18 @@ macro_rules! make_register { }; (impl $field: literal -> $logic: expr) => { paste::paste! { pub static [<$field:snake:upper>]: Block = Block::new( - $field, <crate::block::BlockLogicEnum as crate::block::ConstFrom<_>>::fro($logic), Some(crate::data::renderer::load!($field)) + $field, <crate::block::BlockLogicEnum as crate::block::ConstFrom<_>>::fro($logic), Some(car::map!(crate::data::renderer::load!($field), DynImage::from)) ); } }; (impl $field: literal : $size: literal) => { paste::paste! { pub static [<$field:snake:upper>]: Block = Block::new( - $field, BlockLogicEnum::BasicBlock(BasicBlock::new($size, true, &[])), Some(crate::data::renderer::load!($field)) + $field, BlockLogicEnum::BasicBlock(BasicBlock::new($size, true, &[])), Some(car::map!(crate::data::renderer::load!($field), DynImage::from)) ); } }; // floors (impl $field: literal > $size: literal) => { paste::paste! { pub static [<$field:snake:upper>]: Block = Block::new( - $field, BlockLogicEnum::BasicBlock(BasicBlock::new($size, true, &[])), Some(crate::data::renderer::load!("empty4")) + $field, BlockLogicEnum::BasicBlock(BasicBlock::new($size, true, &[])), Some(car::map!(crate::data::renderer::load!("empty4"), DynImage::from)) ); } }; } diff --git a/mindus/src/data/map.rs b/mindus/src/data/map.rs index 68b5d3b..6550ced 100644 --- a/mindus/src/data/map.rs +++ b/mindus/src/data/map.rs @@ -111,7 +111,7 @@ pub struct Tile { macro_rules! lo { ($v:expr => [$(|)? $($k:literal $(|)?)+], $scale: ident) => { paste::paste! { match $v { - $(BlockEnum::[<$k:camel>] => Some(load!(raw $k, $scale)),)+ + $(BlockEnum::[<$k:camel>] => Some(DynImage::from(load!(raw $k, $scale))),)+ _ => None, } } }; @@ -119,7 +119,7 @@ macro_rules! lo { #[inline] pub(crate) fn ore(ore: BlockEnum, s: Scale) -> DynImage<&'static [u8]> { - lo!(ore => ["ore-copper" | "ore-beryllium" | "ore-lead" | "ore-scrap" | "ore-coal" | "ore-thorium" | "ore-titanium" | "ore-tungsten" | "pebbles" | "tendrils" | "ore-wall-tungsten" | "ore-wall-beryllium" | "ore-wall-thorium" | "spawn" | "ore-crystal-thorium"], s).map(DynImage::Rgba).unwrap_or_else(|| floor(ore, s)) + lo!(ore => ["ore-copper" | "ore-beryllium" | "ore-lead" | "ore-scrap" | "ore-coal" | "ore-thorium" | "ore-titanium" | "ore-tungsten" | "pebbles" | "tendrils" | "ore-wall-tungsten" | "ore-wall-beryllium" | "ore-wall-thorium" | "spawn" | "ore-crystal-thorium"], s).unwrap_or_else(|| floor(ore, s)) } #[inline] @@ -127,7 +127,7 @@ pub(crate) fn floor(tile: BlockEnum, s: Scale) -> DynImage<&'static [u8]> { macro_rules! x { ($($x:literal)+) => { paste::paste! { match tile { - $(BlockEnum::[<$x:camel>] => return DynImage::Rgb(load!(raw $x, s)),)+ + $(BlockEnum::[<$x:camel>] => return DynImage::from(load!(raw $x, s)),)+ _ => {} } }}; @@ -168,7 +168,7 @@ pub(crate) fn floor(tile: BlockEnum, s: Scale) -> DynImage<&'static [u8]> { | "red-stone" | "red-stone-vent" | "dense-red-stone" | "carbon-stone" | "carbon-vent" | "crystal-floor" | "crystalline-stone" | "crystalline-vent" - | "empty"], s).map(DynImage::Rgb).unwrap_or_else(|| ore(tile, s)) + | "empty"], s).unwrap_or_else(|| ore(tile, s)) } impl Tile { @@ -230,7 +230,11 @@ impl Tile { /// Draw this tiles build. #[must_use] #[inline] - pub fn build_image(&self, context: Option<&RenderingContext>, s: Scale) -> ImageHolder<4> { + pub fn build_image( + &self, + context: Option<&RenderingContext>, + s: Scale, + ) -> DynImage<image::Cow> { // building covers floore let Some(b) = &self.build else { unreachable!(); @@ -316,7 +320,7 @@ impl Build { } } - fn image(&self, context: Option<&RenderingContext>, s: Scale) -> ImageHolder<4> { + fn image(&self, context: Option<&RenderingContext>, s: Scale) -> DynImage<image::Cow> { self.block .image(self.state.as_ref(), context, self.rotation, s) } @@ -577,8 +581,8 @@ macro_rules! tiles { while i < $count { let floor_id = $me.buff.read_u16()?; let overlay_id = $me.buff.read_u16()?; - let &(mut floor) = $r.get(floor_id as usize).unwrap_or(&BlockEnum::Stone); - let &(mut ore) = $r.get(overlay_id as usize).unwrap_or(&BlockEnum::Air); + let &floor = $r.get(floor_id as usize).unwrap_or(&BlockEnum::Stone); + let &ore = $r.get(overlay_id as usize).unwrap_or(&BlockEnum::Air); yield $w::Tile { floor, ore }; let consecutives = $me.buff.read_u8()? as usize; for _ in 0..consecutives { diff --git a/mindus/src/data/renderer.rs b/mindus/src/data/renderer.rs index 493500c..0452fa7 100644 --- a/mindus/src/data/renderer.rs +++ b/mindus/src/data/renderer.rs @@ -63,11 +63,11 @@ macro_rules! load { } } }; ($name:literal, $scale:expr) => { paste::paste! { - $crate::utils::image::ImageHolder::from(match $scale { + #[allow(unused_unsafe)] unsafe { match $scale { $crate::data::renderer::Scale::Quarter => &$crate::data::renderer::quar::[<$name:snake:upper>], $crate::data::renderer::Scale::Eigth => &$crate::data::renderer::eigh::[<$name:snake:upper>], $crate::data::renderer::Scale::Full => &$crate::data::renderer::full::[<$name:snake:upper>], - }.copy()) + }.mapped($crate::utils::Cow::Ref) } } }; ($name: ident) => { paste::paste! { [$crate::data::renderer::full::[<$name:snake:upper>].copy(), $crate::data::renderer::quar::[<$name:snake:upper>].copy(), $crate::data::renderer::eigh::[<$name:snake:upper>].copy()] @@ -91,11 +91,11 @@ macro_rules! load { (concat $x:literal => $v:ident which is [$($k:literal $(|)?)+], $scale: ident) => { paste::paste! { match $v { $($k => - ImageHolder::from(match $scale { + #[allow(unused_unsafe)] unsafe { (match $scale { $crate::data::renderer::Scale::Quarter => &$crate::data::renderer::quar::[<$k:snake:upper _ $x:snake:upper>], $crate::data::renderer::Scale::Eigth => &$crate::data::renderer::eigh::[<$k:snake:upper _ $x:snake:upper>], $crate::data::renderer::Scale::Full => &$crate::data::renderer::full::[<$k:snake:upper _ $x:snake:upper>], - }.copy()), + }.mapped($crate::utils::Cow::Ref)) }, )+ #[allow(unreachable_patterns)] n => unreachable!("{n:?}"), @@ -137,7 +137,7 @@ impl Renderable for Schematic { * self.width.checked_sub(self.height).unwrap_or(0) as u32 + 2; let mut bg = unsafe { - load!("metal-floor", scale).borrow().repeated( + load!("metal-floor", scale).repeated( scale * (self.width + x_fac as usize) as u32, scale * (self.height + y_fac as usize) as u32, ) @@ -161,13 +161,11 @@ impl Renderable for Schematic { let y = self.height as u32 - y as u32 - ((tile.block.get_size() / 2) + 1) as u32; unsafe { canvas.as_mut().overlay_at( - &tile - .image( - ctx.as_ref(), - tile.get_rotation().unwrap_or(Rotation::Up), - scale, - ) - .borrow(), + &tile.image( + ctx.as_ref(), + tile.get_rotation().unwrap_or(Rotation::Up), + scale, + ), scale * (x + x_fac / 2), scale * (y + y_fac / 2), ) @@ -217,7 +215,8 @@ impl Renderable for Schematic { */ if relative.1 != 0 { // continue; - bridge = bridge.swap_wh(); + bridge = + Image::build(bridge.height(), bridge.width()).buf(bridge.take_buffer()); } let arrow = load!(concat "arrow" => n which is ["bridge-conveyor"| "bridge-conduit" | "phase-conveyor" | "phase-conduit" | "duct-bridge" | "reinforced-bridge-conduit"], scale); /* @@ -241,7 +240,7 @@ impl Renderable for Schematic { } { unsafe { canvas.overlay_blended_at( - &bridge.borrow(), + &bridge, (p.0 as i32 * scale.px() as i32 + index) as u32, scale * (self.height as u32 - p.1 as u32 - 1 + y_fac / 2), ) @@ -260,25 +259,19 @@ impl Renderable for Schematic { ((self.height as i32 - p.1 as i32 + 1) * scale.px() as i32 + index) as u32; unsafe { - canvas.overlay_blended_at( - &bridge.borrow(), - scale * (p.0 as u32 + x_fac / 2), - y, - ) + canvas.overlay_blended_at(&bridge, scale * (p.0 as u32 + x_fac / 2), y) }; } if relative.0 != 0 { unsafe { canvas.overlay_blended_at( - &arrow - .rotated(if directional { - b.rot.rotated(false).count() - } else if relative.0 < 0 { - 2 - } else { - 0 - }) - .borrow(), + &arrow.rotated(if directional { + b.rot.rotated(false).count() + } else if relative.0 < 0 { + 2 + } else { + 0 + }), scale.px() as u32 + ((scale * p.0 as u32).cast_signed() + (scale.px() as i32 * relative.0 / 2)) @@ -289,15 +282,13 @@ impl Renderable for Schematic { } else { unsafe { canvas.overlay_blended_at( - &arrow - .rotated(if directional { - b.rot.rotated(false).count() - } else if relative.1 < 0 { - 1 - } else { - 3 - }) - .borrow(), + &arrow.rotated(if directional { + b.rot.rotated(false).count() + } else if relative.1 < 0 { + 1 + } else { + 3 + }), (scale * p.0 as u32) + (x_fac / 2 + scale.px() as u32) - 1, scale.px() as u32 + ((scale * (self.height as u32 - p.1 as u32 - 1)).cast_signed() @@ -310,7 +301,7 @@ impl Renderable for Schematic { } if matches!(scale, Scale::Full) { - canvas.as_mut().shadow(); + ImageUtils::shadow(&mut canvas); unsafe { bg.overlay_blended(&canvas) }; } else { unsafe { bg.overlay(&canvas) }; @@ -401,11 +392,9 @@ impl Renderable for Map { const LETTERS: [[Image<&[u8], 4>; 3]; 64] = f![0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63]; unsafe { img.overlay_at( - &ImageHolder::from( - LETTERS[(tile.nd[2] & 0x3f) as usize][scale as usize], - ) - .rotate(tile.nd[2] & 0x3) - .borrow(), + LETTERS[(tile.nd[2] & 0x3f) as usize][scale as usize] + .mapped(image::Cow::Ref) + .rotate(tile.nd[2] & 0x3), scale * x as u32, scale * y as u32, ) @@ -493,7 +482,7 @@ impl Renderable for Map { }); unsafe { img.as_mut().overlay_at( - &tile.build_image(ctx.as_ref(), scale).borrow(), + &tile.build_image(ctx.as_ref(), scale), scale * x as u32, scale * y as u32, ) @@ -513,7 +502,7 @@ impl Renderable for Map { } unsafe { img.as_mut() - .overlay_at(&entity.draw(scale).borrow(), scale * x, scale * y) + .overlay_at(&entity.draw(scale), scale * x, scale * y) }; } img @@ -591,7 +580,7 @@ pub fn draw_units( } unsafe { img.as_mut() - .overlay_at(&entity.draw(scale).borrow(), scale * x, scale * y) + .overlay_at(&entity.draw(scale), scale * x, scale * y) }; } Complete(Err(e)) => return Err(e), @@ -706,7 +695,7 @@ pub fn draw_map_single( }); unsafe { img.as_mut().overlay_at( - &b.image(None, ctx.as_ref(), r, scale).borrow(), + &b.image(None, ctx.as_ref(), r, scale), scale * x as u32, scale * y as u32, ) diff --git a/mindus/src/data/schematic.rs b/mindus/src/data/schematic.rs index 9553d67..aded36b 100644 --- a/mindus/src/data/schematic.rs +++ b/mindus/src/data/schematic.rs @@ -1,4 +1,5 @@ //! schematic parsing +use fimg::DynImage; use std::collections::HashMap; use std::collections::hash_map::Entry; use std::fmt::{self, Write}; @@ -12,6 +13,7 @@ use crate::data::renderer::*; use crate::data::{self, DataRead, DataWrite, GridPos, Serializable}; use crate::item::storage::ItemStorage; use crate::utils::array::Array2D; +use crate::utils::Cow; /// biggest schematic pub const MAX_DIMENSION: usize = 1024; @@ -67,7 +69,7 @@ impl Placement { context: Option<&RenderingContext>, rot: Rotation, s: Scale, - ) -> ImageHolder<4> { + ) -> DynImage<Cow> { self.block.image(self.get_state(), context, rot, s) } diff --git a/mindus/src/lib.rs b/mindus/src/lib.rs index d4c0abd..db900c2 100644 --- a/mindus/src/lib.rs +++ b/mindus/src/lib.rs @@ -9,6 +9,7 @@ likely_unlikely, portable_simd, derive_const, + const_from, coroutines )] #![allow(clippy::redundant_closure_call, incomplete_features)] diff --git a/mindus/src/unit.rs b/mindus/src/unit.rs index 6a27b1d..0343b5b 100644 --- a/mindus/src/unit.rs +++ b/mindus/src/unit.rs @@ -1,6 +1,7 @@ //! units //! //! [source](https://github.com/Anuken/Mindustry/blob/master/core/src/mindustry/content/UnitTypes.java) +use crate::Serializable; use crate::block::payload::read_payload; use crate::content::content_enum; use crate::data::command::UnitCommand; @@ -11,7 +12,6 @@ use crate::item::Type as Item; use crate::modifier::Type as Status; use crate::team::Team; use crate::utils::ImageHolder; -use crate::Serializable; macro_rules! units { ($($unit:literal,)+ $(,)?) => { paste::paste! { diff --git a/mindus/src/utils/image/holder.rs b/mindus/src/utils/image/holder.rs index 6618009..45aab38 100644 --- a/mindus/src/utils/image/holder.rs +++ b/mindus/src/utils/image/holder.rs @@ -1,132 +1,48 @@ -use super::{ClonerOverlay, ClonerOverlayAt, Image, ImageUtils, Overlay, OverlayAt}; +use super::Image; + #[derive(Clone, Debug)] -pub enum ImageHolder<const CHANNELS: usize> { - Borrow(Image<&'static [u8], CHANNELS>), - Own(Image<Box<[u8]>, CHANNELS>), +pub enum Cow { + Ref(&'static [u8]), + Own(Box<[u8]>), } - -impl<const CHANNELS: usize> ImageHolder<CHANNELS> { - #[must_use] - pub fn own(self) -> Image<Box<[u8]>, CHANNELS> { - match self { - Self::Own(x) => x, - Self::Borrow(x) => x.boxed(), - } +impl From<&'static [u8]> for Cow { + fn from(value: &'static [u8]) -> Self { + Self::Ref(value) } } - -impl<const CHANNELS: usize> ImageHolder<CHANNELS> { - pub fn swap_wh(self) -> Self { - match self { - ImageHolder::Borrow(image) => { - ImageHolder::Borrow(Image::build(image.height(), image.width()).buf(image.buffer())) - } - ImageHolder::Own(image) => ImageHolder::Own( - Image::build(image.height(), image.width()).buf(image.take_buffer()), - ), - } +impl From<Box<[u8]>> for Cow { + fn from(value: Box<[u8]>) -> Self { + Self::Own(value) } } -impl<const CHANNELS: usize> ImageHolder<CHANNELS> { - #[must_use] - #[inline] - pub fn borrow(&self) -> Image<&[u8], CHANNELS> { +impl Cow { + pub fn own(self) -> Box<[u8]> { match self { - Self::Own(x) => x.as_ref(), - Self::Borrow(x) => *x, + Self::Own(x) => x, + Self::Ref(x) => x.into(), } } - - #[must_use] - #[inline] - pub fn borrow_mut(&mut self) -> Image<&mut [u8], CHANNELS> { +} +impl AsRef<[u8]> for Cow { + fn as_ref(&self) -> &[u8] { match self { - Self::Own(x) => x.as_mut(), - Self::Borrow(x) => { - *self = Self::from(x.boxed()); - self.borrow_mut() - } + Cow::Ref(x) => x, + Cow::Own(x) => &x, } } } -macro_rules! make { - ($me: ident . $fn:ident($($argv:expr),*)) => { - match $me { - Self::Own(v) => { - #[allow(unused_unsafe)] - unsafe { v.as_mut().$fn($($argv,)*) }; - $me - } - Self::Borrow(v) => { - #[allow(unused_unsafe)] - { *$me = Self::from(unsafe { v.cloner().$fn($($argv,)*).boxed() }) }; - $me +impl AsMut<[u8]> for Cow { + fn as_mut(&mut self) -> &mut [u8] { + match self { + Cow::Ref(x) => { + *self = Self::Own((*x).into()); + self.as_mut() } - } - }; -} - -impl OverlayAt<ImageHolder<4>> for ImageHolder<4> { - unsafe fn overlay_at(&mut self, with: &ImageHolder<4>, x: u32, y: u32) -> &mut Self { - make!(self.overlay_at(&with.borrow(), x, y)) - } -} - -impl OverlayAt<Image<&[u8], 3>> for ImageHolder<3> { - unsafe fn overlay_at(&mut self, with: &Image<&[u8], 3>, x: u32, y: u32) -> &mut Self { - make!(self.overlay_at(with, x, y)) - } -} - -impl Overlay<Image<&[u8], 4>> for ImageHolder<3> { - unsafe fn overlay(&mut self, with: &Image<&[u8], 4>) -> &mut Self { - make!(self.overlay(with)) - } -} - -impl Overlay<ImageHolder<4>> for ImageHolder<3> { - unsafe fn overlay(&mut self, with: &ImageHolder<4>) -> &mut Self { - make!(self.overlay(&with.borrow())) - } -} - -impl Overlay<ImageHolder<4>> for ImageHolder<4> { - unsafe fn overlay(&mut self, with: &Self) -> &mut Self { - make!(self.overlay(&with.borrow())) - } -} - -impl ImageUtils for ImageHolder<4> { - fn tint(&mut self, color: (u8, u8, u8)) -> &mut Self { - self.borrow_mut().tint(color); - self - } - - unsafe fn rotate(&mut self, times: u8) -> &mut Self { - match times { - 2 => make!(self.rot_180()), - 1 => make!(self.rot_90()), - 3 => make!(self.rot_270()), - _ => self, + Cow::Own(x) => x, } } - - fn shadow(&mut self) -> &mut Self { - self.borrow_mut().shadow(); - self - } } -impl<const CHANNELS: usize> From<Image<&'static [u8], CHANNELS>> for ImageHolder<CHANNELS> { - fn from(value: Image<&'static [u8], CHANNELS>) -> Self { - Self::Borrow(value) - } -} - -impl<const CHANNELS: usize> From<Image<Box<[u8]>, CHANNELS>> for ImageHolder<CHANNELS> { - fn from(value: Image<Box<[u8]>, CHANNELS>) -> Self { - Self::Own(value) - } -} +pub type ImageHolder<const CHANNELS: usize> = Image<Cow, CHANNELS>; diff --git a/mindus/src/utils/image/mod.rs b/mindus/src/utils/image/mod.rs index e9dcc10..c7754c3 100644 --- a/mindus/src/utils/image/mod.rs +++ b/mindus/src/utils/image/mod.rs @@ -1,7 +1,7 @@ pub use fimg::*; mod holder; -pub use holder::ImageHolder; +pub use holder::*; pub trait ImageUtils { /// Tint this image with the color @@ -22,7 +22,7 @@ pub trait ImageUtils { fn shadow(&mut self) -> &mut Self; } -impl ImageUtils for Image<&mut [u8], 4> { +impl<T: AsMut<[u8]> + AsRef<[u8]>> ImageUtils for Image<T, 4> { unsafe fn rotate(&mut self, times: u8) -> &mut Self { match times { 2 => self.rot_180(), @@ -44,7 +44,7 @@ impl ImageUtils for Image<&mut [u8], 4> { } fn shadow(&mut self) -> &mut Self { - let mut shadow = self.to_owned().boxed(); + let mut shadow = self.as_ref().boxed(); for [r, g, b, a] in shadow.chunked_mut() { if *a < 128 { *r /= 10; diff --git a/mindus/src/utils/mod.rs b/mindus/src/utils/mod.rs index 3e12541..7183f0e 100644 --- a/mindus/src/utils/mod.rs +++ b/mindus/src/utils/mod.rs @@ -1,3 +1,3 @@ pub mod array; pub mod image; -pub use self::image::{Image, ImageHolder, ImageUtils, Overlay, OverlayAt}; +pub use self::image::{Cow, Image, ImageHolder, ImageUtils, Overlay, OverlayAt}; |