Measure: add distance, perimeter and area tools (#208)

* M12: add calibrated 2D measurement tools

* M12: harden measurement tools for landing (#208)

Bounded snap targets (endpoints only for accepted segments, page-wide cap),
lenient extraction (deep q nesting and undecodable streams are skipped and
reported), per-page snap cache, measure::list reports unsupported entries
instead of failing, closed polygons with a repeated vertex, printable unit
labels (m²), cached panel listing, WinAnsi captions, indirect /VP kept,
measure.export skipped in the command test like other pickers, missing
translations, honest parity (scale and distance partial) and ROADMAP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Ayan
2026-10-08 00:38:57 -04:00
committed by GitHub
co-authored by Claude Opus 5.5 Brandon Thomas
parent 77893e8ab3
commit 6974c6550d
32 changed files with 2458 additions and 55 deletions
+35 -35
View File
@@ -4139,11 +4139,11 @@ title = "Distance measuring tool"
area = "E"
tier = "P2"
milestone = "M12"
status = "planned"
commands = []
tools = []
evidence = []
notes = ""
status = "partial"
commands = ["measure.distance"]
tools = ["measure_distance"]
evidence = ["crates/automation/tests/automation.rs::measurements_calibrate_draw_save_reopen_and_export", "crates/measure/src/tests.rs::calibrated_lengths_concave_areas_and_axis_scales", "crates/ui-egui/tests/control.rs::measurement_tools_draw_live_calibrate_save_and_export"]
notes = "Two-point distance annotations with saved numeric captions and rectilinear scales. Partial: only single-unit decimal formats; compound (ft-in) and fractional formats are not supported (listed as unsupported, data kept), no leader lines or caption placement options, geospatial scales unsupported, and interop with Acrobat-authored measurements (reading theirs, Acrobat reading ours) is untested."
[[feature]]
id = "comment.measure-perimeter"
@@ -4151,11 +4151,11 @@ title = "Perimeter measuring tool"
area = "E"
tier = "P2"
milestone = "M12"
status = "planned"
commands = []
tools = []
evidence = []
notes = ""
status = "shipped"
commands = ["measure.perimeter"]
tools = ["measure_perimeter"]
evidence = ["crates/automation/tests/automation.rs::measurements_calibrate_draw_save_reopen_and_export", "crates/measure/src/tests.rs::calibrated_lengths_concave_areas_and_axis_scales", "crates/ui-egui/tests/control.rs::measurement_tools_draw_live_calibrate_save_and_export"]
notes = "Connected-line lengths with click vertices and double-click/Enter finish. Repeat the first point to include a closing edge. Saved standard PolyLineDimension annotations."
[[feature]]
id = "comment.measure-area"
@@ -4163,11 +4163,11 @@ title = "Area measuring tool"
area = "E"
tier = "P2"
milestone = "M12"
status = "planned"
commands = []
tools = []
evidence = []
notes = ""
status = "shipped"
commands = ["measure.area"]
tools = ["measure_area"]
evidence = ["crates/automation/tests/automation.rs::measurements_calibrate_draw_save_reopen_and_export", "crates/measure/src/tests.rs::calibrated_lengths_concave_areas_and_axis_scales", "crates/ui-egui/tests/control.rs::measurement_tools_draw_live_calibrate_save_and_export"]
notes = "Simple polygon areas, including concave boundaries and either winding. Self-intersecting boundaries are refused. Saved PolygonDimension annotations; no 3D surface measurement."
[[feature]]
id = "comment.measure-scale"
@@ -4175,11 +4175,11 @@ title = "Scale ratio and calibration per viewport"
area = "E"
tier = "P2"
milestone = "M12"
status = "planned"
commands = []
tools = []
evidence = []
notes = ""
status = "partial"
commands = ["measure.scale"]
tools = ["measure_scale"]
evidence = ["crates/measure/src/tests.rs::viewport_precedence_first_point_user_unit_and_roundtrip", "crates/measure/src/tests.rs::coordinates_roundtrip_for_crop_rotation_and_user_unit", "crates/automation/tests/automation.rs::measurements_calibrate_draw_save_reopen_and_export", "crates/ui-egui/tests/control.rs::measurement_tools_draw_live_calibrate_save_and_export"]
notes = "Persistent rectangular viewports with last-containing-viewport precedence, numeric scale and two-point calibration. First vertex selects the scale; prior annotations retain theirs. Partial: single-unit decimal rectilinear scales only; compound (ft-in), fractional and differing distance units can't be authored or imported, no viewport editing/removal UI, and interop with Acrobat's scale ratio dialog and its saved viewports is untested."
[[feature]]
id = "comment.measure-snap"
@@ -4187,11 +4187,11 @@ title = "Snap to paths, endpoints, midpoints and intersections"
area = "E"
tier = "P2"
milestone = "M12"
status = "planned"
commands = []
tools = []
evidence = []
notes = ""
status = "shipped"
commands = ["measure.snap"]
tools = ["measure_snap"]
evidence = ["crates/automation/tests/automation.rs::measurement_snap_tool_covers_all_targets", "crates/measure/src/tests.rs::nested_forms_transforms_curves_and_cycles_are_bounded", "crates/measure/src/tests.rs::snap_paths_endpoints_midpoints_and_intersections"]
notes = "Paths, endpoints, midpoints and intersections of painted vector geometry, including transformed Form XObjects. Cubics flattened to 0.2 user units. Bounded extraction and dense-intersection limits are reported. Raster/text outlines, clipping and optional-content visibility are not interpreted."
[[feature]]
id = "comment.measure-info-panel"
@@ -4199,11 +4199,11 @@ title = "Measurement info panel"
area = "E"
tier = "P2"
milestone = "M12"
status = "planned"
commands = []
tools = []
evidence = []
notes = ""
status = "shipped"
commands = ["measure.info"]
tools = ["measure_info", "measure_list"]
evidence = ["crates/automation/tests/automation.rs::measurements_calibrate_draw_save_reopen_and_export", "crates/ui-egui/tests/control.rs::measurement_tools_draw_live_calibrate_save_and_export"]
notes = "Live value, units, X/Y deltas, angle and selected scale while drawing; saved measurements can be selected from the panel. Rectilinear 2D readings only."
[[feature]]
id = "comment.measure-export"
@@ -4211,11 +4211,11 @@ title = "Export measurements as CSV"
area = "E"
tier = "P3"
milestone = "M12"
status = "planned"
commands = []
tools = []
evidence = []
notes = ""
status = "shipped"
commands = ["measure.export"]
tools = ["measure_export"]
evidence = ["crates/automation/tests/automation.rs::measurements_calibrate_draw_save_reopen_and_export", "crates/measure/src/tests.rs::measurement_csv_quotes_newlines_and_blocks_formula_cells", "crates/ui-egui/tests/control.rs::measurement_tools_draw_live_calibrate_save_and_export"]
notes = "Atomic CSV export of page, annotation index, type, numeric value, unit, label, author and scale. Quotes embedded delimiters and prefixes spreadsheet formula triggers."
[[feature]]
id = "comment.geospatial"