From 2f97fd2d5946624a14f2cb2d140389b24a54ae96 Mon Sep 17 00:00:00 2001 From: mtlcl410 <2368091+mtlcl410@users.noreply.github.com> Date: Sat, 24 Oct 2026 09:27:38 +0800 Subject: [PATCH] M5: the placeholder for an unknown stamp name stays grey whatever its /C An AP-less stamp whose /Name has no drawing got its placeholder frame in the annotation's /C colour (/C [1 0 0] drew a red frame), while the doc comment and parity note promise a neutral grey one. The frame now always strokes PLACEHOLDER_GREY; the fourteen Table 184 names keep /C. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC --- crates/annot/src/appearance.rs | 10 ++++++---- crates/annot/src/tests.rs | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/annot/src/appearance.rs b/crates/annot/src/appearance.rs index a8a080e76..94e77cc53 100644 --- a/crates/annot/src/appearance.rs +++ b/crates/annot/src/appearance.rs @@ -843,9 +843,10 @@ fn standard_stamp(name: &[u8]) -> Option<(&'static str, Rgb)> { const PLACEHOLDER_GREY: Rgb = [0.45, 0.45, 0.45]; /// The display appearance of a rubber stamp another program wrote without one: the stamp its -/// `/Name` names (Draft when there is none, Table 184's default), or for any other name a thin -/// grey frame with both diagonals, so the stamp stays visible and can be selected. The name is -/// never drawn as text. +/// `/Name` names (Draft when there is none, Table 184's default) in its `/C` colour or the +/// stamp's own, or for any other name a thin grey frame with both diagonals, so the stamp stays +/// visible and can be selected. The frame is grey whatever the `/C`: it stands in for a stamp +/// that cannot be drawn, so it takes none of that stamp's colour. The name is never drawn as text. /// /// For display only ([`crate::with_missing_appearances`]): [`build`] declines these stamps, so /// edits (restyling, flattening) never write this drawing into the file. `None` for any other @@ -884,7 +885,8 @@ pub(crate) fn display_stamp(d: &Dict) -> Option { } c.push_str(&format!( "{}1 w\n{} {} {} {} re\n{} {} m {} {} l\n{} {} m {} {} l\nS\n", - rg_stroke(stroke.unwrap_or(PLACEHOLDER_GREY)), + // Grey whatever the `/C`: the placeholder is not the stamp, so it takes none of its colour. + rg_stroke(PLACEHOLDER_GREY), n(a0), n(b0), n(a1 - a0), diff --git a/crates/annot/src/tests.rs b/crates/annot/src/tests.rs index 2af04bc62..ca330bd68 100644 --- a/crates/annot/src/tests.rs +++ b/crates/annot/src/tests.rs @@ -1064,6 +1064,9 @@ fn a_stamp_without_an_appearance_draws_the_stamp_it_names() { } // `/C` colours the stamp, as it does PdfCraft's own. assert!(drawn(&stamp_dict("/Name /Final /C [1 0 1]")).contains("1 0 1 RG")); + // The placeholder stays grey whatever the `/C`: it is not the stamp, so it takes none of its colour. + let placeholder = drawn(&stamp_dict("/Name /MyCustomStamp /C [1 0 0]")); + assert!(placeholder.contains("0.45 0.45 0.45 RG") && !placeholder.contains("1 0 0 RG"), "{placeholder}"); // A stamp's own artwork is never replaced, and the drawing is for display only: edits // (restyling, flattening) still find nothing they may write. assert!(appearance::display_stamp(&stamp_dict("/Name /Draft /AP << /N 9 0 R >>")).is_none());