mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-14 19:27:04 -04:00
Remove Hidden Information counted and removed as a comment every annotation that was not a link, widget, pop-up, file attachment or redaction mark, so a Comments-only cleanup also deleted Watermark, PrinterMark, TrapNet, Screen, Movie, RichMedia and 3D annotations. Use pdfcraft_annot::is_comment_subtype, which the comments list already uses, and keep excluding file attachments (removed with Attachments) and redaction marks as before. Adds tests::removing_comments_keeps_annotations_that_are_not_comments, which fails before this change.
This commit is contained in:
1 parent
f97f24cfbc
commit
9593ff7419
2 files changed
+30
-1
No files matched your search
@@ -113,8 +113,10 @@ fn outline_len(doc: &Document, first: Option<&Object>, depth: usize) -> usize {
|
||||
n
|
||||
}
|
||||
|
||||
/// A comment as the comments list sees it, less file attachments (removed with Attachments) and
|
||||
/// redaction marks.
|
||||
fn is_comment(subtype: &[u8]) -> bool {
|
||||
!matches!(subtype, b"Link" | b"Widget" | b"Popup" | b"FileAttachment" | b"Redact")
|
||||
!matches!(subtype, b"FileAttachment" | b"Redact") && pdfcraft_annot::is_comment_subtype(&String::from_utf8_lossy(subtype))
|
||||
}
|
||||
|
||||
/// The layers that are off in the default configuration.
|
||||
|
||||
@@ -533,6 +533,33 @@ fn hidden_information_is_counted_and_removed() {
|
||||
assert!(shown, "the field's value stays visible as page content");
|
||||
}
|
||||
|
||||
/// Issue #1325: removing comments keeps the annotations that are not comments: the multimedia
|
||||
/// and print-production ones (Watermark, PrinterMark, TrapNet, Screen, Movie, RichMedia, 3D).
|
||||
#[test]
|
||||
fn removing_comments_keeps_annotations_that_are_not_comments() {
|
||||
use crate::sanitize::{Hidden, remove_hidden, scan};
|
||||
let kept = ["Link", "Watermark", "PrinterMark", "TrapNet", "Screen", "Movie", "RichMedia", "3D"];
|
||||
let annots: Vec<String> = (0..=kept.len()).map(|i| format!("{} 0 R", i + 4)).collect();
|
||||
let mut objs = vec![
|
||||
b"<< /Type /Catalog /Pages 2 0 R >>".to_vec(),
|
||||
b"<< /Type /Pages /Kids [3 0 R] /Count 1 >>".to_vec(),
|
||||
format!("<< /Type /Page /Parent 2 0 R /MediaBox [0 0 300 300] /Resources << >> /Annots [{}] >>", annots.join(" ")).into_bytes(),
|
||||
b"<< /Type /Annot /Subtype /Square /Rect [10 10 50 50] >>".to_vec(),
|
||||
];
|
||||
objs.extend(kept.iter().map(|s| format!("<< /Type /Annot /Subtype /{s} /Rect [60 60 90 90] >>").into_bytes()));
|
||||
let mut doc = pdf(objs);
|
||||
let counts: std::collections::HashMap<Hidden, usize> = scan(&doc).into_iter().collect();
|
||||
assert_eq!(counts[&Hidden::Comments], 1, "only the Square");
|
||||
assert_eq!(remove_hidden(&mut doc, &[Hidden::Comments]).unwrap(), [(Hidden::Comments, 1)]);
|
||||
let doc = reopen(&doc);
|
||||
let p = pdfcraft_model::pages(&doc).swap_remove(0);
|
||||
let left: Vec<String> = annots_of(&doc, &p.dict)
|
||||
.iter()
|
||||
.filter_map(|a| doc.resolve(a).as_dict().and_then(|d| d.name(b"Subtype")).map(|s| String::from_utf8_lossy(s).into_owned()))
|
||||
.collect();
|
||||
assert_eq!(left, kept);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlay_text_takes_its_font_size_colour_alignment_and_repeats() {
|
||||
let mut doc = one_page(b"BT /F1 12 Tf 20 250 Td (Secret salary figures) Tj ET", "", Vec::new());
|
||||
|
||||
Reference in new issue
Block a user