8000 Actually support quadratic Beziers. · matplotlib/matplotlib@706de3a · GitHub
[go: up one dir, main page]

Skip to content

Commit 706de3a

Browse files
committed
Actually support quadratic Beziers.
For the slow code path, implement the degree elevation formula. For the fast code path, the path cleaner was already handling this for us, converting everything to lines.
1 parent 37775fb commit 706de3a

File tree

1 file changed

+11
-16
lines changed

1 file changed

+11
-16
lines changed

lib/matplotlib/backends/backend_cairo.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,8 @@ def _convert_path(ctx, path, transform, clip=None):
9898

9999

100100
def _convert_paths(ctx, paths, transforms, clip=None):
101-
if HAS_CAIRO_CFFI:
102-
try:
103-
return _convert_paths_fast(ctx, paths, transforms, clip)
104-
except NotImplementedError:
105-
pass
106-
return _convert_paths_slow(ctx, paths, transforms, clip)
101+
return (_convert_paths_fast if HAS_CAIRO_CFFI else _convert_paths_slow)(
102+
ctx, paths, transforms, clip)
107103

108104

109105
def _convert_paths_slow(ctx, paths, transforms, clip=None):
@@ -116,9 +112,10 @@ def _convert_paths_slow(ctx, paths, transforms, clip=None):
116112
elif code == Path.LINETO:
117113
ctx.line_to(*points)
118114
elif code == Path.CURVE3:
119-
ctx.curve_to(points[0], points[1],
120-
points[0], points[1],
121-
points[2], points[3])
115+
cur = ctx.get_current_point()
116+
ctx.curve_to(
117+
*np.concatenate([cur / 3 + points[:2] * 2 / 3,
118+
points[:2] * 2 / 3 + points[-2:] / 3]))
122119
elif code == Path.CURVE4:
123120
ctx.curve_to(*points)
124121

@@ -131,17 +128,15 @@ def _convert_paths_fast(ctx, paths, transforms, clip=None):
131128
# with the size in bytes in parentheses, and (X, Y) repeated as many times
132129
# as there are points for the current code.
133130
ffi = cairo.ffi
134-
cleaneds = [path.cleaned(transform=transform, clip=clip)
131+
132+
# Convert curves to segment, so that 1. we don't have to handle
133+
# variable-sized CURVE-n codes, and 2. we don't have to implement degree
134+
# elevation for quadratic Beziers.
135+
cleaneds = [path.cleaned(transform=transform, clip=clip, curves=False)
135136
for path, transform in zip(paths, transforms)]
136137
vertices = np.concatenate([cleaned.vertices for cleaned in cleaneds])
137138
codes = np.concatenate([cleaned.codes for cleaned in cleaneds])
138139

139-
# TODO: Implement Bezier degree elevation formula. For now, fall back to
140-
# the "slow" implementation, though note that that implementation is, in
141-
# fact, also incorrect...
142-
if np.any(codes == Path.CURVE3):
143-
raise NotImplementedError("Quadratic Bezier curves are not supported")
144-
145140
# Remove unused vertices and convert to cairo codes. Note that unlike
146141
# cairo_close_path, we do not explicitly insert an extraneous MOVE_TO after
147142
# CLOSE_PATH, so our resulting buffer may be smaller.

0 commit comments

Comments
 (0)
0