* M1: Crop image from the Object menu, the right-click menu and the image fill row (#1464)
* M1: crop mode shows the image dimmed outside the layer and heavier crop marks (#1464)
* M1: the handle overlay draws gradients and crops in their own helpers (#1464)
- An image a layer or style still shows can't be removed: removing it and
putting other bytes under its key would swap the picture that layer
shows, which giving the key other bytes directly can't. A batch made by
the diff stops using an image (node changes, then styles) before it
removes it; an undo keeps the changes that apply, so its image may stay.
- Restore and replay leave out the image entries history written under
older rules can't apply, using one method shared with the undo history
(Replica::apply_kept, extracted from history.rs). It is exact for every
image rule, including removals in use and replacements, and leaves out
only image entries: any other change that doesn't apply is still an
error. The image-only filter it replaces is gone.
- A server whose restore or replay left image entries out, or whose saved
log puts images, catches every resuming client up with its snapshot,
including one at the same sequence number.
- Tests: an_image_in_use_cannot_be_removed,
an_image_no_longer_in_use_can_be_removed, undoing_an_image_layer_still_works,
a_restart_replays_past_a_logged_removal_of_an_image_in_use,
a_resume_after_history_was_left_out_catches_up_with_the_snapshot,
a_resume_after_a_clean_restart_catches_up_with_the_log,
a_snapshot_with_a_broken_layer_change_still_fails_to_open.
- Docs: collab-protocol.md, collaboration-parity.md.
- without_refused_images judges each image entry against the document it
applies to and the batch's earlier entries (image_for, shared with
apply): a logged put of other bytes under a key the replay state holds
is left out, so a restart no longer stops there and drops the rest of
the log.
- Server::restore keeps its saved log only when the log puts no images:
a resuming client may already hold other bytes under a logged key, which
the restored state can't check, so clients catch up with the checked
snapshot instead.
- Tests: a_restart_replays_past_a_logged_image_replacement,
a_client_resuming_past_a_refused_image_in_the_saved_log_catches_up,
a_client_resuming_past_a_replaced_image_in_the_saved_log_catches_up.
- Docs: collab-protocol.md, collaboration-parity.md.