Skip to content

Commit 1a2848d

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 5312461 commit 1a2848d

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
@@ -99,12 +99,8 @@ def _convert_path(ctx, path, transform, clip=None):
9999

100100

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

109105

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

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

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

0 commit comments

Comments
 (0)