10000 Faster path drawing for the cairo backend (cairocffi only) by anntzer · Pull Request #8787 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Faster path drawing for the cairo backend (cairocffi only) #8787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 6, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Rebase for mpl3.
  • Loading branch information
anntzer committed May 6, 2018
commit abbcb3e358ce0e0c399c198e90d58193ec894f31
13 changes: 4 additions & 9 deletions doc/api/backend_cairo_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
:mod:`matplotlib.backends.backend_cairo`
========================= 10000 ===============

.. Building the docs requires either adding pycairo/cairocffi as docs build
dependency, or bumping the minimal numpy version to one that supports
MagicMocks (which does define `__index__`) as indices (recent numpys do, but
1.7.1 doesn't).

.. .. automodule:: matplotlib.backends.backend_cairo
.. :members:
.. :undoc-members:
.. :show-inheritance:
.. automodule:: matplotlib.backends.backend_cairo
:members:
:undoc-members:
:show-inheritance:
29 changes: 17 additions & 12 deletions lib/matplotlib/backends/backend_cairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
==============================
:Author: Steve Chaplin and others

This backend depends on `cairo <http://cairographics.org>`_, and either on
cairocffi, or (Python 2 only) on pycairo.
This backend depends on cairocffi or pycairo.
"""

import six
Expand Down Expand Up @@ -36,13 +35,14 @@
"cairo>=1.4.0 is required".format(cairo.version))
backend_version = cairo.version

from matplotlib import cbook
from matplotlib.backend_bases import (
_Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
RendererBase)
from matplotlib.font_manager import ttfFontProperty
from matplotlib.mathtext import MathTextParser
from matplotlib.path import Path
from matplotlib.transforms import Affine2D
from matplotlib.font_manager import ttfFontProperty


def _premultiplied_argb32_to_unmultiplied_rgba8888(buf):
Expand Down Expand Up @@ -94,7 +94,7 @@ def buffer_info(self):
_CAIRO_PATH_TYPE_SIZES[cairo.PATH_CLOSE_PATH] = 1


def _convert_paths_slow(ctx, paths, transforms, clip=None):
def _append_paths_slow(ctx, paths, transforms, clip=None):
for path, transform in zip(paths, transforms):
for points, code in path.iter_segments(transform, clip=clip):
if code == Path.MOVETO:
Expand All @@ -112,7 +112,7 @@ def _convert_paths_slow(ctx, paths, transforms, clip=None):
ctx.curve_to(*points)


def _convert_paths_fast(ctx, paths, transforms, clip=None):
def _append_paths_fast(ctx, paths, transforms, clip=None):
# We directly convert to the internal representation used by cairo, for
# which ABI compatibility is guaranteed. The layout for each item is
# --CODE(4)-- -LENGTH(4)- ---------PAD(8)---------
Expand Down Expand Up @@ -160,11 +160,11 @@ def _convert_paths_fast(ctx, paths, transforms, clip=None):
cairo.cairo.cairo_append_path(ctx._pointer, ptr)


_convert_paths = _convert_paths_fast if HAS_CAIRO_CFFI else _convert_paths_slow
_append_pa 10000 ths = _append_paths_fast if HAS_CAIRO_CFFI else _append_paths_slow


def _convert_path(ctx, path, transform, clip=None):
return _convert_paths(ctx, [path], [transform], clip)
def _append_path(ctx, path, transform, clip=None):
return _append_paths(ctx, [path], [transform], clip)


class RendererCairo(RendererBase):
Expand Down Expand Up @@ -226,6 +226,11 @@ def _fill_and_stroke(self, ctx, fill_c, alpha, alpha_overrides):
ctx.restore()
ctx.stroke()

@staticmethod
@cbook.deprecated("3.0")
def convert_path(ctx, path, transform, clip=None):
_append_path(ctx, path, transform, clip)

def draw_path(self, gc, path, transform, rgbFace=None):
ctx = gc.ctx
# Clip the path to the actual rendering extents if it isn't filled.
Expand All @@ -235,7 +240,7 @@ def draw_path(self, gc, path, transform, rgbFace=None):
transform = (transform
+ Affine2D().scale(1, -1).translate(0, self.height))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be += to make one line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transforms are mutable but don't implement iadd (so += actually doesn't modify the transform in place), but I was too lazy to check and want to make clear that we're indeed not mutating the transform.

ctx.new_path()
_convert_path(ctx, path, transform, clip)
_append_path(ctx, path, transform, clip)
self._fill_and_stroke(
ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())

Expand All @@ -245,7 +250,7 @@ def draw_markers(self, gc, marker_path, marker_trans, path, transform,

ctx.new_path()
# Create the path for the marker; it needs to be flipped here already!
_convert_path(ctx, marker_path, marker_trans + Affine2D().scale(1, -1))
_append_path(ctx, marker_path, marker_trans + Affine2D().scale(1, -1))
marker_path = ctx.copy_path_flat()

# Figure out whether the path has a fill
Expand Down Expand Up @@ -316,7 +321,7 @@ def _draw_paths():
gc.ctx.new_path()
paths, transforms = zip(*grouped_draw)
grouped_draw.clear()
_convert_paths(gc.ctx, paths, transforms)
_append_paths(gc.ctx, paths, transforms)
self._fill_and_stroke(
gc.ctx, rgb_fc, gc.get_alpha(), gc.get_forced_alpha())

Expand Down Expand Up @@ -529,7 +534,7 @@ def set_clip_path(self, path):
ctx.new_path()
affine = (affine
+ Affine2D().scale(1, -1).translate(0, self.renderer.height))
_convert_path(ctx, tpath, affine)
_append_path(ctx, tpath, affine)
ctx.clip()

def set_dashes(self, offset, dashes):
Expand Down
0