mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-10 13:01:29 +00:00
1 parent
466e1971d6
commit
851d6ceca5
4 files changed
+46
-4
No files matched your search
@@ -32,6 +32,8 @@ spool::submit(&pdf, &spool::Job { printer: None, copies: 2, ..Default::default()
|
||||
- **Poster**: tile scale, overlap shared by neighbouring tiles, cut marks.
|
||||
- **Comments & forms**: document, + markups, + stamps, or form fields only; annotations print
|
||||
only with their Print flag, drawn from their appearance streams (Algorithm 8.1).
|
||||
Existing Link appearances are document content in the first three modes; Link appearances
|
||||
are not synthesized when absent, and form fields only excludes them.
|
||||
- **Properties… on CUPS** reads the queue's PPD and its current defaults (`lpoptions -l`) off
|
||||
the GUI thread, and gives `lpoptions` ten seconds: a CUPS that has stopped answering leaves
|
||||
the PPD's own defaults in force instead of holding the dialog (#1818; `spool::output_within`
|
||||
|
||||
@@ -100,7 +100,9 @@ pub(crate) fn prints(doc: &Document, d: &Dict, content: Content) -> bool {
|
||||
let subtype = subtype_obj.as_deref().and_then(Object::as_name).unwrap_or(b"");
|
||||
match subtype {
|
||||
b"Widget" => true,
|
||||
b"Link" | b"Popup" => false,
|
||||
// Existing Link appearances are part of the document, not markup or fields.
|
||||
b"Link" => content != Content::FormFieldsOnly,
|
||||
b"Popup" => false,
|
||||
b"Stamp" => content != Content::Document && content != Content::FormFieldsOnly,
|
||||
// ISO 32000-2 Table 167: an Invisible annotation of a type that isn't standard (Table
|
||||
// 171) is not printed even with its Print flag set.
|
||||
|
||||
@@ -85,6 +85,44 @@ fn xobject(doc: &Document, owner: &Dict, name: &[u8]) -> ObjRef {
|
||||
objects.as_dict().unwrap().get(name).unwrap().as_ref().unwrap()
|
||||
}
|
||||
|
||||
/// Existing Link artwork prints as document content only when its flags allow printing.
|
||||
#[test]
|
||||
fn printable_link_appearance_survives_vector_print() {
|
||||
for flags in [0, 2, 4, 6, 5] {
|
||||
for content in [Content::Document, Content::DocumentAndMarkups, Content::DocumentAndStamps, Content::FormFieldsOnly] {
|
||||
let (mut doc, _, annot) = widget_fixture(Some(Object::name("Form")), None);
|
||||
doc.update_dict(annot, |d| {
|
||||
d.set(b"Subtype".to_vec(), Object::name("Link"));
|
||||
d.set(b"F".to_vec(), Object::Int(flags));
|
||||
})
|
||||
.unwrap();
|
||||
let before = saved(&doc);
|
||||
let expected = flags & 4 != 0 && flags & 2 == 0 && content != Content::FormFieldsOnly;
|
||||
let printed = render(impose(&doc, &print_settings(content)).unwrap());
|
||||
let color = if expected { [0, 255, 0, 255] } else { [255, 255, 255, 255] };
|
||||
assert_eq!(pixel(&printed, 30, 70), color, "flags={flags}, content={content:?}");
|
||||
let mut raster_source = doc.clone();
|
||||
keep_printed(&mut raster_source, content);
|
||||
let page = &pdfcraft_model::pages(&raster_source)[0];
|
||||
let annots = raster_source.resolve(page.dict.get(b"Annots").unwrap());
|
||||
assert_eq!(annots.as_array().unwrap().len(), usize::from(expected), "raster flags={flags}, content={content:?}");
|
||||
assert_eq!(saved(&doc), before, "source remains unchanged");
|
||||
}
|
||||
}
|
||||
for subtype in ["Link", "Popup"] {
|
||||
let (mut doc, _, annot) = widget_fixture(Some(Object::name("Form")), None);
|
||||
doc.update_dict(annot, |d| {
|
||||
d.set(b"Subtype".to_vec(), Object::name(subtype));
|
||||
if subtype == "Link" {
|
||||
d.remove(b"AP");
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
let printed = render(impose(&doc, &print_settings(Content::DocumentAndMarkups)).unwrap());
|
||||
assert_eq!(pixel(&printed, 30, 70), [255, 255, 255, 255], "{subtype} must not acquire an appearance");
|
||||
}
|
||||
}
|
||||
|
||||
/// Printing keeps occupied page resource names and distinct annotation appearances intact,
|
||||
/// whether the page resources are direct or inherited from the page tree.
|
||||
#[test]
|
||||
|
||||
@@ -819,7 +819,7 @@ status = "shipped"
|
||||
commands = []
|
||||
tools = []
|
||||
evidence = ["crates/render/src/raster/tests.rs::widget_appearance_states", "crates/render/src/raster/tests.rs::highlights_without_an_appearance_are_drawn", "crates/engine/src/tests.rs::comments_without_appearances_are_drawn_but_not_saved", "crates/engine/src/tests.rs::cli_display_adds_missing_appearances_without_changing_the_source", "crates/engine/src/tests.rs::fields_left_to_the_viewer_are_displayed_from_their_values", "crates/forms/src/tests.rs::need_appearances_draws_every_text_and_choice_field_in_the_display_copy", "crates/forms/src/tests.rs::the_field_appearance_cache_sees_every_input", "crates/engine/src/tests.rs::buttons_and_combs_left_to_the_viewer_are_displayed", "crates/forms/src/tests.rs::check_boxes_without_an_appearance_show_their_caption_symbol", "crates/forms/src/tests.rs::push_buttons_without_an_appearance_show_their_caption_and_frame", "crates/forms/src/tests.rs::need_appearances_draws_check_boxes_and_radio_buttons_from_their_captions", "crates/engine/src/tests.rs::need_appearances_buttons_are_displayed_from_their_captions", "crates/render/src/raster/tests.rs::invisible_unknown_annotations_and_popups_paint_nothing", "crates/print/src/tests.rs::invisible_annotations_of_unknown_types_do_not_print", "crates/engine/src/tests.rs::stamps_without_appearances_draw_the_stamp_they_name", "crates/automation/tests/it/automation.rs::page_render_draws_stamps_without_an_appearance", "crates/annot/src/tests.rs::a_four_entry_colour_with_a_null_is_cmyk_with_zero", "crates/forms/src/tests.rs::a_four_entry_mk_colour_with_a_null_is_cmyk_with_zero", "crates/annot/src/tests.rs::text_markup_whose_quads_reach_past_its_rect_is_drawn_over_them", "crates/annot/src/tests.rs::text_markup_reach_stops_at_the_page_and_the_quad_cap", "crates/annot/src/tests.rs::text_markup_reach_reads_quads_like_the_drawing", "crates/annot/src/tests.rs::ink_whose_strokes_reach_past_its_rect_is_drawn_through_them", "crates/annot/src/tests.rs::polyline_whose_vertices_reach_past_its_rect_is_drawn_through_them", "crates/annot/src/tests.rs::polygon_whose_vertices_reach_past_its_rect_is_drawn_through_them", "crates/annot/src/tests.rs::line_whose_points_reach_past_its_rect_is_drawn_through_them", "crates/annot/src/tests.rs::path_reach_stops_at_the_point_cap_and_is_saved_on_restyle", "crates/annot/src/tests.rs::indirect_border_style_and_colour_are_drawn", "crates/annot/src/tests.rs::callout_without_rd_is_drawn", "crates/forms/src/tests.rs::normal_appearances_that_give_no_stream_are_drawn", "crates/engine/src/tests.rs::text_boxes_and_redaction_marks_without_appearances_show_their_outlines", "crates/annot/src/tests.rs::free_text_da_fonts_draw_in_their_standard_face", "crates/annot/src/tests.rs::free_text_ds_style_is_drawn", "crates/annot/src/tests.rs::redaction_marks_with_quadpoints_take_their_outline_from_oc_then_c", "crates/annot/src/tests.rs::unapplied_redaction_marks_follow_their_oc_outline_colour"]
|
||||
notes = "comments without /AP (FreeText, Ink, notes, stamps, shapes, markup; text markup, lines, polylines, polygons and ink through their /QuadPoints, /L, /Vertices or /InkList where these reach past /Rect, as far as the crop box) are drawn from their dictionaries in the page view, page_render and page images, including the CLI render command, never saved, with style values given by reference (a /BS, colour, /RD or /CL as an indirect object, ISO 32000-2 §7.3.10) followed and a callout without /RD (optional, Table 177) boxed at its /Rect; a four-entry colour with a non-number in it (/C, /IC, /MK /BC and /BG written [1 0 0 null]) is read as CMYK with that entry 0; a stamp from another program draws the stamp its /Name names (the fourteen standard names of ISO 32000-2 Table 184, Draft when there is none) or, for any other name, a grey frame with both diagonals; text boxes without /BS or /Border get the /Border default 1-pt border (ISO 32000-2 Table 166), their /DA font when /DR or its resource name makes it one of the twelve standard text faces (others stay Helvetica), and /DS font, size and colour over /DA (no /RC rich text yet); unapplied redaction marks without /AP are outlined in an array /OC colour (three finite numbers) when they have one, with or without /QuadPoints; without one, marks with /QuadPoints keep /C (else red) and marks without /QuadPoints (Table 195: /Rect is the region) draw nothing; an /OC dictionary stays optional content (Table 166). Basis: ISO 32000-2 §12.5.6.23 says only that before redaction is applied the user can see, move and redefine these annotations, and Table 195 has no outline-colour entry, so the colour comes from black-box observation of two synthetic fixtures. noap3.pdf (generator attached to #4364), rows J/K/L, unapplied, without /QuadPoints: Adobe Acrobat Pro J nothing, K red outline, L nothing; Chrome (PDFium) and Edge nothing on all three; PDF-XChange Editor and Right PDF Editor a red outline on all three. oc.pdf, six marks without /AP (1 /OC blue; 2 /C green; 3 /OC blue + /C green; 4 /OC blue + /IC black; 5 no colour; 6 /OC blue + /QuadPoints; rebuilt inline in unapplied_redaction_marks_follow_their_oc_outline_colour): Acrobat blue on 1, 3, 4 and 6 and nothing on 2 and 5; Chrome and Edge nothing on all six; PDF-XChange Editor green on 2 and 3, nothing on the others; Right PDF Editor red on all six. The three readers tested that support redaction marks disagree, so PdfCraft follows the /OC colour, the one Acrobat uses; text and choice fields are drawn from their values when the form sets /NeedAppearances (every one) or a widget's /N gives no stream to draw (none, null, a dictionary without its stream data, or a state subdictionary without a stream for /AS; #3470), also display-only and cached per widget (a field edit on a 1000-field /NeedAppearances form takes ~13 ms against ~7 ms on a form that needs none) (a read-only document still gets the renderer's Highlight fallback only); check boxes and radio buttons with no appearance for their /AS are drawn display-only from /MK (background, border, and when on the /MK /CA ZapfDingbats symbol in the /DA colour, a check or a dot by default), and when the form sets /NeedAppearances so is every one that has an /MK, over the appearance the file carries (ISO 32000-2 Table 224; one without /MK keeps its own), and push buttons with none from /MK and /BS with their caption; Link borders without /AP and printing are not covered yet; an annotation of a non-standard type with the Invisible flag (ISO 32000-2 Table 167) is neither drawn nor printed, and a popup's own /AP is never painted on the page (its parent's text shows in the popup window, §12.5.6.14)"
|
||||
notes = "comments without /AP (FreeText, Ink, notes, stamps, shapes, markup; text markup, lines, polylines, polygons and ink through their /QuadPoints, /L, /Vertices or /InkList where these reach past /Rect, as far as the crop box) are drawn from their dictionaries in the page view, page_render and page images, including the CLI render command, never saved, with style values given by reference (a /BS, colour, /RD or /CL as an indirect object, ISO 32000-2 §7.3.10) followed and a callout without /RD (optional, Table 177) boxed at its /Rect; a four-entry colour with a non-number in it (/C, /IC, /MK /BC and /BG written [1 0 0 null]) is read as CMYK with that entry 0; a stamp from another program draws the stamp its /Name names (the fourteen standard names of ISO 32000-2 Table 184, Draft when there is none) or, for any other name, a grey frame with both diagonals; text boxes without /BS or /Border get the /Border default 1-pt border (ISO 32000-2 Table 166), their /DA font when /DR or its resource name makes it one of the twelve standard text faces (others stay Helvetica), and /DS font, size and colour over /DA (no /RC rich text yet); unapplied redaction marks without /AP are outlined in an array /OC colour (three finite numbers) when they have one, with or without /QuadPoints; without one, marks with /QuadPoints keep /C (else red) and marks without /QuadPoints (Table 195: /Rect is the region) draw nothing; an /OC dictionary stays optional content (Table 166). Basis: ISO 32000-2 §12.5.6.23 says only that before redaction is applied the user can see, move and redefine these annotations, and Table 195 has no outline-colour entry, so the colour comes from black-box observation of two synthetic fixtures. noap3.pdf (generator attached to #4364), rows J/K/L, unapplied, without /QuadPoints: Adobe Acrobat Pro J nothing, K red outline, L nothing; Chrome (PDFium) and Edge nothing on all three; PDF-XChange Editor and Right PDF Editor a red outline on all three. oc.pdf, six marks without /AP (1 /OC blue; 2 /C green; 3 /OC blue + /C green; 4 /OC blue + /IC black; 5 no colour; 6 /OC blue + /QuadPoints; rebuilt inline in unapplied_redaction_marks_follow_their_oc_outline_colour): Acrobat blue on 1, 3, 4 and 6 and nothing on 2 and 5; Chrome and Edge nothing on all six; PDF-XChange Editor green on 2 and 3, nothing on the others; Right PDF Editor red on all six. The three readers tested that support redaction marks disagree, so PdfCraft follows the /OC colour, the one Acrobat uses; text and choice fields are drawn from their values when the form sets /NeedAppearances (every one) or a widget's /N gives no stream to draw (none, null, a dictionary without its stream data, or a state subdictionary without a stream for /AS; #3470), also display-only and cached per widget (a field edit on a 1000-field /NeedAppearances form takes ~13 ms against ~7 ms on a form that needs none) (a read-only document still gets the renderer's Highlight fallback only); check boxes and radio buttons with no appearance for their /AS are drawn display-only from /MK (background, border, and when on the /MK /CA ZapfDingbats symbol in the /DA colour, a check or a dot by default), and when the form sets /NeedAppearances so is every one that has an /MK, over the appearance the file carries (ISO 32000-2 Table 224; one without /MK keeps its own), and push buttons with none from /MK and /BS with their caption; Link borders without /AP are not synthesized for display or printing; an annotation of a non-standard type with the Invisible flag (ISO 32000-2 Table 167) is neither drawn nor printed, and a popup's own /AP is never painted on the page (its parent's text shows in the popup window, §12.5.6.14)"
|
||||
|
||||
[[feature]]
|
||||
id = "view.render-error-isolation"
|
||||
@@ -8333,8 +8333,8 @@ milestone = "M10"
|
||||
status = "shipped"
|
||||
commands = ["print.dialog"]
|
||||
tools = ["doc_print"]
|
||||
evidence = ["crates/print/src/tests.rs::imposed_pdf_has_the_sheets_and_honours_comments_and_forms", "crates/print/src/tests/appearances.rs::annotation_appearances_do_not_replace_page_xobjects"]
|
||||
notes = "Print flag honoured; appearance resource names preserve existing page XObjects and distinct annotations, including inherited resources"
|
||||
evidence = ["crates/print/src/tests.rs::imposed_pdf_has_the_sheets_and_honours_comments_and_forms", "crates/print/src/tests/appearances.rs::annotation_appearances_do_not_replace_page_xobjects", "crates/print/src/tests/appearances.rs::printable_link_appearance_survives_vector_print"]
|
||||
notes = "Print and Hidden flags honoured; existing Link appearances print as document content, but missing Link appearances are not synthesized. Appearance resource names preserve existing page XObjects and distinct annotations, including inherited resources"
|
||||
|
||||
[[feature]]
|
||||
id = "print.print-with-comment-summary"
|
||||
|
||||
Reference in new issue
Block a user