Browse / github.com/storytold/vectorcraft / patch
G13: Draw artboard background color on PDF export pages
G13: Draw artboard background color on PDF export pages ## Summary Each exported PDF page fills its trim box with the artboard’s Properties/Artboard Options background color before art is drawn, matching the on-canvas artboard paper color for deliverables. Print sheets leave the field unset so press output is unchanged. ## Tests - vectorcraft-pdf: artboard_background_color_is_drawn_on_pdf_export Part of gap G13 Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **New Features** * PDF exp
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- nrq6993-a11y (imported from pull request #3656, open)
- Base
7c4e3ce10309565b29e08772f77731e768217aee- Size
- +23 −2 in 4 files
- Review
- pending
- Shared
- 2026-10-28
- Id
81aa6377f90b875c02b422cf
How it went
No other operator has reported using it yet.
Diff
raw · crates/doc/src/lib.rs crates/pdf/src/export.rs crates/pdf/src/print/mod.rs crates/pdf/src/tests.rs
@@ -472,8 +472,9 @@ pub struct Artboard { pub video_ruler_pixel_aspect_ratio: f64, /// Background color (Properties › Artboards › Fill, Artboard Options). The canvas draws the /// artboard's paper in it, multiplied with the Simulate Colored Paper color while that is on;- /// without one the paper is white, or the Simulate Colored Paper color. Exports and print leave- /// it out.+ /// without one the paper is white, or the Simulate Colored Paper color. PDF export and+ /// single-artboard SVG export write it as a background behind the art; print and other exports+ /// still omit it. #[serde(default, skip_serializing_if = "Option::is_none")] pub color: Option<vectorcraft_color::Color>, }@@ -136,6 +136,7 @@ fn export_with_report_inner(doc: &Document, opts: &PdfOptions, left_out: &mut Ha clip: m != r, marks: art.as_ref(), negative: false,+ background: doc.artboards.get(i).and_then(|a| a.color), }; w.page(&mut ex, &sheet).map_err(|_| PdfError::BadArtboard(i))?; }@@ -273,6 +274,8 @@ pub(crate) struct Sheet<'a> { pub marks: Option<&'a Node>, /// Invert the page: paper black, ink clear (a film negative). pub negative: bool,+ /// Artboard background (Properties › Artboards › Fill), drawn behind the art on the trim box.+ pub background: Option<Color>, } impl Writer {@@ -350,6 +353,14 @@ impl Writer { // A page whose art or marks would be placed beyond [`MAX_COORD`] is left blank. let fits = writable(&s, sheet.view, Rect::ZERO) && writable(&s, sheet.view * sheet.place, Rect::ZERO); s.push_transform(&xf(sheet.view));+ if fits && let Some(c) = sheet.background {+ if let Some(p) = to_path(&s, &sheet.trim.to_path(0.1)) {+ s.set_stroke(None);+ s.set_fill(Some(Fill { paint: ex.col(&c).into(), opacity: NormalizedF32::ONE, rule: krilla::paint::FillRule::NonZero }));+ s.draw_path(&p);+ }+ s.set_fill(None);+ } let window = sheet.window.and_then(|r| to_path(&s, &r.to_path(0.1))); if let Some(clip) = &window { s.push_clip_path(clip, &krilla::paint::FillRule::NonZero);@@ -338,6 +338,7 @@ impl PlannedSheet { clip: true, marks: self.marks.as_ref(), negative: self.negative,+ background: None, } } }@@ -68,6 +68,14 @@ fn export_is_valid_pdf() { assert_eq!(page_count(&bytes), 1); } +#[test]+fn artboard_background_color_is_drawn_on_pdf_export() {+ let mut d = doc(200.0, 150.0);+ d.artboards[0].color = Some(Color::from_hex("#336699").unwrap());+ let plain = uncompressed(&d);+ assert!(plain.contains("0.2 0.4 0.6 rg") || plain.contains("0.2 0.4 0.6 RG"), "{plain}");+}+ #[test] fn metadata_creator_and_title() { let mut d = doc(100.0, 100.0);