diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-11-20 16:36:22 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-11-20 16:36:22 +0100 |
| commit | f105663037c44740b5aa02dea72a9b368bc003e0 (patch) | |
| tree | ee97638bfba2be3cfba8c1191919447262f181d0 /src/library | |
| parent | 2e6e6244ccf73795d7d74cbc286fb0b43b404315 (diff) | |
Basic image support 🖼
- [image] function
- Image rendering in tests
- Supports JPEG and PNG
- No PDF export so far
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/graphics.rs | 42 | ||||
| -rw-r--r-- | src/library/mod.rs | 27 |
2 files changed, 59 insertions, 10 deletions
diff --git a/src/library/graphics.rs b/src/library/graphics.rs new file mode 100644 index 00000000..779d78b5 --- /dev/null +++ b/src/library/graphics.rs @@ -0,0 +1,42 @@ +use std::fs::File; +use std::io::BufReader; + +use image::io::Reader; + +use crate::layout::Image; +use crate::prelude::*; + +/// `image`: Include an image. +/// +/// # Positional arguments +/// - The path to the image (string) +pub fn image(mut args: Args, ctx: &mut EvalContext) -> Value { + let path = args.need::<_, Spanned<String>>(ctx, 0, "path"); + let width = args.get::<_, Linear>(ctx, "width"); + 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)) + .with_guessed_format() + .map_err(|err| err.into()) + .and_then(|reader| reader.decode()) + .map(|img| img.into_rgba8()) + { + Ok(buf) => { + ctx.push(Image { + buf, + width, + height, + align: ctx.state.align, + }); + } + Err(err) => ctx.diag(error!(path.span, "invalid image: {}", err)), + } + } else { + ctx.diag(error!(path.span, "failed to open image file")); + } + } + + Value::None +} diff --git a/src/library/mod.rs b/src/library/mod.rs index af23d050..e59201dc 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -4,6 +4,7 @@ mod align; mod boxed; mod color; mod font; +mod graphics; mod page; mod spacing; @@ -11,29 +12,35 @@ pub use align::*; pub use boxed::*; pub use color::*; pub use font::*; +pub use graphics::*; pub use page::*; pub use spacing::*; use crate::eval::{Scope, ValueFunc}; macro_rules! std { - ($($name:literal => $func:expr),* $(,)?) => { + ($($func:expr $(=> $name:expr)?),* $(,)?) => { /// Create a scope with all standard library functions. pub fn _std() -> Scope { let mut std = Scope::new(); - $(std.set($name, ValueFunc::new($func));)* + $( + let _name = stringify!($func); + $(let _name = $name;)? + std.set(_name, ValueFunc::new($func)); + )* std } }; } std! { - "align" => align, - "box" => boxed, - "font" => font, - "h" => h, - "page" => page, - "pagebreak" => pagebreak, - "rgb" => rgb, - "v" => v, + align, + boxed => "box", + font, + h, + image, + page, + pagebreak, + rgb, + v, } |
