summaryrefslogtreecommitdiff
path: root/crates/typst-render/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-07-20 14:51:24 +0200
committerGitHub <noreply@github.com>2024-07-20 12:51:24 +0000
commit0c37a2c2334afb6947f265e00bded0fe75be6434 (patch)
treec6dd66554f1f9cadc1f43f386639c05f3aa6bf3e /crates/typst-render/src
parent3aa18beacf84e8e982a1cb28170d281769c06dd0 (diff)
Support transparent page fill (#4586)
Co-authored-by: Martin Haug <mhaug@live.de>
Diffstat (limited to 'crates/typst-render/src')
-rw-r--r--crates/typst-render/src/lib.rs44
1 files changed, 25 insertions, 19 deletions
diff --git a/crates/typst-render/src/lib.rs b/crates/typst-render/src/lib.rs
index 305dcd1f..d5eeacce 100644
--- a/crates/typst-render/src/lib.rs
+++ b/crates/typst-render/src/lib.rs
@@ -7,45 +7,49 @@ mod text;
use tiny_skia as sk;
use typst::layout::{
- Abs, Axes, Frame, FrameItem, FrameKind, GroupItem, Point, Size, Transform,
+ Abs, Axes, Frame, FrameItem, FrameKind, GroupItem, Page, Point, Size, Transform,
};
use typst::model::Document;
-use typst::visualize::Color;
+use typst::visualize::{Color, Geometry, Paint};
-/// Export a frame into a raster image.
+/// Export a page into a raster image.
///
-/// This renders the frame at the given number of pixels per point and returns
+/// This renders the page at the given number of pixels per point and returns
/// the resulting `tiny-skia` pixel buffer.
#[typst_macros::time(name = "render")]
-pub fn render(frame: &Frame, pixel_per_pt: f32, fill: Color) -> sk::Pixmap {
- let size = frame.size();
+pub fn render(page: &Page, pixel_per_pt: f32) -> sk::Pixmap {
+ let size = page.frame.size();
let pxw = (pixel_per_pt * size.x.to_f32()).round().max(1.0) as u32;
let pxh = (pixel_per_pt * size.y.to_f32()).round().max(1.0) as u32;
+ let ts = sk::Transform::from_scale(pixel_per_pt, pixel_per_pt);
+ let state = State::new(size, ts, pixel_per_pt);
+
let mut canvas = sk::Pixmap::new(pxw, pxh).unwrap();
- canvas.fill(paint::to_sk_color(fill));
- let ts = sk::Transform::from_scale(pixel_per_pt, pixel_per_pt);
- render_frame(&mut canvas, State::new(size, ts, pixel_per_pt), frame);
+ if let Some(fill) = page.fill_or_white() {
+ if let Paint::Solid(color) = fill {
+ canvas.fill(paint::to_sk_color(color));
+ } else {
+ let rect = Geometry::Rect(page.frame.size()).filled(fill);
+ shape::render_shape(&mut canvas, state, &rect);
+ }
+ }
+
+ render_frame(&mut canvas, state, &page.frame);
canvas
}
/// Export a document with potentially multiple pages into a single raster image.
-///
-/// The gap will be added between the individual frames.
pub fn render_merged(
document: &Document,
pixel_per_pt: f32,
- frame_fill: Color,
gap: Abs,
- gap_fill: Color,
+ fill: Option<Color>,
) -> sk::Pixmap {
- let pixmaps: Vec<_> = document
- .pages
- .iter()
- .map(|page| render(&page.frame, pixel_per_pt, frame_fill))
- .collect();
+ let pixmaps: Vec<_> =
+ document.pages.iter().map(|page| render(page, pixel_per_pt)).collect();
let gap = (pixel_per_pt * gap.to_f32()).round() as u32;
let pxw = pixmaps.iter().map(sk::Pixmap::width).max().unwrap_or_default();
@@ -53,7 +57,9 @@ pub fn render_merged(
+ gap * pixmaps.len().saturating_sub(1) as u32;
let mut canvas = sk::Pixmap::new(pxw, pxh).unwrap();
- canvas.fill(paint::to_sk_color(gap_fill));
+ if let Some(fill) = fill {
+ canvas.fill(paint::to_sk_color(fill));
+ }
let mut y = 0;
for pixmap in pixmaps {