diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-11-27 22:35:42 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-11-27 22:35:42 +0100 |
| commit | 475ca7a62ec99f0b4d8319410b7ee3134a5fcfec (patch) | |
| tree | 75037761e1da5681b2971e79e605f95903ba6032 /src/library | |
| parent | bc997b7c3380d5f516f0aa58efc3dd513d75fafb (diff) | |
Basic environment and resource loader 🏞
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/insert.rs | 66 |
1 files changed, 29 insertions, 37 deletions
diff --git a/src/library/insert.rs b/src/library/insert.rs index 2904c958..b2cdc255 100644 --- a/src/library/insert.rs +++ b/src/library/insert.rs @@ -1,10 +1,9 @@ -use std::fmt::{self, Debug, Formatter}; -use std::fs::File; -use std::io::BufReader; +use std::io::Cursor; use image::io::Reader; -use image::RgbImage; +use image::GenericImageView; +use crate::env::ResourceId; use crate::layout::*; use crate::prelude::*; @@ -20,25 +19,27 @@ pub fn image(mut args: Args, ctx: &mut EvalContext) -> Value { let height = args.get::<_, Linear>(ctx, "height"); if let Some(path) = path { - if let Ok(file) = File::open(path.v) { - match Reader::new(BufReader::new(file)) + let mut env = ctx.env.borrow_mut(); + let loaded = env.resources.load(path.v, |data| { + Reader::new(Cursor::new(data)) .with_guessed_format() - .map_err(|err| err.into()) - .and_then(|reader| reader.decode()) - .map(|img| img.into_rgb8()) - { - Ok(buf) => { - ctx.push(Image { - buf, - width, - height, - align: ctx.state.align, - }); - } - Err(err) => ctx.diag(error!(path.span, "invalid image: {}", err)), - } + .ok() + .and_then(|reader| reader.decode().ok()) + }); + + if let Some((resource, buf)) = loaded { + let dimensions = buf.dimensions(); + drop(env); + ctx.push(Image { + resource, + dimensions, + width, + height, + align: ctx.state.align, + }); } else { - ctx.diag(error!(path.span, "failed to open image file")); + drop(env); + ctx.diag(error!(path.span, "failed to load image")); } } @@ -46,10 +47,12 @@ pub fn image(mut args: Args, ctx: &mut EvalContext) -> Value { } /// An image node. -#[derive(Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq)] struct Image { - /// The image. - buf: RgbImage, + /// The resource id of the image file. + resource: ResourceId, + /// The pixel dimensions of the image. + dimensions: (u32, u32), /// The fixed width, if any. width: Option<Linear>, /// The fixed height, if any. @@ -61,8 +64,7 @@ struct Image { impl Layout for Image { fn layout(&self, _: &mut LayoutContext, areas: &Areas) -> Layouted { let Area { rem, full } = areas.current; - let (pixel_width, pixel_height) = self.buf.dimensions(); - let pixel_ratio = (pixel_width as f64) / (pixel_height as f64); + let pixel_ratio = (self.dimensions.0 as f64) / (self.dimensions.1 as f64); let width = self.width.map(|w| w.resolve(full.width)); let height = self.height.map(|w| w.resolve(full.height)); @@ -85,23 +87,13 @@ impl Layout for Image { let mut boxed = BoxLayout::new(size); boxed.push( Point::ZERO, - LayoutElement::Image(ImageElement { buf: self.buf.clone(), size }), + LayoutElement::Image(ImageElement { resource: self.resource, size }), ); Layouted::Layout(boxed, self.align) } } -impl Debug for Image { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.debug_struct("Image") - .field("width", &self.width) - .field("height", &self.height) - .field("align", &self.align) - .finish() - } -} - impl From<Image> for LayoutNode { fn from(image: Image) -> Self { Self::dynamic(image) |
