cairocffi

repository·main·Indexed 42 days ago

https://github.com/kozea/cairocffi

A CFFI-based Python binding for the Cairo 2D vector graphics library, designed as a drop-in replacement for Pycairo. It provides a Pythonic interface for Cairo objects, including Surface, Context, and Matrix, while allowing low-level access to the raw Cairo C API via CFFI pointers.

Tokens
4.6K
Snippets
28
Records
44
Agent score
52%

What's inside cairocffi

  1. Overview of cairocffi

    main

    cairocffi is a CFFI-based drop-in replacement for Pycairo. It provides Python bindings and an object-oriented API for the Cairo 2D vector graphics library. Cairo supports multiple backends, including image buffers, PNG, PostScript, PDF, and SVG file output.

    Key characteristics:

    • Compatibility: Designed as a drop-in replacement for Pycairo, though the API is only partially compatible.
    • Cairo Support: Works with any version of the Cairo library.
    • Image Decoding: The cairocffi.pixbuf module utilizes GDK-PixBuf to decode various image formats for use within Cairo.
  2. Understand Cairo's 'toy' text API and font limitations

    main

    Cairo provides a basic 'toy' text API for simple text rendering.

    Limitations:

    • It performs simple shaping only: no ligatures or kerning.
    • It uses one glyph per character.
    • Positioning is handled by moving the cursor by the X and Y advance of each glyph.

    Recommendation: For professional text layout, complex shaping, or advanced font handling, it is recommended to use a library like Pango in conjunction with cairocffi.

  3. Apply colors and gradients using Patterns

    main

    Patterns define how areas are filled. You can use:

    • SolidPattern: For a single solid color.
    • SurfacePattern: For using an existing Surface as a pattern.
    • LinearGradient: For a color gradient along a straight line.
    • RadialGradient: For a color gradient along a circular path.
  4. How the cairocffi API works

    main

    cairocffi provides a Pythonic interface for Cairo objects using wrapper classes. It improves upon the raw C API by:

    • Converting functions that take a pointer as the first argument into object methods.
    • Converting error statuses into Python exceptions.
    • Automatically managing Cairo's reference counting during Python garbage collection.

    If the high-level API is insufficient or you need to integrate with other C libraries (like Pango), you can access the underlying C pointers and the raw Cairo API via the provided CFFI interface.

  5. Use different Surface types for rendering

    main

    Cairo uses Surface objects to define where drawing occurs. Depending on your target, you should use one of the following specialized surface classes:

    • ImageSurface: For drawing into an in-memory pixel buffer.
    • PDFSurface: For generating PDF documents.
    • PSSurface: For PostScript files.
    • SVGSurface: For Scalable Vector Graphics files.
    • RecordingSurface: For recording drawing commands to be replayed later.
    • Win32PrintingSurface: For printing on Windows systems.
  6. Convert Pycairo wrappers to cairocffi

    main

    If you are using libraries like PyGTK or PyGObject that provide a pycairo.Context object, you can extract the underlying cairo_t * pointer to create a cairocffi wrapper.

    Note: This method uses unsafe pointer manipulation and is only compatible with CPython.

  7. Import cairocffi and resolve library loading issues

    main

    To use cairocffi while avoiding name collisions with Pycairo, import it using an alias. cairocffi dynamically loads the cairo shared library at import time.

    Common Errors: If the shared library is not found, you will encounter: OSError: library not found: 'cairo'.

    Resolving Library Paths:

    • Linux: Use the LD_LIBRARY_PATH environment variable to point to the directory containing the Cairo shared libraries.
    • Windows: Use the CAIROCFFI_DLL_DIRECTORIES environment variable to specify the folder containing Cairo DLLs (e.g., libcairo-2.dll).

    Windows Installation Note: Ensure libcairo-2.dll is in a directory listed in your PATH. You can use GTK+ installers (32-bit GTK+-2 or 64-bit GTK+-3) and ensure the "Set up PATH environment variable" checkbox is selected.

    import cairocffi as cairo
  8. Install cairocffi and CFFI dependencies

    main

    Install cairocffi using pip. This will automatically install CFFI as a dependency.

    System Dependencies for CFFI:

    • Linux: Install python-dev and libffi-dev via your package manager.
    • OS X: Install pkg-config and libffi (e.g., via Homebrew). You may need to set the PKG_CONFIG_PATH environment variable.
    • Windows: Consider using Christoph Gohlke's unofficial binary builds for CFFI.

    XCB Support: To enable XCB support, install xcffib before installing cairocffi.

    # Standard installation
    pip install cairocffi
    
    # Installation with XCB support
    pip install xcffib
    pip install cairocffi
  9. Replace Pycairo with cairocffi in existing code

    main

    The cairocffi Python API is compatible with Pycairo. You can switch to cairocffi using one of these methods:

    1. Manual Import Change: Change import cairo to import cairocffi as cairo.
    2. Monkeypatching: Use cairocffi.install_as_pycairo() to make cairocffi act as the cairo module globally.
    3. Path Injection: Add a cairo.py file to your sys.path that performs from cairocffi import *.
    import cairocffi
    cairocffi.install_as_pycairo()
    import cairo
    assert cairo is cairocffi
  10. Decode various image formats using cairocffi.pixbuf

    main

    While ImageSurface.create_from_png() is optimized for PNG files, you can use the cairocffi.pixbuf module to decode other formats like JPEG and GIF using GDK-PixBuf.

    To use this functionality, you must import the cairocffi.pixbuf module. Note that this module requires GDK-PixBuf to be installed on your system. If GDK-PixBuf is not available, the module will use a slower fallback method for pixel conversion (converting from GDK-PixBuf's big-endian RGBA to Cairo's native-endian ARGB).

    If the image loading fails, an ImageLoadingError is raised.

    import cairocffi.pixbuf
    # Use decode_to_image_surface to load images like JPEG or GIF
    surface = cairocffi.pixbuf.decode_to_image_surface('path/to/image.jpg')
  11. Use XCB surfaces with xcffib

    main
    The cairocffi.xcb module allows you to create Cairo graphics surfaces for X windows and pixmaps by using xcffib as the underlying XCB library. This is useful when you need to perform Cairo drawing operations directly onto X11 resources.