forked from 1b-agent/opencadstudio-upstream
fix: harden the issue-fix wave after full adversarial review
Five reviewers (PDF, snap, commands, otrack/help, printing) covered the eight issue-fix commits; every blocker and major is fixed here. Printing (#1261 follow-up): - printto params now quote the printer name and pad the empty driver/ port slots handlers substitute ("Microsoft Print to PDF" was split into three arguments and the job silently lost). - Level-2 enumeration also merges when the level-4 list omits the configured default, not only when it is empty; a level-2 error no longer discards the default-printer merge. - The printer list loads in a background task instead of blocking the UI thread (level-2 queries can wait out RPC timeouts). - CTB registration: collisions keep the existing file but now say so, and only container-parsed tables are registered (the permissive zlib heuristic stays session-only so junk cannot persist). Snapping (#1030/#1319 follow-up): - Edge-wire key_vertices gain NaN separators: junctions between unrelated mesh edges no longer fabricate phantom midpoints. - The wire cap counts segments (not separator points) and decimates instead of dropping, so dense meshes keep partial endpoint coverage instead of losing snap entirely. - f64 endpoint recovery is a one-shot per-wire map instead of an O(points x geoms) rescan on every mouse move. Commands (#1082 class): the same typed-value-on-web bug also hit CYLINDER/BOX/WEDGE/CONE/PYRAMID heights, HELIX final height (wrong value, not just dropped), and SWEEP reference/new lengths — all now commit as text at exactly those steps, each pinned by a regression test that fails without the override (plus the missing native-route twin for EXTRUDE). PDF (#702 follow-up): heavy CTB pens bypass the Form XObject (their half-width exceeds the /BBox SDF margin and was flat-chopped), CTM scale entries round to 4 significant digits (0.01 quantized small text by ~1%), degenerate quads skip emission, the atlas snapshot is taken once per export instead of per text entity, and the rounding comments no longer conflate page points with glyph-plane units. OTRACK (#1313 follow-up): the guide's polar quantization diverges from the snapper's drafting-gated polar during window-corner drags — documented; an orphaned grid-step doc block is reunited with its function.
This commit is contained in:
1 parent
5ea4294d3d
commit
d135b15ab6
18 files changed
+1326
-138
No files matched your search
@@ -11,6 +11,7 @@
|
||||
use OpenCADStudio::io::pdf_export::{
|
||||
render_pdf_bytes, PdfPageInput, PdfPlotOptions, PlotContent, PlotWire,
|
||||
};
|
||||
use OpenCADStudio::io::plot_style::{LW_TABLE, PlotStyleTable};
|
||||
use OpenCADStudio::scene::model::hatch_model::{HatchModel, HatchPattern, PatFamily};
|
||||
use OpenCADStudio::scene::pipeline::text_gpu::push_glyph_vertices;
|
||||
use OpenCADStudio::scene::text::glyph_quads::layout_glyph_quads;
|
||||
@@ -153,6 +154,82 @@ fn stroke_text_page_size_is_bounded() {
|
||||
);
|
||||
}
|
||||
|
||||
/// Heavy-pen (CTB lineweight override) leg: an absolute pen is arbitrary pt and
|
||||
/// can exceed the glyph Form XObject /BBox's 1.5-unit SDF spread margin
|
||||
/// (2.5 mm text + 1.0 mm pen → 1.79-unit half-width), squaring round caps off
|
||||
/// at the tile edge. Heavy-pen entities must bypass the Forms and stroke
|
||||
/// directly in page space, while the default-pen export of the same page keeps
|
||||
/// its Form replay (and size class).
|
||||
#[test]
|
||||
fn heavy_pen_text_bypasses_forms_and_light_pen_sizes_hold() {
|
||||
let heavy_ctb = {
|
||||
let mut ctb = PlotStyleTable::identity("heavy-pen.ctb");
|
||||
let one_mm = LW_TABLE.iter().position(|&mm| mm == 1.0).unwrap() as u8;
|
||||
let entry = &mut ctb.aci_entries[1];
|
||||
entry.lineweight = one_mm;
|
||||
entry.color = Some([0, 0, 0]);
|
||||
ctb
|
||||
};
|
||||
// The same 200-entity stroke-text page as the bounded leg above, with the
|
||||
// wires on ACI 1 so the CTB's 1.0 mm pen applies.
|
||||
let wires: Vec<PlotWire> = (0..200)
|
||||
.map(|i| {
|
||||
let x = 10.0 + (i % 5) as f64 * 40.0;
|
||||
let y = 10.0 + (i / 5) as f64 * 7.0;
|
||||
let mut wire = text_wire(
|
||||
"txt",
|
||||
"DIMENSION TEXT 12345.6789 - TEXT ANNOTATION LINE",
|
||||
[x, y, 0.0],
|
||||
2.5,
|
||||
);
|
||||
wire.wire.aci = 1;
|
||||
wire
|
||||
})
|
||||
.collect();
|
||||
let glyph_quads: usize = wires.iter().map(|w| w.wire.text_verts.len() / 6).sum();
|
||||
let page = a4_page(wires, Vec::new());
|
||||
|
||||
let heavy =
|
||||
render_pdf_bytes(std::slice::from_ref(&page), Some(&heavy_ctb)).expect("heavy export");
|
||||
println!(
|
||||
"heavy-pen (1.0 mm CTB) stroke-text 200-entity A4 page: {} bytes for {} glyph quads",
|
||||
heavy.len(),
|
||||
glyph_quads
|
||||
);
|
||||
assert!(heavy.starts_with(b"%PDF"), "not a PDF");
|
||||
assert!(
|
||||
heavy.len() > 100_000,
|
||||
"heavy-pen text page suspiciously small: {}",
|
||||
heavy.len()
|
||||
);
|
||||
// The bypass engaged: zero glyph Form `/Do` replays in the heavy render.
|
||||
// (Page content streams are uncompressed, so the operator is greppable.)
|
||||
let do_count = |bytes: &[u8]| bytes.windows(3).filter(|w| w == b" Do").count();
|
||||
assert_eq!(
|
||||
do_count(&heavy),
|
||||
0,
|
||||
"heavy-pen glyphs still replay clipped Form XObjects"
|
||||
);
|
||||
|
||||
// Light-pen regression fence: the same page without a plot style keeps
|
||||
// every glyph on the Form path (one `/Do` per quad) and its size class.
|
||||
let light = render_pdf_bytes(std::slice::from_ref(&page), None).expect("light export");
|
||||
println!(
|
||||
"same page without CTB: {} bytes ({} Form /Do replays)",
|
||||
light.len(),
|
||||
do_count(&light)
|
||||
);
|
||||
assert!(
|
||||
do_count(&light) >= glyph_quads,
|
||||
"Form glyph replay vanished from the light path"
|
||||
);
|
||||
assert!(
|
||||
light.len() < 2_000_000,
|
||||
"light-pen text page regressed to {} bytes",
|
||||
light.len()
|
||||
);
|
||||
}
|
||||
|
||||
/// Pattern hatch + dense polyline comparison leg: identifies which content
|
||||
/// type dominates a mixed page. ANSI31-style 45° hatch over an A4-sized rect.
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user