Fix Free-Form Select behavior when melding with negative coordinates

This commit is contained in:
Isaiah Odhner 2023-09-12 20:16:55 -04:00
parent 96fe28269d
commit 08847ca91b
3 changed files with 19 additions and 5 deletions

View File

@ -184,7 +184,6 @@ To preview ANSI art files in file managers like Nautilus, Thunar, Nemo, or Caja,
- The canvas flickers when zooming in with the Magnifier tool.
- Some languages don't display correctly.
- Large files can make the program very slow, as can magnifying the canvas. There is a 500 KB limit when opening files to prevent it from freezing.
- Free-Form Select stamping/finalizing is incorrect when the selection is off-screen to the left or top.
- The status bar description can be left blank when selecting a menu item. (I think the `Leave` event can come after closing, once the mouse moves.)
- Menu items like Copy/Cut/Paste are not grayed out when inapplicable. Only unimplemented items are grayed out.
- ANSI files (.ans) are treated as UTF-8 when saving and loading, rather than CP437 or Windows-1252 or any other encodings. Unicode is nice and modern terminals support it, but it's not the standard for ANSI files. There isn't really a standard for ANSI files.

View File

@ -1106,4 +1106,20 @@ class Selection:
target_region = self.region.intersection(Region(0, 0, document.width, document.height))
source_region = Region(target_region.x - self.region.x, target_region.y - self.region.y, self.contained_image.width, self.contained_image.height)
document.copy_region(source=self.contained_image, source_region=source_region, target_region=target_region, mask=self.mask)
# Offset mask due to account for the intersection.
# This is probably not the best way (or place) to do this.
# If refactoring, make sure to run:
# pytest -k test_free_form_select_meld_negative_coords
# (and then all the tests)
offset = target_region.offset - self.region.offset
if self.mask:
def sample(x: int, y: int) -> bool:
try:
return self.mask[y + offset.y][x + offset.x]
except IndexError:
return False
mask = [[sample(x, y) for x in range(source_region.width)] for y in range(source_region.height)]
else:
mask = None
document.copy_region(source=self.contained_image, source_region=source_region, target_region=target_region, mask=mask)

View File

@ -289,9 +289,6 @@ def test_free_form_select(snap_compare: SnapCompareType):
assert snap_compare(PAINT, run_before=automate_app, terminal_size=LARGER)
# Don't run, so that it doesn't overwrite the snapshot with --snapshot-update
# You can run it to see the diff, but it's disabled to prevent accidentally committing a bad snapshot.
@pytest.mark.xfail(run=False, reason="The Free-Form Select tool is currently buggy, melding incorrectly when off-screen to the left/top, but I've contrived the correct output for the test by disabling the deselect step at the end of automate_app and disabling the selection's border rendering in Canvas.render_line.")
def test_free_form_select_meld_negative_coords(snap_compare: SnapCompareType):
async def automate_app(pilot: Pilot[None]):
await click_by_attr(pilot, "ToolsBox Button", "tooltip", "Fill With Color")
@ -301,7 +298,9 @@ def test_free_form_select_meld_negative_coords(snap_compare: SnapCompareType):
await drag(pilot, '#editing_area', [Offset(19, 1), Offset(19, 1), Offset(18, 2), Offset(17, 2), Offset(15, 3), Offset(13, 4), Offset(6, 6), Offset(2, 8), Offset(0, 10), Offset(3, 2), Offset(2, 0), Offset(2, 1), Offset(2, 2), Offset(3, 2), Offset(5, 2), Offset(14, 14), Offset(1, 14), Offset(1, 13), Offset(4, 13), Offset(8, 12), Offset(12, 11), Offset(16, 11), Offset(20, 10), Offset(22, 10), Offset(23, 9), Offset(24, 9), Offset(25, 9), Offset(26, 9), Offset(26, 8), Offset(25, 8), Offset(23, 7), Offset(19, 6), Offset(15, 6), Offset(11, 5), Offset(6, 3), Offset(3, 2), Offset(2, 1), Offset(2, 0), Offset(3, 0), Offset(3, 0)])
await drag(pilot, '#canvas', [Offset(13, 8), Offset(13, 8), Offset(12, 8), Offset(12, 7), Offset(12, 6), Offset(11, 6), Offset(11, 5), Offset(10, 5), Offset(10, 4), Offset(9, 4), Offset(8, 3), Offset(8, 3)])
await pilot.press('ctrl+i')
await pilot.pause(0.5)
await pilot.click('#editing_area', offset=Offset(0, 20)) # deselect
await pilot.pause(0.5)
assert snap_compare(PAINT, run_before=automate_app, terminal_size=LARGER)