M2: print previews don't apply the View auto state; doc_info layer_order end-to-end test

A print preview (a request carrying the print tag, with or without the
canvas's scale and grayscale bits) rendered with the document's on-screen
settings, so a layer the View auto state turns off was hidden in the
preview but printed. Printing is not the View event (ISO 32000-2
8.11.4.4), so the preview now leaves the auto state off like the print.

Also add a tool-level test of doc_info's layer_order rows for a /Order
with a group, a labelled nested array and an unlisted group (1-based
layer index, name, label and depth).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
This commit is contained in:
mtlcl410
2026-10-31 14:13:35 +08:00
co-authored by Claude Opus 5.5
parent 2117186687
commit 5f757262f9
4 changed files with 47 additions and 1 deletions
+30
View File
@@ -8186,6 +8186,36 @@ fn doc_info_describes_set_layer_links() {
assert_eq!(info["layer_order"], json!([]));
}
/// `doc_info`'s `layer_order` follows the default configuration's /Order (ISO 32000-2 Table 99):
/// a group by its 1-based position in `layers` and its name, a nested array one level deeper,
/// a label that starts one, and a group /Order does not list left out.
#[test]
fn doc_info_lists_the_layer_order_tree() {
let dir = workdir("layer-order");
let pdf = pdf_of(&[
"<< /Type /Catalog /Pages 2 0 R /OCProperties << /OCGs [4 0 R 5 0 R 6 0 R 7 0 R] /D << /Order [6 0 R [(Inks) 4 0 R [5 0 R]]] >> >> >>",
"<< /Type /Pages /Kids [3 0 R] /Count 1 >>",
"<< /Type /Page /Parent 2 0 R /MediaBox [0 0 200 200] >>",
"<< /Type /OCG /Name (Red) >>",
"<< /Type /OCG /Name (Green) >>",
"<< /Type /OCG /Name (Blue) >>",
"<< /Type /OCG /Name (Unlisted) >>",
]);
std::fs::write(dir.join("order.pdf"), pdf).unwrap();
let mut a = auto(&dir);
let doc = ok(&mut a, "doc_open", json!({ "path": "order.pdf" }))["doc"].as_u64().unwrap();
let info = ok(&mut a, "doc_info", json!({ "doc": doc }));
assert_eq!(
info["layer_order"],
json!([
{ "depth": 0, "layer": 3, "name": "Blue" },
{ "depth": 0, "label": "Inks" },
{ "depth": 1, "layer": 1, "name": "Red" },
{ "depth": 2, "layer": 2, "name": "Green" },
])
);
}
mod close_argument_tests {
use super::*;
use std::sync::atomic::{AtomicU64, Ordering};
+2
View File
@@ -440,6 +440,8 @@ fn render_page<'a>(
// Previews render at low detail (tiny images are skipped); finals always draw all.
let mut preview_settings = settings.clone();
preview_settings.preview = req.preview;
// A print preview shows what prints, and printing is not the View event.
preview_settings.view_auto_state &= req.tag & PRINT_TAG == 0;
render_into(page, cache, &preview_settings, &rs, pixels.bytes_mut());
Ok((w.into(), h.into(), pixels, None))
}));
+14
View File
@@ -2370,6 +2370,20 @@ fn layer_toggles_and_print_renders_are_not_the_view_auto_state() {
assert!(!auto_state_red(pdf, RenderConfig::default()), "on screen: hidden");
}
/// A print preview ([`PRINT_TAG`], with or without the canvas's scale and grayscale bits)
/// shows what prints, so the View auto state is not applied to it either.
#[test]
fn print_previews_are_not_the_view_auto_state() {
let pdf = Arc::new(auto_state_pdf(VIEW_OFF, &format!("<< {AS_VIEW} >>"), ""));
let mut r = PageRenderer::new(pdf, RenderConfig::default());
for tag in [PRINT_TAG, PRINT_TAG | 1 << 59 | 7] {
let p = r.render(RenderRequest { page: 0, kind: RequestKind::Pixels, tile: None, scale: 0.5, tag, ..Default::default() });
assert_eq!(p.rgba.get(..4), Some(&[255, 0, 0, 255][..]), "tag {tag:#x}: printed state");
}
let p = r.render(RenderRequest { page: 0, kind: RequestKind::Pixels, tile: None, scale: 0.5, tag: 7, ..Default::default() });
assert_ne!(p.rgba.get(..4), Some(&[255, 0, 0, 255][..]), "on screen: hidden");
}
/// Malformed auto state is ignored without a panic, and the walk is bounded.
#[test]
fn malformed_view_auto_state_is_ignored() {
+1 -1
View File
@@ -1335,7 +1335,7 @@ status = "shipped"
commands = []
tools = ["doc_info", "layer_set"]
evidence = ["crates/render/src/raster/tests.rs::layer_override_hides_content", "crates/engine/src/tests.rs::layer_choices_survive_edits", "crates/automation/tests/it/automation.rs::layers_and_hidden_comments_change_what_page_render_draws", "crates/render/src/raster/tests.rs::the_view_auto_state_sets_a_groups_state_on_screen", "crates/render/src/raster/tests.rs::layer_toggles_and_print_renders_are_not_the_view_auto_state", "crates/render/src/raster/tests.rs::malformed_view_auto_state_is_ignored", "crates/render/src/inspect/tests.rs::the_layers_panel_presents_the_order_tree", "crates/ui-egui/tests/it/layer_actions.rs::the_layers_panel_shows_the_order_tree"]
notes = "layer_set shows or hides a layer by name (every group with that name, as CAD exporters repeat names) or by position, and page_render draws with the document's layer visibility. Still missing: Reset to initial visibility (view.layers-reset), layer properties, and /OC on annotations (#2176). The default configuration's auto state for the View event (/AS, ISO 32000-2 8.11.4.4) sets the groups it manages from their /Usage /View /ViewState as the document opens, on screen and in the panel, and toggles still override it; renders for printing don't apply it. Not yet: the /Zoom, /User and /Language categories, and the Print event's auto state when printing. The panel presents the default configuration's /Order (ISO 32000-2 Table 99) as a tree: a nested array one level deeper, a leading text string as a label that can't be toggled. Groups /Order leaves out aren't listed but still draw in their state, and a document without /Order lists none, the default Table 99 gives; doc_info reports the rows as layer_order. Not yet: /ListMode /VisiblePages."
notes = "layer_set shows or hides a layer by name (every group with that name, as CAD exporters repeat names) or by position, and page_render draws with the document's layer visibility. Still missing: Reset to initial visibility (view.layers-reset), layer properties, and /OC on annotations (#2176). The default configuration's auto state for the View event (/AS, ISO 32000-2 8.11.4.4) sets the groups it manages from their /Usage /View /ViewState as the document opens, on screen and in the panel, and toggles still override it; renders for printing and print previews don't apply it. Not yet: the /Zoom, /User and /Language categories, and the Print event's auto state when printing. The panel presents the default configuration's /Order (ISO 32000-2 Table 99) as a tree: a nested array one level deeper, a leading text string as a label that can't be toggled. Groups /Order leaves out aren't listed but still draw in their state, and a document without /Order lists none, the default Table 99 gives; doc_info reports the rows as layer_order. Not yet: /ListMode /VisiblePages."
[[feature]]
id = "view.layers-reset"