mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-10 04:09:53 -06:00
Watermark: ODT keeps a picture of unknown size in its header (#3001)
`picture_plan` chose the header frames as the document's watermark without checking that `own_size` can read the picture. A picture shown in a header whose size is not a raster's (an EMF or WMF) was taken out of the headers, then `add` could not place it: the picture was lost. The plan now returns None for such a picture, so the frames stay header pictures, as in the DOCX plan. Co-Authored-By: C00kieMonsta <22135261+C00kieMonsta@users.noreply.github.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FypgCVCCEo7u5wetHaJRU4
This commit is contained in:
co-authored by
C00kieMonsta
Claude Sonnet 5.5
parent
be2fef40a4
commit
eb2cb3a7d9
@@ -87,6 +87,9 @@ fn picture_plan(reads: &[SlotRead], pages: &Pages) -> Option<(Vec<u8>, (f32, f32
|
||||
return None;
|
||||
}
|
||||
let first = headers.first()?.pictures.first()?;
|
||||
// A picture whose size can't be read is no watermark (`add` couldn't place it, and the frames
|
||||
// taken out of the headers would be lost): it stays a header picture, as in the DOCX plan.
|
||||
wordcraft_doc::watermark::own_size(&first.0)?;
|
||||
if !headers.iter().filter_map(|r| r.pictures.first()).all(|p| p.0 == first.0 && p.2 == first.2) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -420,6 +420,33 @@ fn a_picture_frame_in_the_headers_is_the_watermark_only_where_every_page_shows_i
|
||||
assert_eq!(part_pictures(&d).iter().map(|(_, n)| n).sum::<usize>(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_picture_frame_of_unknown_size_is_not_a_watermark() {
|
||||
// An EMF picture shows in a header, but its size isn't a raster's, which a watermark is sized
|
||||
// from: the frames stay the pictures they are (taking them out would lose them).
|
||||
let mut emf = vec![0u8; 88];
|
||||
emf[0..4].copy_from_slice(&1u32.to_le_bytes());
|
||||
emf[4..8].copy_from_slice(&88u32.to_le_bytes());
|
||||
emf[24..40].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0x27, 0, 0, 0x10, 0x27, 0, 0]);
|
||||
emf[40..44].copy_from_slice(&0x464D_4520u32.to_le_bytes());
|
||||
assert!(wordcraft_doc::watermark::own_size(&emf).is_none());
|
||||
let a = wm_frame("a.emf");
|
||||
let pkg = watermark_package(&[(&a, ""), (&a, "")]);
|
||||
let mut z = zip::ZipArchive::new(std::io::Cursor::new(&pkg)).unwrap();
|
||||
let mut entries: Vec<(String, Vec<u8>)> = Vec::new();
|
||||
for i in 0..z.len() {
|
||||
let mut f = z.by_index(i).unwrap();
|
||||
let mut b = Vec::new();
|
||||
std::io::Read::read_to_end(&mut f, &mut b).unwrap();
|
||||
entries.push((f.name().to_string(), b));
|
||||
}
|
||||
entries.push(("Pictures/a.emf".into(), emf));
|
||||
let refs: Vec<(&str, &[u8])> = entries.iter().map(|(n, b)| (n.as_str(), b.as_slice())).collect();
|
||||
let d = import(&crate::odt::tests::zip_of(&refs)).unwrap();
|
||||
assert_eq!(d.settings.watermark, None);
|
||||
assert_eq!(part_pictures(&d).iter().map(|(_, n)| n).sum::<usize>(), 2, "{:?}", part_pictures(&d));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_watermark_added_to_an_odt_file_is_saved() {
|
||||
// Open an ODT, add a watermark, save as ODT: the watermark is written (the page setup was
|
||||
|
||||
Reference in New Issue
Block a user