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.
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