Putting the frame in prims() also made it a TRIM/EXTEND edge, an object snap
target and dimension geometry. prims() is back to nothing for it, the extents
arm is restored, and select::hit_polylines adds the frame's outline for picking
(none for a frame with no width or height or a bad corner).
Tests: clicking_an_ole_frame_edge_selects_it (now also a frame with no width),
ole_frame_is_not_a_trim_edge_or_snap_target.
ALIGN builds its matrix from two angles that agree only to rounding, so a large
scale leaves a rotation part of about scale * 1e-16 that an absolute 1e-12 bound
refused as a turn. The bound now grows with the scale; a real turn is still refused.
Test: ole_frame_accepts_a_large_scale_with_rounding_noise_in_its_rotation.
ARRAYPATH with align and polar arrays that rotate items refused part way, leaving the earlier copies in the drawing. Every copy's matrix is now checked before the first copy is made. The refusal text names the other unsupported transforms. Test: arraypath_refuses_before_adding_any_copy.
ole_frame_accepts took only a translation, so SCALE on a selection with a frame failed as a whole. A uniform positive scale keeps the frame axis-aligned and upper-left, so the corner rewrite handles it; rotation and mirroring are still refused. Tests: scale_carries_an_ole_frame_with_the_rest_of_the_selection, mocoro_scales_an_ole_frame, ole_frame_accepts_translations_and_uniform_positive_scales_only.
MOCORO refuses a rotate or scale step on an OLE frame up front, before an earlier move or copy
is applied. refuse_ole_frames ignores a frame on a locked layer for in-place edits, as
edit_entities does. Tests: mocoro_refuses_before_it_changes_anything,
a_locked_ole_frame_does_not_block_an_in_place_rotation.
The data layout is only known when its corners match the frame's groups; any other
header is left byte-identical while the tags still move. Test: move_leaves_ole_data_that_is_not_the_frames_corners_alone.
The OLE data (310 groups) starts with the frame's four corners. MOVE shifted groups 10/20/11/21 only, so
a DXF save wrote new corner groups beside a data header with the old position. The transform now
rewrites those doubles (x, y; z kept) in the decoded hex, keeping each chunk's length; malformed or
short data is left untouched.
ole_frame read 10/20 and 11/21 from inside 102 groups; it now skips them as the DXF reader does.
A window-selected OLE2FRAME was left in place by MOVE/COPY. A DWG save writes the position from
the corner groups (checked by write + read-back), so MOVE/COPY now shift them; transforms that
would not keep it axis aligned return an error before anything changes.