mirror of
https://github.com/1j01/textual-paint.git
synced 2024-12-23 14:51:50 +03:00
Got it working
It handles the pathological character grid test case SVG I devised, as well as loading the SVG as saved by the app. It's a little weird that I managed to get the pathological case working before the simple rigid grid, but it was what I was shooting for, and the main problem with the rigid grid was the spanned rects, which I didn't think of when making the test case SVG. It does have one problem left; characters that are wider than a cell, when saved as SVG, take up two cells, but in my SVG loading code, they're just placed in one cell, so, when saving and loading, it shifts content to the right of the wide character rightwards, expanding the region of the background from the wide character's cell. But it converges now.
This commit is contained in:
parent
ee224d1a82
commit
14725279c9
@ -1266,13 +1266,22 @@ class AnsiArtDocument:
|
|||||||
def rect_center(rect: ET.Element, coord_attrib: str) -> float:
|
def rect_center(rect: ET.Element, coord_attrib: str) -> float:
|
||||||
return float(rect.attrib[coord_attrib]) + float(rect.attrib["width" if coord_attrib == "x" else "height"]) / 2
|
return float(rect.attrib[coord_attrib]) + float(rect.attrib["width" if coord_attrib == "x" else "height"]) / 2
|
||||||
for (coord_attrib, min_rect_size) in [("x", min_width), ("y", min_height)]:
|
for (coord_attrib, min_rect_size) in [("x", min_width), ("y", min_height)]:
|
||||||
tracks = [Track([rect], rect_center(rect, coord_attrib), rect_center(rect, coord_attrib)) for rect in rects]
|
# size_attrib = "width" if coord_attrib == "x" else "height"
|
||||||
|
# Have to ignore rects that span multiple cells, since their centers can be half-off the grid
|
||||||
|
# of cell-sized rect centers (which is normally half-off from the grid of cell corners).
|
||||||
|
max_rect_size = min_rect_size * 1.5
|
||||||
|
tracks = [Track([rect], rect_center(rect, coord_attrib), rect_center(rect, coord_attrib)) for rect in rects if float(rect.attrib["width" if coord_attrib == "x" else "height"]) <= max_rect_size]
|
||||||
joined = True
|
joined = True
|
||||||
while joined and len(tracks) > 1:
|
while joined and len(tracks) > 1:
|
||||||
joined = False
|
joined = False
|
||||||
for i in range(len(tracks)):
|
for i in range(len(tracks)):
|
||||||
for j in range(i + 1, len(tracks)):
|
for j in range(i + 1, len(tracks)):
|
||||||
max_offset = min_rect_size * 0.4
|
# The cell spacing will be at least min_rect_size, probably.
|
||||||
|
# However, if we join columns that are one cell apart, we'll
|
||||||
|
# fail to measure the cell spacing, it'll be too big.
|
||||||
|
# We only want to join rects within a single column.
|
||||||
|
max_offset = min_rect_size * 0.9
|
||||||
|
"""
|
||||||
# i_min--j_min--i_max--j_max
|
# i_min--j_min--i_max--j_max
|
||||||
# (always join)
|
# (always join)
|
||||||
# or
|
# or
|
||||||
@ -1293,6 +1302,10 @@ class AnsiArtDocument:
|
|||||||
ranges_overlap = (i_min <= j_min <= i_max) or (j_min <= i_min <= j_max)
|
ranges_overlap = (i_min <= j_min <= i_max) or (j_min <= i_min <= j_max)
|
||||||
ends_near = min(abs(i_max - j_min), abs(j_max - i_min)) <= max_offset
|
ends_near = min(abs(i_max - j_min), abs(j_max - i_min)) <= max_offset
|
||||||
if ranges_overlap or ends_near:
|
if ranges_overlap or ends_near:
|
||||||
|
"""
|
||||||
|
i_center = (tracks[i].min_center + tracks[i].max_center) / 2
|
||||||
|
j_center = (tracks[j].min_center + tracks[j].max_center) / 2
|
||||||
|
if abs(i_center - j_center) <= max_offset:
|
||||||
tracks[i] = join_tracks(tracks[i], tracks[j])
|
tracks[i] = join_tracks(tracks[i], tracks[j])
|
||||||
del tracks[j]
|
del tracks[j]
|
||||||
joined = True
|
joined = True
|
||||||
|
Loading…
Reference in New Issue
Block a user