style: cargo fmt on moved files

This commit is contained in:
aiongg
2026-10-27 00:34:32 +00:00
parent 323172e860
commit f022ef0671
19 changed files with 84 additions and 217 deletions
+9 -23
View File
@@ -92,10 +92,7 @@ fn unquoted_paths_with_spaces_are_rejoined() {
let exists = |p: &str| have.contains(&p);
let args = |a: &[&str]| a.iter().map(|s| s.to_string()).collect::<Vec<_>>();
// The case an office program produced: one path, split at its space.
assert_eq!(
super::rejoin_split_paths(args(&["P:\\Archive\\00042A26", "Contract.PDF"]), exists),
args(&["P:\\Archive\\00042A26 Contract.PDF"])
);
assert_eq!(super::rejoin_split_paths(args(&["P:\\Archive\\00042A26", "Contract.PDF"]), exists), args(&["P:\\Archive\\00042A26 Contract.PDF"]));
// The longest run wins; files that exist on their own are left alone.
assert_eq!(super::rejoin_split_paths(args(&["C:\\a", "b", "c.pdf", "C:\\a.pdf"]), exists), args(&["C:\\a b c.pdf", "C:\\a.pdf"]));
assert_eq!(super::rejoin_split_paths(args(&["C:\\a.pdf", "C:\\x", "y.pdf"]), exists), args(&["C:\\a.pdf", "C:\\x y.pdf"]));
@@ -159,9 +156,7 @@ fn a_software_renderer_is_shown_to_the_user() {
fn gpu_setup_avoids_vulkan_and_stretched_resizes_on_windows_and_prefers_low_power() {
let mut native = eframe::NativeOptions::default();
super::configure_gpu(&mut native);
let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &native.wgpu_options.wgpu_setup else {
panic!("default setup creates its own instance")
};
let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &native.wgpu_options.wgpu_setup else { panic!("default setup creates its own instance") };
if std::env::var_os("WGPU_POWER_PREF").is_none() {
assert_eq!(setup.power_preference, eframe::wgpu::PowerPreference::LowPower);
}
@@ -270,15 +265,9 @@ fn a_window_larger_than_the_gpu_limit_gets_a_surface_within_it() {
#[test]
fn surface_fit_never_empties_or_overflows_a_surface() {
use eframe::egui_wgpu::winit::surface_fit;
for (w, h, max) in [
(1, u32::MAX, 8192),
(u32::MAX, 1, 2048),
(u32::MAX, u32::MAX, 16384),
(0, u32::MAX, 8192),
(u32::MAX, 0, 8192),
(5, 7, 0),
(40_000, 3, 1),
] {
for (w, h, max) in
[(1, u32::MAX, 8192), (u32::MAX, 1, 2048), (u32::MAX, u32::MAX, 16384), (0, u32::MAX, 8192), (u32::MAX, 0, 8192), (5, 7, 0), (40_000, 3, 1)]
{
let (fw, fh, scale) = surface_fit(w, h, max);
assert!(fw <= max.max(1) && fh <= max.max(1), "{w} x {h} in {max}: {fw} x {fh}");
// A side that wasn't zero stays non-zero (`Surface::configure` rejects an empty one),
@@ -327,9 +316,7 @@ fn a_gpu_error_while_a_window_is_set_up_is_returned_not_a_panic() {
use eframe::wgpu;
let _gpu = gpu();
let native = super::native_options(false, false, eframe::Renderer::Wgpu);
let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &native.wgpu_options.wgpu_setup else {
panic!("default setup creates its own instance")
};
let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &native.wgpu_options.wgpu_setup else { panic!("default setup creates its own instance") };
let instance = pollster::block_on(native.wgpu_options.wgpu_setup.new_instance());
let options = wgpu::RequestAdapterOptions { power_preference: setup.power_preference, ..Default::default() };
// CI runners have a software adapter (WARP, llvmpipe); a machine without any skips.
@@ -398,8 +385,8 @@ fn pipeline_creation_error_is_returned_and_device_remains_usable() {
eprintln!("skipping pipeline regression: no GPU adapter");
return;
};
let (device, queue) = pollster::block_on(adapter.request_device(&(setup.device_descriptor)(&adapter)))
.expect("the selected adapter must provide a test device");
let (device, queue) =
pollster::block_on(adapter.request_device(&(setup.device_descriptor)(&adapter))).expect("the selected adapter must provide a test device");
native.wgpu_options.wgpu_setup =
egui_wgpu::WgpuSetup::Existing(egui_wgpu::WgpuSetupExisting { instance: instance.clone(), adapter, device, queue });
// Three samples is invalid on every backend, so this reproduces a pipeline error
@@ -519,8 +506,7 @@ fn pick_adapter_keeps_the_integrated_gpu_on_hybrid_laptops() {
fn pick_adapter_prefers_the_discrete_gpu_on_desktops_with_a_monitor_on_each() {
// Issue #445: one monitor on the Intel iGPU, one on the NVIDIA card, no built-in panel.
use eframe::wgpu::DeviceType;
let desktop =
[(INTEL_IGPU.0, INTEL_IGPU.1, DeviceType::IntegratedGpu), (NVIDIA.0, NVIDIA.1, DeviceType::DiscreteGpu), (0, 0, DeviceType::Cpu)];
let desktop = [(INTEL_IGPU.0, INTEL_IGPU.1, DeviceType::IntegratedGpu), (NVIDIA.0, NVIDIA.1, DeviceType::DiscreteGpu), (0, 0, DeviceType::Cpu)];
assert_eq!(super::pick_adapter(&desktop, &[monitor(INTEL_IGPU), monitor(NVIDIA)], None), Some(1));
assert_eq!(super::pick_adapter(&desktop, &[monitor(NVIDIA), monitor(INTEL_IGPU)], None), Some(1));
// A GPU driving no display still loses to one that does.
+5 -18
View File
@@ -18,12 +18,7 @@ fn composite(doc: &mut Document, encoding: &str, w: Vec<Object>, to_unicode: &st
let tu = Object::Ref(doc.add(Object::Stream(Stream::flate(Dict::new(), to_unicode.as_bytes()))));
font(
doc,
vec![
("Subtype", Object::name("Type0")),
("Encoding", enc),
("DescendantFonts", Object::Array(vec![Object::Dict(desc)])),
("ToUnicode", tu),
],
vec![("Subtype", Object::name("Type0")), ("Encoding", enc), ("DescendantFonts", Object::Array(vec![Object::Dict(desc)])), ("ToUnicode", tu)],
)
}
@@ -273,13 +268,10 @@ fn standard_fonts_without_widths_measure_the_glyph_their_differences_name() {
let mut doc = Document::new_empty();
let mut enc = Dict::new();
enc.set(b"BaseEncoding".to_vec(), Object::name("WinAnsiEncoding"));
let diffs =
vec![Object::Int(65), Object::name("W"), Object::Int(87), Object::name("A"), Object::name("uni03A9"), Object::name("not.a.glyph")];
let diffs = vec![Object::Int(65), Object::name("W"), Object::Int(87), Object::name("A"), Object::name("uni03A9"), Object::name("not.a.glyph")];
enc.set(b"Differences".to_vec(), Object::Array(diffs));
let f = font(
&mut doc,
vec![("Subtype", Object::name("Type1")), ("BaseFont", Object::name("Helvetica")), ("Encoding", Object::Dict(enc.clone()))],
);
let f =
font(&mut doc, vec![("Subtype", Object::name("Type1")), ("BaseFont", Object::name("Helvetica")), ("Encoding", Object::Dict(enc.clone()))]);
let m = Metrics::from_dict(&doc, &f);
assert_eq!((m.width(65), m.width(87)), (0.944, 0.667), "A and W swap their widths");
// Omega has no WinAnsi code and the last name reads as nothing: both keep their code's width.
@@ -467,12 +459,7 @@ fn composite_subset_glyphs_of_the_default_width_are_present() {
}
desc.set(
b"W".to_vec(),
Object::Array(vec![
Object::Int(0x55),
Object::Array(vec![Object::Int(333)]),
Object::Int(0x57),
Object::Array(vec![Object::Int(277)]),
]),
Object::Array(vec![Object::Int(0x55), Object::Array(vec![Object::Int(333)]), Object::Int(0x57), Object::Array(vec![Object::Int(277)])]),
);
let f = font(
&mut doc,
+1 -4
View File
@@ -253,10 +253,7 @@ fn numbers_format_like_acrobat() {
assert_eq!(make_number("(7)"), Some(-7.0));
assert_eq!(make_number("abc"), None);
assert_eq!(keystroke(&n(2, 0, 0, "$", true), "Total", "$1,000"), Ok("1000".into()));
assert_eq!(
keystroke(&n(2, 0, 0, "$", true), "Total", "ten"),
Err("The value entered does not match the format of the field [ Total ]".into())
);
assert_eq!(keystroke(&n(2, 0, 0, "$", true), "Total", "ten"), Err("The value entered does not match the format of the field [ Total ]".into()));
// Blank input clears a formatted field (#1323); without a format it is text like any other.
assert_eq!(keystroke(&n(2, 0, 0, "$", true), "Total", " \t"), Ok(String::new()));
assert_eq!(keystroke(&Format::None, "Name", " \t"), Ok(" \t".into()));
+1 -1
View File
@@ -1,7 +1,7 @@
use super::document::{field_object, get_field, get_nth_field_name, noop, num_fields, page_num_get, page_num_set, print, reset_form, submit_form};
use super::format::{printd, printf, printx, scand};
use super::host::{arg, function, host, s, text, text_line};
use super::model::{DISPLAY_HIDDEN, DISPLAY_NO_PRINT, DISPLAY_NO_VIEW, DISPLAY_VISIBLE, Event, Panel, Request};
use super::format::{printd, printf, printx, scand};
use super::*;
// ── app, util, console ──────────────────────────────────────────────────────────────────────
+5 -5
View File
@@ -35,26 +35,26 @@ use boa_engine::realm::Realm;
use boa_engine::{Context, JsError, JsNativeError, JsObject, JsResult, JsString, JsValue, NativeFunction, Source, js_string};
mod document;
mod format;
mod globals;
mod host;
mod model;
mod run;
mod format;
#[cfg(test)]
pub(crate) use format::PRINTD_SCANNED;
use format::{printd, printf, printx, scand};
pub(crate) use globals::menu_item;
use globals::platform;
use host::{arg, as_number, error, function, s, text};
pub use model::{
DISPLAY_HIDDEN, DISPLAY_NO_PRINT, DISPLAY_NO_VIEW, DISPLAY_VISIBLE, DocInfo, Event, FieldState, FieldType, Limits, Outcome, Panel, Request,
};
pub(crate) use run::{CheckedCodeFromStrings, MAX_SCRIPT_BYTES};
#[cfg(not(target_arch = "wasm32"))]
use run::SCRIPT_STACK;
use run::refuse;
pub(crate) use run::{CheckedCodeFromStrings, MAX_SCRIPT_BYTES};
pub use run::{run, run_shared};
#[cfg(test)]
pub(crate) use format::PRINTD_SCANNED;
use format::{printd, printf, printx, scand};
pub mod formcalc;
pub mod xfa;
+11 -25
View File
@@ -173,10 +173,8 @@ fn compressed_object_container_chain_does_not_recurse() {
#[test]
fn compressed_objects_and_indirect_stream_length_still_load() {
let pdf = compressed_length_pdf(
&[(3, 4, 0), (5, 4, 1)],
&[(4, b"<< /Type /ObjStm /N 2 /First 8 /Length 17 >>\nstream\n3 0 5 2 5 (value)\nendstream")],
);
let pdf =
compressed_length_pdf(&[(3, 4, 0), (5, 4, 1)], &[(4, b"<< /Type /ObjStm /N 2 /First 8 /Length 17 >>\nstream\n3 0 5 2 5 (value)\nendstream")]);
let doc = Document::load_mem_with_options(&pdf, LoadOptions { strict: true, ..Default::default() }).unwrap();
assert_eq!(doc.get_object((3, 0)).unwrap().as_i64().unwrap(), 5);
assert_eq!(doc.get_object((5, 0)).unwrap().as_str().unwrap(), b"value");
@@ -187,8 +185,7 @@ fn compressed_objects_and_indirect_stream_length_still_load() {
fn compressed_length_in_a_container_with_an_indirect_length_still_loads() {
// Two hops, as in a valid file: stream 2's /Length (3) is compressed in container 4, whose own /Length (5) is
// a plain indirect integer.
let pdf =
compressed_length_pdf(&[(3, 4, 0)], &[(4, b"<< /Type /ObjStm /N 1 /First 4 /Length 5 0 R >>\nstream\n3 0 5\nendstream"), (5, b"5")]);
let pdf = compressed_length_pdf(&[(3, 4, 0)], &[(4, b"<< /Type /ObjStm /N 1 /First 4 /Length 5 0 R >>\nstream\n3 0 5\nendstream"), (5, b"5")]);
let doc = Document::load_mem_with_options(&pdf, LoadOptions { strict: true, ..Default::default() }).unwrap();
assert_eq!(doc.get_object((3, 0)).unwrap().as_i64().unwrap(), 5);
assert_eq!(doc.get_object((5, 0)).unwrap().as_i64().unwrap(), 5);
@@ -356,9 +353,7 @@ fn label_info(nums: Vec<Object>, kids: Vec<Object>) -> DocInfo {
doc.objects.insert((1, 0), Object::Dictionary(catalog));
doc.trailer.set("Root", Object::Reference((1, 0)));
let mut info = DocInfo {
pages: (1..=3)
.map(|n| PageInfo { width: 200.0, height: 300.0, crop: [0.0, 0.0, 200.0, 300.0], rotation: 0, label: n.to_string() })
.collect(),
pages: (1..=3).map(|n| PageInfo { width: 200.0, height: 300.0, crop: [0.0, 0.0, 200.0, 300.0], rotation: 0, label: n.to_string() }).collect(),
..Default::default()
};
Inspector::new(&doc).fill(&mut info);
@@ -442,11 +437,7 @@ fn page_label_prefix_spaces_survive_public_inspection() {
}
})
.collect();
assert_eq!(
info.pages.iter().map(|p| p.label.clone()).collect::<Vec<_>>(),
expected,
"{prefix:?}, decimal={decimal}, indirect={indirect}"
);
assert_eq!(info.pages.iter().map(|p| p.label.clone()).collect::<Vec<_>>(), expected, "{prefix:?}, decimal={decimal}, indirect={indirect}");
assert!(info.warnings.is_empty(), "{:?}", info.warnings);
assert_eq!(info.title.as_deref(), Some("Metadata title"), "page-prefix decoding must not change metadata normalization");
}
@@ -454,12 +445,9 @@ fn page_label_prefix_spaces_survive_public_inspection() {
#[test]
fn page_label_limits_keep_normal_pdf_numbering() {
for (style, first, expected) in [
("r", 4, ["iv", "v", "vi"]),
("R", 1994, ["MCMXCIV", "MCMXCV", "MCMXCVI"]),
("a", 26, ["z", "aa", "bb"]),
("A", 52, ["ZZ", "AAA", "BBB"]),
] {
for (style, first, expected) in
[("r", 4, ["iv", "v", "vi"]), ("R", 1994, ["MCMXCIV", "MCMXCV", "MCMXCVI"]), ("a", 26, ["z", "aa", "bb"]), ("A", 52, ["ZZ", "AAA", "BBB"])]
{
let info = label_info(vec![Object::Integer(0), label_spec(style, Vec::new(), first)], Vec::new());
assert_eq!(info.pages.iter().map(|p| p.label.as_str()).collect::<Vec<_>>(), expected);
assert!(info.warnings.is_empty(), "{:?}", info.warnings);
@@ -537,9 +525,8 @@ fn page_label_limits_bound_total_custom_output_atomically() {
let mut catalog = Dictionary::new();
catalog.set("PageLabels", Object::Dictionary(tree));
let count = MAX_LABEL_TOTAL_BYTES / MAX_LABEL_BYTES + 1;
let mut pages: Vec<_> = (1..=count)
.map(|n| PageInfo { width: 200.0, height: 300.0, crop: [0.0, 0.0, 200.0, 300.0], rotation: 0, label: n.to_string() })
.collect();
let mut pages: Vec<_> =
(1..=count).map(|n| PageInfo { width: 200.0, height: 300.0, crop: [0.0, 0.0, 200.0, 300.0], rotation: 0, label: n.to_string() }).collect();
let err = Inspector::new(&doc).page_labels(&catalog, &mut pages).unwrap_err();
assert!(err.contains("4 MiB"), "{err}");
assert!(pages.iter().enumerate().all(|(i, p)| p.label == (i + 1).to_string()));
@@ -1491,8 +1478,7 @@ fn xfa_dynamic_render_is_read_from_config_acrobat7_only() {
);
assert_eq!(text(&xdp).as_deref(), Some("required"));
// Only in the data, or nested in the template: no configuration at all.
let xdp =
format!("<xdp:xdp><xfa:datasets><xfa:data>{}</xfa:data></xfa:datasets></xdp:xdp>", config("<dynamicRender>forbidden</dynamicRender>"));
let xdp = format!("<xdp:xdp><xfa:datasets><xfa:data>{}</xfa:data></xfa:datasets></xdp:xdp>", config("<dynamicRender>forbidden</dynamicRender>"));
assert_eq!(text(&xdp), None);
let xdp = format!("<xdp:xdp><template>{}</template></xdp:xdp>", config("<dynamicRender>forbidden</dynamicRender>"));
assert_eq!(text(&xdp), None);
+21 -61
View File
@@ -215,10 +215,7 @@ fn page_panic_retires_shared_generation_and_healthy_pages_use_private_parsers()
// in the shared generation first (then only one parse would happen).
let gate = render_gate(1, true);
*lock(&pool.shared.render_gates) = vec![gate.clone()];
pool.set_queue(vec![
RenderRequest { page: 0, scale: 1.0, ..Default::default() },
RenderRequest { page: 1, scale: 1.0, ..Default::default() },
]);
pool.set_queue(vec![RenderRequest { page: 0, scale: 1.0, ..Default::default() }, RenderRequest { page: 1, scale: 1.0, ..Default::default() }]);
let crashed = receive_before_deadline(&pool);
if gate.claimed.load(Ordering::Acquire) {
gate.entered.wait();
@@ -394,8 +391,7 @@ fn a_failed_page_stays_refused_at_every_scale_and_generation_but_other_pages_ren
let pool = RenderPool::new(Arc::new(ONE_PAGE_TWICE.to_vec()), 1, RenderConfig::default());
let bad = RenderRequest { page: 0, scale: 1.0, tag: 70, ..Default::default() };
lock(&pool.shared.stuck).insert(bad.into());
for req in [bad, RenderRequest { scale: 0.5, tag: 71, ..bad }, RenderRequest { tile: Some(Tile { x: 0, y: 0, w: 8, h: 8 }), tag: 72, ..bad }]
{
for req in [bad, RenderRequest { scale: 0.5, tag: 71, ..bad }, RenderRequest { tile: Some(Tile { x: 0, y: 0, w: 8, h: 8 }), tag: 72, ..bad }] {
pool.set_queue(vec![req]);
let failed = receive_before_deadline(&pool);
assert_eq!(failed.request, req);
@@ -478,14 +474,7 @@ fn worker_reuses_parser_and_releases_source_after_rendering() {
}
assert_eq!(
pool.stats(),
RenderStats {
parser_builds: 1,
page_interpretations: 2,
render_requests: 3,
tile_requests: 0,
text_interpretations: 1,
rasterizations: 2
}
RenderStats { parser_builds: 1, page_interpretations: 2, render_requests: 3, tile_requests: 0, text_interpretations: 1, rasterizations: 2 }
);
drop(pool);
let until = std::time::Instant::now() + std::time::Duration::from_secs(8);
@@ -806,12 +795,8 @@ fn indexed_palettes_over_lab_keep_their_colours() {
// Palette entry 1 is <80 CC B2>: L* = 128/255·100, a* = -100 + 204/255·200,
// b* = -100 + 178/255·200, about Lab (50.2 60 39.6): a warm red.
let indexed = render("/I cs 1 sc 0 0 200 200 re f");
let direct = render(&format!(
"/L cs {} {} {} sc 0 0 200 200 re f",
128.0 / 255.0 * 100.0,
-100.0 + 204.0 / 255.0 * 200.0,
-100.0 + 178.0 / 255.0 * 200.0
));
let direct =
render(&format!("/L cs {} {} {} sc 0 0 200 200 re f", 128.0 / 255.0 * 100.0, -100.0 + 204.0 / 255.0 * 200.0, -100.0 + 178.0 / 255.0 * 200.0));
for (channel, (got, want)) in indexed.iter().zip(direct).enumerate() {
assert!(got.abs_diff(want) <= 1, "channel {channel}: indexed {indexed:?}, direct {direct:?}");
}
@@ -1033,9 +1018,8 @@ fn re_sent_queues_render_each_page_once() {
}
pdf += "trailer << /Root 1 0 R >>\n%%EOF";
let pool = RenderPool::new(Arc::new(pdf.into_bytes()), 3, RenderConfig::default());
let wanted: Vec<RenderRequest> = (0..pages)
.map(|page| RenderRequest { page, kind: RequestKind::Pixels, tile: None, scale: 2.0, tag: 2000, ..Default::default() })
.collect();
let wanted: Vec<RenderRequest> =
(0..pages).map(|page| RenderRequest { page, kind: RequestKind::Pixels, tile: None, scale: 2.0, tag: 2000, ..Default::default() }).collect();
// The canvas's loop: take what arrived, then queue every page still missing whenever
// that list changes (requests already rendering included).
let mut got = vec![0; pages];
@@ -1298,14 +1282,7 @@ fn heavy_vector_fixture_preserves_trailing_text_and_raster_output() {
assert!(text.text.is_some_and(|page| page.plain_text().contains("TRAILING_MARKER")));
assert_eq!(
renderer.stats(),
RenderStats {
parser_builds: 1,
page_interpretations: 1,
render_requests: 2,
tile_requests: 0,
text_interpretations: 1,
rasterizations: 1
}
RenderStats { parser_builds: 1, page_interpretations: 1, render_requests: 2, tile_requests: 0, text_interpretations: 1, rasterizations: 1 }
);
}
@@ -3783,14 +3760,7 @@ fn pages_in_one_object_stream(pages: usize) -> Vec<u8> {
(1, "<< /Type /Catalog /Pages 2 0 R >>".to_string()),
(2, format!("<< /Type /Pages /Kids [{}] /Count {pages} >>", kids.join(" "))),
(3, format!("<< /Length {} >>\nstream\n{content}\nendstream", content.len())),
(
4,
format!(
"<< /Type /ObjStm /N {pages} /First {} /Length {} >>\nstream\n{index}{body}\nendstream",
index.len(),
index.len() + body.len()
),
),
(4, format!("<< /Type /ObjStm /N {pages} /First {} /Length {} >>\nstream\n{index}{body}\nendstream", index.len(), index.len() + body.len())),
] {
offsets.push(pdf.len());
pdf.extend_from_slice(format!("{num} 0 obj\n{obj}\nendobj\n").as_bytes());
@@ -4236,11 +4206,13 @@ fn sampled_functions_with_billions_of_samples_are_refused() {
let mut pdf = b"%PDF-1.7\n1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj\n2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj\n3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 40 40] /Contents 4 0 R /Resources << /Shading << /Sh0 5 0 R >> >> >> endobj\n".to_vec();
pdf.extend_from_slice(format!("4 0 obj << /Length {} >> stream\n", page_content.len()).as_bytes());
pdf.extend_from_slice(page_content);
pdf.extend_from_slice(b"\nendstream endobj\n5 0 obj << /ShadingType 2 /ColorSpace /DeviceGray /Coords [0 0 40 0] /Function 6 0 R >> endobj\n");
pdf.extend_from_slice(
b"\nendstream endobj\n5 0 obj << /ShadingType 2 /ColorSpace /DeviceGray /Coords [0 0 40 0] /Function 6 0 R >> endobj\n",
);
pdf.extend_from_slice(
format!("6 0 obj << /FunctionType 0 /Domain [0 1] /Range [0 1] /Size [1073741824] /BitsPerSample 1 /Filter /FlateDecode /Length {} >> stream\n", bomb.len()).as_bytes(),
format!(
"6 0 obj << /FunctionType 0 /Domain [0 1] /Range [0 1] /Size [1073741824] /BitsPerSample 1 /Filter /FlateDecode /Length {} >> stream\n",
bomb.len()
)
.as_bytes(),
);
pdf.extend_from_slice(&bomb);
pdf.extend_from_slice(b"\nendstream endobj\ntrailer << /Root 1 0 R >>\n%%EOF\n");
@@ -4278,10 +4250,8 @@ fn shadings_with_large_sampled_functions_paint_quickly() {
const SAMPLES: usize = 1 << 21;
let samples = zlib_zeros(SAMPLES);
let function = format!(
"<< /FunctionType 0 /Domain [0 1] /Range [0 1] /Size [{SAMPLES}] /BitsPerSample 8 /Filter /FlateDecode /Length {} >>",
samples.len()
);
let function =
format!("<< /FunctionType 0 /Domain [0 1] /Range [0 1] /Size [{SAMPLES}] /BitsPerSample 8 /Filter /FlateDecode /Length {} >>", samples.len());
// Black ramp on the left half, 30 times over; a red square after it.
let content = "q 0 0 20 40 re W n /Sh0 sh Q\n".repeat(30) + "1 0 0 rg 36 36 4 4 re f";
let mut pdf = b"%PDF-1.7\n1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj\n2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj\n3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 40 40] /Contents 4 0 R /Resources << /Shading << /Sh0 5 0 R >> >> >> endobj\n".to_vec();
@@ -5341,10 +5311,7 @@ fn raw_crop_unit_floor_reciprocal_does_not_trigger_letter_fallback() {
let page = pdf.pages().first().expect("one page");
let (width, height) = page.base_dimensions();
// In f32, the nearest reciprocal of 41 or 47 multiplies back to 0.99999994.
assert!(
width * page.user_unit() >= 1.0 && height * page.user_unit() >= 1.0,
"unit={unit}: floor must not round below one physical point"
);
assert!(width * page.user_unit() >= 1.0 && height * page.user_unit() >= 1.0, "unit={unit}: floor must not round below one physical point");
let info = crate::inspect(Arc::new(bytes), None).expect("inspect the same small crop");
let page = &info.pages[0];
assert!(
@@ -5979,8 +5946,7 @@ fn print_preview_requests_render_with_reading_colors_off() {
/// flash wrong colours at tile seams.
#[test]
fn reading_colors_tiles_match_full_render() {
let mut r =
PageRenderer::new(Arc::new(ONE_PAGE.to_vec()), RenderConfig { reading_colors: ReadingColors::WHITE_ON_BLACK, ..Default::default() });
let mut r = PageRenderer::new(Arc::new(ONE_PAGE.to_vec()), RenderConfig { reading_colors: ReadingColors::WHITE_ON_BLACK, ..Default::default() });
let full = r.render(RenderRequest { page: 0, kind: RequestKind::Pixels, tile: None, scale: 2.0, tag: 0, preview: false });
let tile = Tile { x: 30, y: 40, w: 50, h: 30 };
let part = r.render(RenderRequest { page: 0, kind: RequestKind::Pixels, tile: Some(tile), scale: 2.0, tag: 0, preview: false });
@@ -6342,8 +6308,7 @@ fn spot_colour_images_run_their_tint_transform_once_per_sample_value() {
data.len()
);
let function = format!("<< /FunctionType 4 /Domain [0 1] /Range [0 1 0 1 0 1] /Length {} >>", program.len());
let pdf =
image_cache_pdf("q 130 0 0 70 0 0 cm /A Do Q", "<< /XObject << /A 5 0 R >> >>", &[(&image, &data), (&function, program.as_bytes())]);
let pdf = image_cache_pdf("q 130 0 0 70 0 0 cm /A Do Q", "<< /XObject << /A 5 0 R >> >>", &[(&image, &data), (&function, program.as_bytes())]);
// The count is per thread, and this render runs on this one.
let before = hayro::hayro_interpret::color::tint_transform_runs();
let out = render_first_page(pdf);
@@ -6790,12 +6755,7 @@ endstream endobj
let reference = render(sampled("{ pop 10 sub 4 div }"));
for (x, expected) in [(2, 0), (9, 0), (10, 32), (11, 96), (12, 159), (13, 223), (14, 255), (30, 255)] {
assert!((grey(&native, x) - expected).abs() <= 4, "axial, x {x}: {} instead of {expected}", grey(&native, x));
assert!(
(grey(&native, x) - grey(&reference, x)).abs() <= 4,
"axial, x {x}: native {} vs sampled {}",
grey(&native, x),
grey(&reference, x)
);
assert!((grey(&native, x) - grey(&reference, x)).abs() <= 4, "axial, x {x}: native {} vs sampled {}", grey(&native, x), grey(&reference, x));
}
// An extended radial shading matches the sampled one everywhere.
+2 -4
View File
@@ -415,8 +415,7 @@ fn encoded_pages(pages: &[(lopdf::Object, &[u8])]) -> Pdf {
let pages_id = doc.new_object_id();
let mut kids = Vec::new();
for (encoding, content) in pages {
let font =
doc.add_object(dictionary! { "Type" => "Font", "Subtype" => "Type1", "BaseFont" => "Helvetica", "Encoding" => encoding.clone() });
let font = doc.add_object(dictionary! { "Type" => "Font", "Subtype" => "Type1", "BaseFont" => "Helvetica", "Encoding" => encoding.clone() });
let content = doc.add_object(Stream::new(dictionary! {}, content.to_vec()));
let page = doc.add_object(dictionary! { "Type" => "Page", "Parent" => pages_id, "MediaBox" => vec![Object::Integer(0), Object::Integer(0), Object::Integer(300), Object::Integer(300)], "Resources" => dictionary! {"Font" => dictionary! {"F1" => font}}, "Contents" => content });
kids.push(Object::Reference(page));
@@ -455,8 +454,7 @@ fn the_annex_d2_alias_codes_read_as_an_ordinary_hyphen_and_space() {
(name("MacRomanEncoding"), &b"BT /F1 20 Tf 1 0 0 1 20 150 Tm (a\xcab) Tj ET"[..]),
(differences, &b"BT /F1 20 Tf 1 0 0 1 20 150 Tm (aXbYc) Tj ET"[..]),
]);
let texts =
|page| extract_page(&pdf, page, &InterpreterSettings::default()).unwrap().glyphs.iter().map(|g| g.text.clone()).collect::<Vec<_>>();
let texts = |page| extract_page(&pdf, page, &InterpreterSettings::default()).unwrap().glyphs.iter().map(|g| g.text.clone()).collect::<Vec<_>>();
assert_eq!(texts(0), ["a", "-", "b", " ", "c"], "WinAnsi 0xAD and 0xA0");
assert_eq!(texts(1), ["a", " ", "b"], "MacRoman 0xCA");
assert_eq!(texts(2), ["a", "\u{ad}", "b", "\u{a0}", "c"], "a named glyph keeps its glyph list value");
+4 -18
View File
@@ -489,13 +489,7 @@ fn keyboard_find_step_is_explicit_and_a_late_text_layer_cannot_undo_it() {
let ctx = egui::Context::default();
ctx.input_mut(|i| {
i.events.push(egui::Event::Key {
key: egui::Key::G,
physical_key: None,
pressed: true,
repeat: false,
modifiers: egui::Modifiers::COMMAND,
});
i.events.push(egui::Event::Key { key: egui::Key::G, physical_key: None, pressed: true, repeat: false, modifiers: egui::Modifiers::COMMAND });
});
shortcuts(&mut v, &ctx, Default::default());
@@ -1453,10 +1447,7 @@ fn many_open_documents_share_one_raster_allowance_and_close_releases_handles() {
assert_eq!(app.active_ids().map(|(index, _)| index), Some(5));
assert!(app.views.iter().zip(&expected).all(|(view, (request, dimensions))| {
view.thumbs.len() == 1
&& view
.thumbs
.get(&0)
.is_some_and(|thumb| thumb.tag == request.tag && thumb.tex.size() == [dimensions.0 as usize, dimensions.1 as usize])
&& view.thumbs.get(&0).is_some_and(|thumb| thumb.tag == request.tag && thumb.tex.size() == [dimensions.0 as usize, dimensions.1 as usize])
}));
app.finish_render_frame(&ctx);
@@ -1902,13 +1893,8 @@ fn destinations_set_the_zoom_mode_and_the_point_to_show() {
fn page_text_failure_preserves_valid_search_match_without_jitter() {
let mut v = view(3, PageLayout::Single, true);
v.current = 1;
v.find = Some(Find {
query: "test".into(),
case_query: "test".into(),
matches: vec![(0, 0..4), (1, 5..9)],
current: Some(0),
..Default::default()
});
v.find =
Some(Find { query: "test".into(), case_query: "test".into(), matches: vec![(0, 0..4), (1, 5..9)], current: Some(0), ..Default::default() });
let req = RenderRequest { page: 0, kind: RequestKind::Text, ..Default::default() };
v.last_queue = vec![req];
let ctx = egui::Context::default();
+3 -19
View File
@@ -159,20 +159,8 @@ fn a_started_request_finishes_its_batches_after_focus_moves() {
since: web_time::Instant::now(),
release: Vec::new(),
batches: VecDeque::from([
vec![egui::Event::Key {
key: egui::Key::Tab,
physical_key: None,
pressed: true,
repeat: false,
modifiers: egui::Modifiers::NONE,
}],
vec![egui::Event::Key {
key: egui::Key::Tab,
physical_key: None,
pressed: false,
repeat: false,
modifiers: egui::Modifiers::NONE,
}],
vec![egui::Event::Key { key: egui::Key::Tab, physical_key: None, pressed: true, repeat: false, modifiers: egui::Modifiers::NONE }],
vec![egui::Event::Key { key: egui::Key::Tab, physical_key: None, pressed: false, repeat: false, modifiers: egui::Modifiers::NONE }],
]),
});
}
@@ -811,11 +799,7 @@ fn completed_screenshots_obey_the_admission_deadline_before_success_or_retry() {
callback: None,
region: None,
reply,
since: if expired {
web_time::Instant::now().checked_sub(std::time::Duration::from_secs(10)).unwrap()
} else {
web_time::Instant::now()
},
since: if expired { web_time::Instant::now().checked_sub(std::time::Duration::from_secs(10)).unwrap() } else { web_time::Instant::now() },
geometry,
reserved: geometry.image_bytes().unwrap(),
attempts: 0,
+3 -3
View File
@@ -11,12 +11,12 @@ mod save;
pub use close::CloseRequest;
#[cfg(not(target_arch = "wasm32"))]
pub(crate) use save::in_document_folder;
#[cfg(not(target_arch = "wasm32"))]
pub use save::PendingOverwrite;
pub use save::{SaveTarget, write_atomically};
#[cfg(target_arch = "wasm32")]
pub(crate) use save::download;
#[cfg(not(target_arch = "wasm32"))]
pub(crate) use save::in_document_folder;
pub use save::{SaveTarget, write_atomically};
#[cfg(test)]
pub(crate) use save::{is_mail_temp_copy, save_dialog_folder};
#[cfg(test)]
+4 -13
View File
@@ -279,11 +279,8 @@ fn ordinary_paths_are_not_mail_copies() {
/// A one-page document with a proper xref table.
fn one_page_pdf() -> Vec<u8> {
let objs = [
"<< /Type /Catalog /Pages 2 0 R >>",
"<< /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 200 300] >>",
"<< /Type /Page /Parent 2 0 R >>",
];
let objs =
["<< /Type /Catalog /Pages 2 0 R >>", "<< /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 200 300] >>", "<< /Type /Page /Parent 2 0 R >>"];
let mut out = b"%PDF-1.7\n".to_vec();
let mut offsets = Vec::new();
for (i, o) in objs.iter().enumerate() {
@@ -308,14 +305,8 @@ fn save_commits_the_open_text_box() {
app.open_bytes("a.pdf", None, one_page_pdf()).unwrap();
app.save_override = Some(dest.to_string_lossy().into_owned());
let style = crate::content_ui::default_style();
app.views[0].content.draft = Some(crate::content_ui::TextDraft {
page: 0,
index: None,
rect: [20.0, 20.0, 120.0, 40.0],
text: "Typed text".into(),
style,
focus: true,
});
app.views[0].content.draft =
Some(crate::content_ui::TextDraft { page: 0, index: None, rect: [20.0, 20.0, 120.0, 40.0], text: "Typed text".into(), style, focus: true });
assert!(app.save_active(SaveTarget::InPlace));
let id = app.views[0].id;
+4 -12
View File
@@ -162,10 +162,8 @@ fn lookups_fall_back_to_english() {
#[test]
fn catalog_kinds_are_parsed_and_looked_up() {
let (c, errors) = Catalog::parse(
"# c\n\tHello\tこんにちは\n@id\tfile.save\t保存する\nmenu\tWindows\tウィンドウ群\n@plural\t{n} file|{n} files\t{n} 個\n\n",
1,
);
let (c, errors) =
Catalog::parse("# c\n\tHello\tこんにちは\n@id\tfile.save\t保存する\nmenu\tWindows\tウィンドウ群\n@plural\t{n} file|{n} files\t{n} 個\n\n", 1);
assert!(errors.is_empty(), "{errors:?}");
assert_eq!(c.plain("Hello"), Some("こんにちは"));
assert_eq!(c.id("file.save"), Some("保存する"));
@@ -222,14 +220,8 @@ fn catalogs_handle_escapes_crlf_and_distinct_contexts() {
#[test]
fn broken_catalog_falls_back_to_english() {
static BROKEN: LangInfo = LangInfo {
code: "broken",
name: "Broken test catalog",
source: "malformed\n\\",
plural: plural_none,
rtl: false,
catalog: OnceLock::new(),
};
static BROKEN: LangInfo =
LangInfo { code: "broken", name: "Broken test catalog", source: "malformed\n\\", plural: plural_none, rtl: false, catalog: OnceLock::new() };
assert_eq!(tr(Lang(&BROKEN), "File"), "File");
assert_eq!(trn(Lang(&BROKEN), 2, "{n} page", "{n} pages"), "2 pages");
}
+1 -1
View File
@@ -68,9 +68,9 @@ mod state;
mod tools;
mod workflows;
pub(crate) use app::{MAX_AUTHOR_CHARS, copy_refused, date_text_for_pdf, print_refused};
#[cfg(not(target_arch = "wasm32"))]
pub(crate) use app::same_file;
pub(crate) use app::{MAX_AUTHOR_CHARS, copy_refused, date_text_for_pdf, print_refused};
use canvas::autoscroll;
use canvas::crop;
use canvas::fling;
+1 -1
View File
@@ -2,8 +2,8 @@
use egui::{Align2, Color32, CornerRadius, Rect, Response, Sense, Stroke, vec2};
use crate::theme::{self, Tokens};
use crate::PdfCraftApp;
use crate::theme::{self, Tokens};
pub(super) mod icon_data;
pub mod icons;
+3 -3
View File
@@ -23,17 +23,17 @@ mod session;
mod table;
mod view;
pub use files::{Columns, CombineFile, CombineView, ConflictPreview, Lock, SortKey};
#[cfg(not(target_arch = "wasm32"))]
pub(crate) use files::Incoming;
pub use files::{Columns, CombineFile, CombineView, ConflictPreview, Lock, SortKey};
pub(crate) use files::{Preview, RowAction};
use files::{Snapshot, UnlockPrompt};
#[cfg(test)]
pub(crate) use parts::{Part, moved_order, moved_pages, removed_pages, step_to};
#[cfg(not(target_arch = "wasm32"))]
pub(crate) use parts::ago;
pub(crate) use parts::range_of;
#[cfg(test)]
pub(crate) use parts::{Part, moved_order, moved_pages, removed_pages, step_to};
#[cfg(test)]
use parts::{title_of, utc_stamp};
pub(crate) use view::page;
+1 -1
View File
@@ -20,10 +20,10 @@ use crate::model::{
};
use crate::text::{self, Block, Face, Span};
mod common;
mod draw;
mod field;
mod flow;
mod common;
mod items;
mod measure;
mod pages;
+1 -1
View File
@@ -1,5 +1,5 @@
use super::field::auto_check_reserve;
use super::common::clamp_opt;
use super::field::auto_check_reserve;
use super::*;
impl Layouter<'_> {
+4 -4
View File
@@ -18,17 +18,17 @@ use std::io::Write as _;
use pdfcraft_cos::{Dict, Document, ObjRef, Object, PdfString};
use pdfcraft_forms::{FieldKind, FieldValue};
mod fdf;
mod common;
mod fdf;
mod xfdf;
#[cfg(test)]
use common::{MAX_DEPTH, MAX_XML_DEPTH, arr, nums_of, parse_hex, text_of, xml_nesting_depth};
use common::{check_form_xml_depth, esc, parse_form_xml, walk_xfdf, xml_name};
pub use fdf::export_fdf;
use fdf::{ImportBudget, fdf_body, import_fdf, walk_fdf};
#[cfg(test)]
use fdf::{MAX_FDF_BYTES, MAX_FDF_OBJECTS};
#[cfg(test)]
use common::{MAX_DEPTH, MAX_XML_DEPTH, arr, nums_of, parse_hex, text_of, xml_nesting_depth};
use common::{check_form_xml_depth, esc, parse_form_xml, walk_xfdf, xml_name};
pub use xfdf::export_xfdf;
#[cfg(test)]
use xfdf::{LOCKED, find_by_name};