cairocffi icon indicating copy to clipboard operation
cairocffi copied to clipboard

Add HAS_ constants

Open aragilar opened this issue 11 years ago • 4 comments

pycairo has a bunch of constants (see http://cairographics.org/documentation/pycairo/2/reference/constants.html#cairo-has) which define if a given feature is available. It'd be awesome if cairocffi supported these as well.

aragilar avatar Mar 28 '14 11:03 aragilar

It’d be nice, but it’s not obvious how to do it.

These constants are given by cairo as #define C preprocessor macros. pycairo is itself written in C, includes cairo.h, and can just use these macros.

cairocffi, on the other hand, uses dlopen to load a shared library at runtime. All we get are the "symbols" exported by the library, which do not include macros. The best we could do is find a cairo.h file on the system and parse it, but there’s no telling whether it matches the cairo version we’ve loaded as a library.

Or, perhaps we can convince the cairo developers to add a function (not a macro) for getting these constants (perhaps as a bitfield).

SimonSapin avatar Mar 28 '14 12:03 SimonSapin

I've asked the cairo developers to add this in https://bugs.freedesktop.org/show_bug.cgi?id=83050

aragilar avatar Aug 25 '14 10:08 aragilar

I’ve just thought of a work-around: just try to use a cairo function, and catch whatever exception CFFI raises for not finding the corresponding symbol.

SimonSapin avatar Aug 25 '14 10:08 SimonSapin

… which is pretty much what Behdad Esfahbod suggests:

https://bugs.freedesktop.org/show_bug.cgi?id=83050#c1

Well, it would be more convenient for something like cairocffi to try to load a symbol and see if it fails...

Now, if we want to do this with an API compatible with pycairo, we either need to:

  • Test for all the HAS_* flags and set them at import time, which has some performance cost. (It’d be useful to profile it and see how it compares with the existing import-time performance cost of parsing a bunch of C headers.)
  • Make them magic objects that implements all sorts of magic methods to behave kinda like booleans, but only evaluate themselves when first used.
  • To make them be actual booleans but determined lazily, we’d need to replace the cairocffi module with a custom class with properties (descriptors) on it. The latter might be fragile, too much magic.

Or, if pycairo compat can be dropped, this could be more simply a function or a set of functions.

In any case, we’d first need to map each HAS_* constant to a symbol that only exists in the shared library if that feature is enabled. (E.g. HAS_IMAGE_SURFACE to cairo_image_surface_create.)

SimonSapin avatar Nov 10 '14 18:11 SimonSapin