add implicit_closed arg to read_point_list()

The process for closing a point list depends on the delta type, so it
needs to happen at read time. However, paths aren't implicity closed, so
it needs to be an input option.
master
Jan Petykiewicz 3 years ago
parent 48d52f56c7
commit fd9f16d705

@ -1500,12 +1500,16 @@ class ArbitraryRepetition:
return 'ArbitraryRepetition: x{} y{})'.format(self.x_displacements, self.y_displacements)
def read_point_list(stream: io.BufferedIOBase) -> List[List[int]]:
def read_point_list(stream: io.BufferedIOBase,
implicit_closed: bool,
) -> List[List[int]]:
"""
Read a point list from a stream.
Args:
stream: Stream to read from.
implicit_closed: If true, the source point list is assumed to be implicitly
closed, and will be explicitly closed in the return value.
Returns:
Point list of the form `[[x0, y0], [x1, y1], ...]`
@ -1517,36 +1521,22 @@ def read_point_list(stream: io.BufferedIOBase) -> List[List[int]]:
list_len = read_uint(stream)
if list_type == 0:
points = []
dx, dy = 0, 0
for i in range(list_len):
point = [0, 0]
n = read_sint(stream)
if n == 0:
raise InvalidDataError('Zero-sized 1-delta')
point = [0, 0]
point[i % 2] = n
points.append(point)
if i % 2:
dy += n
else:
dx += n
points.append([-dx, 0])
points.append([0, -dy])
elif list_type == 1:
points = []
dx, dy = 0, 0
for i in range(list_len):
point = [0, 0]
n = read_sint(stream)
if n == 0:
raise Exception('Zero-sized 1-delta')
point = [0, 0]
point[(i + 1) % 2] = n
points.append(point)
if i % 2:
dx += n
else:
dy += n
points.append([0, -dy])
points.append([-dx, 0])
elif list_type == 2:
points = [ManhattanDelta.read(stream).as_list() for _ in range(list_len)]
elif list_type == 3:
@ -1567,6 +1557,28 @@ def read_point_list(stream: io.BufferedIOBase) -> List[List[int]]:
points.append([x, y])
else:
raise InvalidDataError('Invalid point list type')
if not implicit_closed:
return points
if _USE_NUMPY:
dx, dy = numpy.sum(points, axis=0)
else:
dx = sum(x for x, _y in points)
dy = sum(y for _x, y in points)
if list_type == 0:
points += [[-dx, 0], [0, -dy]]
elif list_type == 1:
points += [[0, -dy], [-dx, 0]]
elif list_type == 2:
assert (dx == 0) or (dy == 0)
points.append([-dx, -dy])
elif list_type == 3:
assert (dx == 0) or (dy == 0) or (dx == dy) or (dx == -dy)
points.append([-dx, -dy])
else:
points.append([-dx, -dy])
return points

@ -1803,7 +1803,7 @@ class Polygon(Record, GeometryMixin):
if d:
optional['datatype'] = read_uint(stream)
if p:
optional['point_list'] = read_point_list(stream)
optional['point_list'] = read_point_list(stream, implicit_closed=True)
if x:
optional['x'] = read_sint(stream)
if y:
@ -1964,7 +1964,7 @@ class Path(Record, GeometryMixin):
optional['extension_start'] = get_pathext(scheme_start)
optional['extension_end'] = get_pathext(scheme_end)
if p:
optional['point_list'] = read_point_list(stream)
optional['point_list'] = read_point_list(stream, implicit_closed=False)
if x:
optional['x'] = read_sint(stream)
if y:

Loading…
Cancel
Save