Skip to content

Commit

Permalink
Update to use cffi 1.0 compilation mechanism
Browse files Browse the repository at this point in the history
Create two ffi's for the module in ffi_build, one for the cairo library,
importing the ffi from xcffib (if it can be imported) and adding the
relevant cdefs, and another ffi for the gdk_pixbuf cdefs.

Now, to run cairocffi from source will require running `python
cairocffi/ffi_build.py` to compile the ffi objects, these are handled
automatically when installing.
  • Loading branch information
flacjacket committed Jun 2, 2015
1 parent 138b63f commit 31a5a0c
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 80 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,5 +1,6 @@
*.pyc
__pycache__
cairocffi/_ffi*.py
*.egg-info
/dist
/.tox
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -9,4 +9,5 @@ python:
install:
- "pip install xcffib"
- "pip install ."
- "python cairocffi/ffi_build.py"
script: "py.test"
1 change: 1 addition & 0 deletions MANIFEST.in
@@ -1,3 +1,4 @@
include README.rst CHANGES LICENSE tox.ini .coveragerc
recursive-include docs *
prune docs/_build
exclude cairocffi/_ffi*.py
4 changes: 1 addition & 3 deletions cairocffi/__init__.py
Expand Up @@ -11,11 +11,11 @@
"""

import sys
from cffi import FFI

from . import constants
from .compat import FileNotFoundError

from ._ffi import ffi

VERSION = '0.6'
# pycairo compat:
Expand All @@ -34,8 +34,6 @@ def dlopen(ffi, *names):
return ffi.dlopen(names[0]) # pragma: no cover


ffi = FFI()
ffi.cdef(constants._CAIRO_HEADERS)
CAIRO_NAMES = ['libcairo.so.2', 'libcairo.2.dylib', 'libcairo-2.dll',
'cairo', 'libcairo-2']
cairo = dlopen(ffi, *CAIRO_NAMES)
Expand Down
103 changes: 103 additions & 0 deletions cairocffi/ffi_build.py
@@ -0,0 +1,103 @@
# coding: utf8
"""
cairocffi.ffi_build
~~~~~~~~~~~~~~~~~~~
Build the cffi bindings
:copyright: Copyright 2013 by Simon Sapin
:license: BSD, see LICENSE for details.
"""

import os
import sys
from cffi import FFI

# Path hack to import constants when this file is exec'd by setuptools
this_file = os.path.abspath(__file__)
this_dir = os.path.split(this_file)[0]
sys.path.append(this_dir)

import constants


# Primary cffi definitions
ffi = FFI()
ffi.set_source('cairocffi._ffi', None)
ffi.cdef(constants._CAIRO_HEADERS)

# include xcffib cffi definitions for cairo xcb support
try:
from xcffib.ffi_build import ffi as xcb_ffi
ffi.include(xcb_ffi)
ffi.cdef(constants._CAIRO_XCB_HEADERS)
except ImportError:
pass

# gdk pixbuf cffi definitions
ffi_pixbuf = FFI()
ffi_pixbuf.set_source('cairocffi._ffi_pixbuf', None)
ffi_pixbuf.include(ffi)
ffi_pixbuf.cdef('''
typedef unsigned long gsize;
typedef unsigned int guint32;
typedef unsigned int guint;
typedef unsigned char guchar;
typedef char gchar;
typedef int gint;
typedef gint gboolean;
typedef guint32 GQuark;
typedef void* gpointer;
typedef ... GdkPixbufLoader;
typedef ... GdkPixbufFormat;
typedef ... GdkPixbuf;
typedef struct {
GQuark domain;
gint code;
gchar *message;
} GError;
typedef enum {
GDK_COLORSPACE_RGB
} GdkColorspace;
GdkPixbufLoader * gdk_pixbuf_loader_new (void);
GdkPixbufFormat * gdk_pixbuf_loader_get_format (GdkPixbufLoader *loader);
GdkPixbuf * gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader);
gboolean gdk_pixbuf_loader_write (
GdkPixbufLoader *loader, const guchar *buf, gsize count,
GError **error);
gboolean gdk_pixbuf_loader_close (
GdkPixbufLoader *loader, GError **error);
gchar * gdk_pixbuf_format_get_name (GdkPixbufFormat *format);
GdkColorspace gdk_pixbuf_get_colorspace (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_n_channels (const GdkPixbuf *pixbuf);
gboolean gdk_pixbuf_get_has_alpha (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_bits_per_sample (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_width (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_height (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_rowstride (const GdkPixbuf *pixbuf);
guchar * gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf);
gsize gdk_pixbuf_get_byte_length (const GdkPixbuf *pixbuf);
gboolean gdk_pixbuf_save_to_buffer (
GdkPixbuf *pixbuf, gchar **buffer, gsize *buffer_size,
const char *type, GError **error, ...);
void gdk_cairo_set_source_pixbuf (
cairo_t *cr, const GdkPixbuf *pixbuf,
double pixbuf_x, double pixbuf_y);
void g_object_ref (gpointer object);
void g_object_unref (gpointer object);
void g_error_free (GError *error);
void g_type_init (void);
''')


if __name__ == '__main__':
ffi.compile()
ffi_pixbuf.compile()
69 changes: 2 additions & 67 deletions cairocffi/pixbuf.py
Expand Up @@ -11,82 +11,17 @@
"""

import sys
import ctypes
from io import BytesIO
from functools import partial
from array import array

import cffi

from . import ffi as cairo_ffi, dlopen, ImageSurface, Context, constants
from . import dlopen, ImageSurface, Context, constants
from ._ffi_pixbuf import ffi
from .compat import xrange


__all__ = ['decode_to_image_surface']


ffi = cffi.FFI()
ffi.include(cairo_ffi)
ffi.cdef('''
typedef unsigned long gsize;
typedef unsigned int guint32;
typedef unsigned int guint;
typedef unsigned char guchar;
typedef char gchar;
typedef int gint;
typedef gint gboolean;
typedef guint32 GQuark;
typedef void* gpointer;
typedef ... GdkPixbufLoader;
typedef ... GdkPixbufFormat;
typedef ... GdkPixbuf;
typedef struct {
GQuark domain;
gint code;
gchar *message;
} GError;
typedef enum {
GDK_COLORSPACE_RGB
} GdkColorspace;
GdkPixbufLoader * gdk_pixbuf_loader_new (void);
GdkPixbufFormat * gdk_pixbuf_loader_get_format (GdkPixbufLoader *loader);
GdkPixbuf * gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader);
gboolean gdk_pixbuf_loader_write (
GdkPixbufLoader *loader, const guchar *buf, gsize count,
GError **error);
gboolean gdk_pixbuf_loader_close (
GdkPixbufLoader *loader, GError **error);
gchar * gdk_pixbuf_format_get_name (GdkPixbufFormat *format);
GdkColorspace gdk_pixbuf_get_colorspace (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_n_channels (const GdkPixbuf *pixbuf);
gboolean gdk_pixbuf_get_has_alpha (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_bits_per_sample (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_width (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_height (const GdkPixbuf *pixbuf);
int gdk_pixbuf_get_rowstride (const GdkPixbuf *pixbuf);
guchar * gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf);
gsize gdk_pixbuf_get_byte_length (const GdkPixbuf *pixbuf);
gboolean gdk_pixbuf_save_to_buffer (
GdkPixbuf *pixbuf, gchar **buffer, gsize *buffer_size,
const char *type, GError **error, ...);
void gdk_cairo_set_source_pixbuf (
cairo_t *cr, const GdkPixbuf *pixbuf,
double pixbuf_x, double pixbuf_y);
void g_object_ref (gpointer object);
void g_object_unref (gpointer object);
void g_error_free (GError *error);
void g_type_init (void);
''')

gdk_pixbuf = dlopen(ffi, 'gdk_pixbuf-2.0', 'libgdk_pixbuf-2.0-0',
'libgdk_pixbuf-2.0.so')
gobject = dlopen(ffi, 'gobject-2.0', 'libgobject-2.0-0', 'libgobject-2.0.so')
Expand Down
12 changes: 4 additions & 8 deletions cairocffi/xcb.py
Expand Up @@ -8,15 +8,11 @@
:copyright: Copyright 2014 by Simon Sapin
:license: BSD, see LICENSE for details.
"""
from xcffib import ffi as xcb_ffi, visualtype_to_c_struct
from xcffib import visualtype_to_c_struct

from . import ffi, dlopen, constants, CAIRO_NAMES
from . import cairo, constants
from .surfaces import Surface, SURFACE_TYPE_TO_CLASS

ffi.include(xcb_ffi)
ffi.cdef(constants._CAIRO_XCB_HEADERS)
cairo_xcb = dlopen(ffi, *CAIRO_NAMES)


class XCBSurface(Surface):
"""The XCB surface is used to render cairo graphics to X Window System
Expand All @@ -38,7 +34,7 @@ class XCBSurface(Surface):
def __init__(self, conn, drawable, visual, width, height):
c_visual = visualtype_to_c_struct(visual)

p = cairo_xcb.cairo_xcb_surface_create(
p = cairo.cairo_xcb_surface_create(
conn._conn, drawable, c_visual, width, height)
Surface.__init__(self, p)

Expand All @@ -57,7 +53,7 @@ def set_size(self, width, height):
:param width: integer
:param height: integer
"""
cairo_xcb.cairo_xcb_surface_set_size(self._pointer, width, height)
cairo.cairo_xcb_surface_set_size(self._pointer, width, height)
self._check_status()

SURFACE_TYPE_TO_CLASS[constants.SURFACE_TYPE_XCB] = XCBSurface
9 changes: 7 additions & 2 deletions setup.py
Expand Up @@ -36,6 +36,11 @@
'Topic :: Multimedia :: Graphics',
],
packages=find_packages(),
install_requires=['cffi>=0.6'],
extras_require={'xcb': ['xcffib']}
install_requires=['cffi>=1.1.0'],
setup_requires=['cffi>=1.1.0'],
cffi_modules=[
'cairocffi/ffi_build.py:ffi',
'cairocffi/ffi_build.py:ffi_pixbuf'
],
extras_require={'xcb': ['xcffib>=0.3.2']},
)

0 comments on commit 31a5a0c

Please sign in to comment.