Skip to content

Commit

Permalink
Merge pull request #1227 from mdboom/cairocffi
Browse files Browse the repository at this point in the history
Does the gtk3agg backend work on python3?
  • Loading branch information
tacaswell committed Jan 22, 2014
2 parents fcdb600 + 8c85074 commit 157eec9
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 16 deletions.
13 changes: 13 additions & 0 deletions doc/users/whats_new.rst
Expand Up @@ -149,6 +149,19 @@ added. Furthermore, the the subplottool is now implemented as a modal
dialog. It was previously a QMainWindow, leaving the SPT open if one closed the
plotwindow.

Cairo backends
``````````````

The Cairo backends are now able to use the `cairocffi bindings
<https://github.com/SimonSapin/cairocffi>`__ which are more actively
maintained than the `pycairo bindings
<http://cairographics.org/pycairo/>`__.

Gtk3Agg backend
```````````````

The Gtk3Agg backend now works on Python 3.x, if the `cairocffi
bindings <https://github.com/SimonSapin/cairocffi>`__ are installed.

Text
----
Expand Down
25 changes: 19 additions & 6 deletions lib/matplotlib/backends/backend_cairo.py
Expand Up @@ -30,9 +30,16 @@
def _fn_name(): return sys._getframe(1).f_code.co_name

try:
import cairo
import cairocffi as cairo
except ImportError:
raise ImportError("Cairo backend requires that pycairo is installed.")
try:
import cairo
except ImportError:
raise ImportError("Cairo backend requires that cairocffi or pycairo is installed.")
else:
HAS_CAIRO_CFFI = False
else:
HAS_CAIRO_CFFI = True

_version_required = (1,2,0)
if cairo.version_info < _version_required:
Expand Down Expand Up @@ -197,8 +204,14 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
if angle:
ctx.rotate (-angle * np.pi / 180)
ctx.set_font_size (size)
if isinstance(s, six.text_type):
s = s.encode("utf-8")

if HAS_CAIRO_CFFI:
if not isinstance(s, six.text_type):
s = six.text_type(s)
else:
if isinstance(s, six.text_type):
s = s.encode("utf-8")

ctx.show_text(s)
ctx.restore()

Expand Down Expand Up @@ -363,8 +376,8 @@ def set_dashes(self, offset, dashes):
if dashes == None:
self.ctx.set_dash([], 0) # switch dashes off
else:
self.ctx.set_dash (
self.renderer.points_to_pixels (np.asarray(dashes)), offset)
self.ctx.set_dash(
list(self.renderer.points_to_pixels(np.asarray(dashes))), offset)


def set_foreground(self, fg, isRGBA=None):
Expand Down
20 changes: 15 additions & 5 deletions lib/matplotlib/backends/backend_gtk3agg.py
Expand Up @@ -3,18 +3,20 @@

import six

import cairo
import numpy as np
import sys
import warnings

from . import backend_agg
from . import backend_gtk3
from .backend_cairo import cairo, HAS_CAIRO_CFFI
from matplotlib.figure import Figure
from matplotlib import transforms

if six.PY3:
warnings.warn("The Gtk3Agg backend is not known to work on Python 3.x.")
if six.PY3 and not HAS_CAIRO_CFFI:
warnings.warn(
"The Gtk3Agg backend is known to not work on Python 3.x with pycairo. "
"Try installing cairocffi.")


class FigureCanvasGTK3Agg(backend_gtk3.FigureCanvasGTK3,
Expand Down Expand Up @@ -53,8 +55,16 @@ def on_draw_event(self, widget, ctx):
width = int(bbox.x1) - int(bbox.x0)
height = int(bbox.y1) - int(bbox.y0)

image = cairo.ImageSurface.create_for_data(
buf, cairo.FORMAT_ARGB32, width, height)
if HAS_CAIRO_CFFI:
ctx = cairo.Context._from_pointer(
cairo.ffi.cast('cairo_t **',
id(ctx) + object.__basicsize__)[0],
incref=True)
image = cairo.ImageSurface.create_for_data(
buf.data, cairo.FORMAT_ARGB32, width, height)
else:
image = cairo.ImageSurface.create_for_data(
buf, cairo.FORMAT_ARGB32, width, height)
ctx.set_source_surface(image, x, y)
ctx.paint()

Expand Down
8 changes: 8 additions & 0 deletions lib/matplotlib/backends/backend_gtk3cairo.py
Expand Up @@ -5,10 +5,18 @@

from . import backend_gtk3
from . import backend_cairo
from .backend_cairo import cairo, HAS_CAIRO_CFFI
from matplotlib.figure import Figure

class RendererGTK3Cairo(backend_cairo.RendererCairo):
def set_context(self, ctx):
if HAS_CAIRO_CFFI:
ctx = cairo.Context._from_pointer(
cairo.ffi.cast(
'cairo_t **',
id(ctx) + object.__basicsize__)[0],
incref=True)

self.gc.ctx = ctx


Expand Down
18 changes: 13 additions & 5 deletions setupext.py
Expand Up @@ -1699,9 +1699,12 @@ def get_package_data(self):

def backend_gtk3cairo_internal_check(x):
try:
import cairo
import cairocffi
except ImportError:
return (False, "Requires cairo to be installed.")
try:
import cairo
except ImportError:
return (False, "Requires cairocffi or pycairo to be installed.")

try:
import gi
Expand Down Expand Up @@ -1891,11 +1894,16 @@ class BackendCairo(OptionalBackendPackage):

def check_requirements(self):
try:
import cairo
import cairocffi
except ImportError:
raise CheckFailed("cairo not found")
try:
import cairo
except ImportError:
raise CheckFailed("cairocffi or pycairo not found")
else:
return "pycairo version %s" % cairo.version
else:
return "version %s" % cairo.version
return "cairocffi version %s" % cairocffi.version


class DviPng(SetupPackage):
Expand Down

0 comments on commit 157eec9

Please sign in to comment.