pub struct ImageData {
pub width: u32,
pub height: u32,
pub rgba: Vec<u8>,
}
pub(crate) fn missing_image() -> ImageData {
const W: u32 = 8;
const H: u32 = 8;
let mut rgba = vec![0u8; (W * H * 4) as usize];
for pixel in rgba.chunks_exact_mut(4) {
pixel[0] = 0xFF;
pixel[1] = 0x00;
pixel[2] = 0xFF;
pixel[3] = 0xFF;
}
ImageData { width: W, height: H, rgba }
}
#[cfg(target_os = "windows")]
fn load_image_wic(path: &str) -> Option<ImageData> {
use windows::{
core::PCWSTR,
Win32::Foundation::GENERIC_ACCESS_RIGHTS,
Win32::Graphics::Imaging::{
CLSID_WICImagingFactory, GUID_WICPixelFormat32bppRGBA,
IWICBitmapFrameDecode, IWICFormatConverter, IWICImagingFactory, IWICPalette,
WICBitmapDitherTypeNone, WICBitmapPaletteTypeMedianCut,
WICDecodeMetadataCacheOnDemand,
},
Win32::System::Com::{
CoCreateInstance, CoInitializeEx, CLSCTX_INPROC_SERVER, COINIT_APARTMENTTHREADED,
},
};
unsafe {
let _ = CoInitializeEx(None, COINIT_APARTMENTTHREADED);
let factory: IWICImagingFactory =
CoCreateInstance(&CLSID_WICImagingFactory, None, CLSCTX_INPROC_SERVER).ok()?;
let path_w: Vec<u16> = path.encode_utf16().chain(std::iter::once(0)).collect();
let decoder = factory
.CreateDecoderFromFilename(
PCWSTR(path_w.as_ptr()),
None,
GENERIC_ACCESS_RIGHTS(0x8000_0000), WICDecodeMetadataCacheOnDemand,
)
.ok()?;
let frame: IWICBitmapFrameDecode = decoder.GetFrame(0).ok()?;
let mut width = 0u32;
let mut height = 0u32;
frame.GetSize(&mut width, &mut height).ok()?;
let converter: IWICFormatConverter = factory.CreateFormatConverter().ok()?;
converter
.Initialize(
&frame,
&GUID_WICPixelFormat32bppRGBA,
WICBitmapDitherTypeNone,
None::<&IWICPalette>,
0.0,
WICBitmapPaletteTypeMedianCut,
)
.ok()?;
let stride = width * 4;
let mut rgba = vec![0u8; (stride * height) as usize];
converter
.CopyPixels(std::ptr::null(), stride, &mut rgba)
.ok()?;
Some(ImageData { width, height, rgba })
}
}
pub(crate) fn decode_image_file(path: &str) -> ImageData {
#[cfg(target_os = "windows")]
if let Some(s) = load_image_wic(path) {
return s;
}
crate::log_warn!("画像の読み込みに失敗しました: '{path}'、代替スプライトを使用します");
missing_image()
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub enum BlendMode { #[default] Normal, Add, Mul }
#[derive(Copy, Clone)]
pub struct DrawScreenParams {
pub scale_x: f32,
pub scale_y: f32,
pub rotation: f32, pub alpha: f32,
pub flip_x: bool,
pub flip_y: bool,
}
impl Default for DrawScreenParams {
fn default() -> Self {
Self {
scale_x: 1.0,
scale_y: 1.0,
rotation: 0.0,
alpha: 1.0,
flip_x: false,
flip_y: false,
}
}
}