mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-31 13:37:35 -06:00
set_props with a complete look read the widget's /MK without resolving it, so an indirect one started from an empty dictionary: a check box lost its Cross mark, its 90-degree rotation and any unknown entry, and the loss survived a save. The /MK is now resolved first, as the check_style branch already does; a direct /MK behaves as before. Adds tests::a_whole_look_keeps_the_rest_of_an_indirect_mk, which fails before this change.
This commit is contained in:
@@ -1033,8 +1033,9 @@ pub fn set_props(doc: &mut Document, name: &str, props: &FieldProps) -> Result<S
|
||||
if let Some(l) = &props.look {
|
||||
let arr = |c: [f64; 3]| Object::Array(c.iter().map(|v| Object::Real(v.clamp(0.0, 1.0))).collect());
|
||||
for w in &f.widgets {
|
||||
// Resolved first: an indirect /MK keeps its mark, rotation and other entries.
|
||||
let mut mk = doc.get(w.obj).as_dict().and_then(|d| d.get(b"MK").map(|m| doc.resolve(m).as_dict().cloned())).flatten().unwrap_or_default();
|
||||
doc.update_dict(w.obj, |d| {
|
||||
let mut mk = d.get(b"MK").and_then(|m| m.as_dict().cloned()).unwrap_or_default();
|
||||
match l.border {
|
||||
Some(c) => mk.set(b"BC".to_vec(), arr(c)),
|
||||
None => {
|
||||
|
||||
@@ -1790,6 +1790,37 @@ fn partial_appearance_preserves_each_widgets_indirect_colours_and_border_extensi
|
||||
}
|
||||
}
|
||||
|
||||
/// A whole look sets the colours of an indirect /MK and keeps its mark, rotation and unknown
|
||||
/// entries (#1322), as it already did for a direct one.
|
||||
#[test]
|
||||
fn a_whole_look_keeps_the_rest_of_an_indirect_mk() {
|
||||
let mut doc = fixture();
|
||||
let widget = field(&fields(&doc), "agree").widgets[0].obj;
|
||||
let mut mk = pdfcraft_cos::Dict::new();
|
||||
mk.set(b"CA".to_vec(), pdfcraft_cos::PdfString::text("8"));
|
||||
mk.set(b"R".to_vec(), Object::Int(90));
|
||||
mk.set(b"VendorKey".to_vec(), Object::Int(71));
|
||||
let mk_ref = doc.add(Object::Dict(mk));
|
||||
doc.update_dict(widget, |d| d.set(b"MK".to_vec(), Object::Ref(mk_ref))).unwrap();
|
||||
let new = Look {
|
||||
border: Some([1.0, 0.0, 0.0]),
|
||||
fill: Some([1.0, 1.0, 0.8]),
|
||||
width: 2.0,
|
||||
style: BorderStyle::Solid,
|
||||
text: [0.0; 3],
|
||||
font: FieldFont::Helvetica,
|
||||
};
|
||||
set_props(&mut doc, "agree", &FieldProps { look: Some(new), ..FieldProps::default() }).unwrap();
|
||||
let doc = reopen(&doc);
|
||||
let f = field(&fields(&doc), "agree").clone();
|
||||
assert_eq!((check_style(&doc, &f), f.widgets[0].rotation), (CheckStyle::Cross, 90));
|
||||
let mk = doc.get(widget).as_dict().unwrap().get(b"MK").map(|v| doc.resolve(v)).unwrap();
|
||||
let mk = mk.as_dict().unwrap();
|
||||
assert_eq!(mk.int(b"VendorKey"), Some(71));
|
||||
assert_eq!(look(&doc, &f).border, Some([1.0, 0.0, 0.0]));
|
||||
assert_eq!(look(&doc, &f).fill, Some([1.0, 1.0, 0.8]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_appearance_patches_are_refused_before_anything_is_written() {
|
||||
let mut doc = fixture();
|
||||
|
||||
Reference in New Issue
Block a user