# Creating a language binding for cairo

While cairo is implemented and C, and has a C API, it is expected that many users of cairo will be using it from languages other than C. The glue that connects the core cairo library to another language is known as a language binding. This appendix attempts to collect together issues that come up when creating a language bindings for cairo and present standardized solutions to promote consistency among the different language bindings.

## General considerations

The naming of the central cairo_t type is a special exception. The object is “a cairo context” not “a cairo”, and names such as cairo_t rather than cairo_context_t and `cairo_set_source()` rather than `cairo_context_set_source()` are simply abbreviations to make the C API more palatable. In languages which have object-oriented syntax, this abbreviation is much less useful. In fact, if ‘Cairo’ is used as a namespace, then in many languages, you'd end up with a ridiculous type name like ‘Cairo.Cairo’. For this reason, and for inter-language consistency all object-oriented languages should name this type as if it were cairo_context_t.

The punctuation and casing of the type names and method names of cairo should be changed to match the general convention of the language. In Java, where type names are written in StudlyCaps and method names in javaCaps, cairo_font_extents_t will become FontExtents and `cairo_set_source(cr,source)`, `cr.setSource(source)`. As compared to changing the punctuation, and casing, much more reluctance should be used in changing the method names themselves. Even if get is usually omitted from getters in your language, you shouldn't bind cairo_get_source() as cr.source().

## Memory management

The objects in cairo can roughly be divided into two types: reference-counted, opaque types like cairo_surface_t and plain structures like cairo_glyph_t. cairo_path_t and cairo_path_data_t are special cases and are treated separately in this appendix.

Refcounted opaque types all have a `..._reference()` function to increase the refcount by one and a `..._destroy()` to decrease the refcount by one. These should not be exposed to the user of the language binding, but rather used to implement memory management within the language binding. The simplest way to do memory management for a language binding is to treat the language binding object as a simple handle to the cairo object. The language binding object references the cairo object, and unreferences it when finalized. This is the recommended method, though there are a couple of caveats to be noted:

- Equality won't work as expected. You can have two language objects for the same cairo and they won't necessarily compare equal. If the language allows customizing the equality operation, then this is fixable by comparing the underlying pointers. It also can be fixed by creating at most one language object per cairo object, and uniquifying via a pin table (a hash table that goes from cairo object to language object). For cairo_surface_t you can use also `cairo_surface_set_user_data()` instead of a separate pin table.

- Derivation from the language object doesn't work because you can lose the language object while keeping the Cairo object. Code like:

      public class MySurface (ImageSurface) {
         public MySurface (width, height) {
            super (Format.ARGB32, width, height);
         }
         public int get42 () {
            return 42;
         }
      }

         cr = Cairo(MySurface(width, height));
         surface = cr.getTarget();

  Can result in `surface` containing an `ImageSurface` not a `MySurface`. This is not easily fixable without creating memory leaks, and it's probably best to simply forbid deriving from the language objects.

When a plain structure is used as a return value from cairo, this is done by passing it as a “out parameter”.

    cairo_font_extents_t extents;

    cairo_font_extents (cr, &extents);

In a language binding, this should typically be treated as a return value:

    FontExtents extents = cr.fontExtents ();

A language binding has a choice in how it implements the language objects for plain structures. It can use a pure language object with fields corresponding to those of the C structure, and convert from and to the C structure when calling cairo functions or converting cairo return values. Or it can keep a pointer to the C structure internally and wrap it inside a language object much like occurs for refcounted objects. The choice should be invisible to the user: they should be able to imagine that it is implemented as a pure language object.

## Multiple return values

There are a number of functions in the cairo API that have multiple out parameters or in-out parameters. In some languages these can be translated into multiple return values. In Python, what is:

    cairo_user_to_device (cr, &x, &y);

can by mapped to:

    (x, y) = cr.user_to_device (cr, x, y);

but many languages don't have provisions for multiple return values, so it is necessary to introduce auxiliary types. Most of the functions that require the auxiliary types require a type that would, in C, look like

    typedef struct _cairo_point cairo_point_t;
    struct _cairo_point {
        double x;
        double y;
    }

The same type should be used both for functions that use a pair of coordinates as an absolute position, and functions that use a pair of coordinates as a displacement. While an argument could be made that having a separate “distance” type is more correct, it is more likely just to confuse users.

    void
    cairo_user_to_device (cairo_t *cr, double *x, double *y);

    void
    cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy);

    void
    cairo_device_to_user (cairo_t *cr, double *x, double *y);

    void
    cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy);

    void
    cairo_matrix_transform_distance (cairo_matrix_t *matrix, double *dx, double *dy);

    void
    cairo_matrix_transform_point (cairo_matrix_t *matrix, double *x, double *y);

    void
    cairo_get_current_point (cairo_t *cr, double *x, double *y);

There are also a couple of functions that return four values representing a rectangle. These should be mapped to a “rectangle” type that looks like:

    typedef struct _cairo_rectangle cairo_rectangle_t;
    struct _cairo_rectangle {
        double x;
        double y;
        double width;
        double height;
    }

The C function returns the rectangle as a set of two points to facilitate rounding to integral extents, but this isn't worth adding a “box” type to go along with the more obvious “rectangle” representation.

    void
    cairo_stroke_extents (cairo_t *cr,
    		      double *x1, double *y1,
    		      double *x2, double *y2);

    void
    cairo_fill_extents (cairo_t *cr,
    		    double *x1, double *y1,
    		    double *x2, double *y2);

## Overloading and optional arguments

Function overloading (having a several variants of a function with the same name and different arguments) is a language feature available in many languages but not in C.

In general, language binding authors should use restraint in combining functions in the cairo API via function overloading. What may seem like an obvious overload now may turn out to be strange with future additions to cairo. It might seem logical to make `cairo_set_source_rgb()` an overload of `cairo_set_source()`, but future plans to add `cairo_set_source_rgb_premultiplied()`, which will also take three doubles make this a bad idea. For this reason, only the following pairs of functions should be combined via overloading

    void
    cairo_set_source (cairo_t *cr, cairo_pattern_t *source);

    void
    cairo_set_source_surface (cairo_t          *cr,
                              cairo_surface_t  *source,
                              double            surface_x,
                              double            surface_y);

    void
    cairo_mask (cairo_t         *cr,
    	    cairo_pattern_t *pattern);

    void
    cairo_mask_surface (cairo_t         *cr,
    		    cairo_surface_t *surface,
    		    double           surface_x,
    		    double           surface_y);

    cairo_surface_t *
    cairo_image_surface_create (cairo_format_t	format,
    			    int			width,
    			    int			height);
    cairo_surface_t *
    cairo_image_surface_create_for_data (unsigned char	       *data,
    				     cairo_format_t		format,
    				     int			width,
    				     int			height,
    				     int			stride);

    cairo_status_t
    cairo_surface_write_to_png (cairo_surface_t	*surface,
    			    const char		*filename);

    cairo_status_t
    cairo_surface_write_to_png_stream (cairo_surface_t	*surface,
    				   cairo_write_func_t	write_func,
    				   void			*closure);

    cairo_surface_t *
    cairo_image_surface_create_from_png (const char	*filename);

    cairo_surface_t *
    cairo_image_surface_create_from_png_stream (cairo_read_func_t	read_func,
    					    void		*closure);

Note that there are cases where all constructors for a type aren't overloaded together. For example `cairo_image_surface_create_from_png()` should not be overloaded together with `cairo_image_surface_create()`. In such cases, the remaining constructors will typically need to be bound as static methods. In Java, for example, we might have:

    Surface surface1 = ImageSurface(Format.RGB24, 100, 100);
    Surface surface2 = ImageSurface.createFromPNG("camera.png");

Some other overloads that add combinations not found in C may be convenient for users for language bindings that provide cairo_point_t and cairo_rectangle_t types, for example:

    void
    cairo_move_to (cairo_t       *cr,
                   cairo_point_t *point);
    void
    cairo_rectangle (cairo_t           *cr,
                     cairo_rectangle_t *rectangle);

## Streams and File I/O

Various places in the cairo API deal with reading and writing data, whether from and to files, or to other sources and destinations. In these cases, what is typically provided in the C API is a simple version that just takes a filename, and a complex version that takes a callback function. An example is the PNG handling functions:

    cairo_surface_t *
    cairo_image_surface_create_from_png (const char	*filename);

    cairo_surface_t *
    cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
    					    void             *closure);

    cairo_status_t
    cairo_surface_write_to_png (cairo_surface_t	*surface,
    			    const char		*filename);

    cairo_status_t
    cairo_surface_write_to_png_stream (cairo_surface_t	*surface,
    				   cairo_write_func_t	write_func,
    				   void			*closure);

The expectation is that the filename version will be mapped literally in the language binding, but the callback version will be mapped to a version that takes a language stream object. For example, in Java, the four functions above might be mapped to:

    static public ImageSurface createFromPNG (String filename) throws IOException;
    static public ImageSurface createFromPNG (InputStream stream) throws IOException;
    public void writeToPNG (String filename) throws IOException;
    public void writeToPNG (OutputStream stream) throws IOException;

In many cases, it will be better to implement the filename version internally using the stream version, rather than building it on top of the filename version in C. The reason for this is that will naturally give a more standard handling of file errors for the language, as seen in the above Java example, where `createFromPNG()` is marked as raising an exception. Propagating exceptions from inside the callback function to the caller will pose a challenge to the language binding implementor, since an exception must not propagate through the Cairo code. A technique that will be useful in some cases is to catch the exception in the callback, store the exception object inside a structure pointed to by `closure`, and then rethrow it once the function returns.

## Error handling

The error handling approach in C for Cairo has multiple elements:

- When a method on an object fails, the object is put into an error state. Subsequent operations on the object do nothing. The status of the object can be queried with a function like `status()`.

- Constructors, rather than returning `NULL` on out-of-memory failure, return a special singleton object on which all operations do nothing. Retrieving the status of the singleton object returns `CAIRO_STATUS_NO_MEMORY`

- Errors propagate from object to object. Setting a pattern in an out-of-memory state as the source of a cairo_t puts the type into an error state.

A language binding could copy the C approach, and for a language without exceptions, this is likely the right thing to do. However, for a language with exceptions, exposing a completely different style of error handling for cairo would be strange. So, instead, status should be checked after every call to cairo, and exceptions thrown as necessary.

One problem that can arise with this, in languages where handling exceptions is mandatory (like Java), is that almost every cairo function can result in a status being set, usually because of an out-of-memory condition. This could make cairo hard to use. To resolve this problem, let's classify then cairo status codes:

    /* Memory */
    CAIRO_STATUS_NO_MEMORY,

    /* Programmer error */
    CAIRO_STATUS_INVALID_RESTORE
    CAIRO_STATUS_INVALID_POP_GROUP
    CAIRO_STATUS_NO_CURRENT_POINT
    CAIRO_STATUS_INVALID_MATRIX
    CAIRO_STATUS_NO_TARGET_SURFACE
    CAIRO_STATUS_INVALID_STRING
    CAIRO_STATUS_SURFACE_FINISHED
    CAIRO_STATUS_BAD_NESTING

    /* Language binding implementation */
    CAIRO_STATUS_NULL_POINTER
    CAIRO_STATUS_INVALID_PATH_DATA
    CAIRO_STATUS_SURFACE_TYPE_MISMATCH

    /* Other */
    CAIRO_STATUS_READ_ERROR
    CAIRO_STATUS_WRITE_ERROR

If we look at these, the `CAIRO_STATUS_NO_MEMORY` should map to the native out-of-memory exception, which could happen at any point in any case. Most of the others indicate programmer error, and handling them in user code would be silly. These should be mapped into whatever the language uses for assertion failures, rather than errors that are normally handled. (In Java, a subclass of Error rather than Exception, perhaps.) And `CAIRO_STATUS_READ_ERROR`, and `CAIRO_STATUS_WRITE_ERROR` can occur only in very specific places. (In fact, as described in , these errors may be mapped into the language's native I/O error types.) So, there really aren't exceptions that the programmer must handle at most points in the Cairo API.

## Patterns

The cairo C API allows for creating a number of different types of patterns. All of these different types of patterns map to cairo_pattern_t in C, but in an object oriented language, there should instead be a hierarchy of types. (The functions that should map to constructors or static methods for the various types are listed after the type, methods on that type are listed below. Note that cairo_pattern_create_rgb() and cairo_pattern_create_rgba() should not be overloaded with each other as a SolidPattern() constructor, but should appear as static methods instead. This is to maintain code clarity by making it clear how the arguments relate to color components.)

    cairo_pattern_t
          cairo_pattern_set_matrix()
          cairo_pattern_get_matrix()
       cairo_solid_pattern_t (cairo_pattern_create_rgb() and cairo_pattern_create_rgba())
       cairo_surface_pattern_t (cairo_pattern_create_for_surface())
             cairo_pattern_set_extend()
             cairo_pattern_get_extend()
             cairo_pattern_set_filter()
             cairo_pattern_get_filter()
       cairo_gradient_t
             cairo_pattern_add_color_stop_rgb()
             cairo_pattern_add_color_stop_rgba()
          cairo_linear_gradient_t (cairo_pattern_create_linear())
          cairo_radial_gradient_t (cairo_pattern_create_radial())
       cairo_mesh_t (cairo_pattern_create_mesh())
             cairo_mesh_pattern_begin_patch()
             cairo_mesh_pattern_end_patch()
             cairo_mesh_pattern_move_to()
             cairo_mesh_pattern_line_to()
             cairo_mesh_pattern_curve_to()
             cairo_mesh_pattern_set_control_point()
             cairo_mesh_pattern_set_corner_color_rgb()
             cairo_mesh_pattern_set_corner_color_rgba()
             cairo_mesh_pattern_get_patch_count()
             cairo_mesh_pattern_get_path()
             cairo_mesh_pattern_get_control_point()
             cairo_mesh_pattern_get_corner_color_rgba()

## Surfaces

Like patterns, surfaces, which use only the cairo_surface_t type in the C API should be broken up into a hierarchy of types in a language binding.

    cairo_surface_t
        cairo_image_surface_t
        cairo_atsui_surface_t
        cairo_win32_surface_t
        cairo_xlib_surface_t
        cairo_beos_surface_t

Unlike patterns, the constructors and methods on these types are clearly named, and can be trivially associated with the appropriate subtype. Many language bindings will want to avoid binding the platform-specific subtypes at all, since the methods on these types are not useful without passing in native C types. Unless there is a language binding for Xlib available, there is no way to represent a XLib Display * in that language.

This doesn't mean that platform-specific surface types can't be used in a language binding that doesn't bind the constructor. A very common situation is to use a cairo language binding in combination with a binding for a higher level system like the GTK+ widget toolkit. In such a situation, the higher level toolkit provides ways to get references to platform specific surfaces.

The `cairo_surface_set_user_data()`, and `cairo_surface_get_user_data()` methods are provided for use in language bindings, and should not be directly exposed to applications. One example of the use of these functions in a language binding is creating a binding for:

    cairo_surface_t *
    cairo_image_surface_create_for_data (unsigned char	       *data,
    				     cairo_format_t		format,
    				     int			width,
    				     int			height,
    				     int			stride);

The memory block passed in for `data` must be kept around until the surface is destroyed, so the language binding must have some way of determining when that happens. The way to do this is to use the `destroy` argument to `cairo_surface_set_user_data()`.

## Fonts

Fonts are once more an area where there is a hierarchy of types:

    cairo_font_face_t
       cairo_ft_font_face_t
       cairo_win32_font_face_t
    cairo_scaled_font_t
       cairo_ft_scaled_font_t
       cairo_win32_scaled_font_t

The methods on the subtypes are, however, not useful without bindings for fontconfig and FreeType or for the Win32 GDI, so most language bindings will choose not to bind these types.

The `cairo_font_face_set_user_data()`, and `cairo_font_face_get_user_data()` methods are provided for use in language bindings, and should not be directly exposed to applications.

## cairo_path_t

The cairo_path_t type is one area in which most language bindings will differ significantly from the C API. The C API for cairo_path_t is designed for efficiency and to avoid auxiliary objects that would be have to be manually memory managed by the application. However, a language binding should not present cairo_path_t as an array, but rather as an opaque that can be iterated over. Different languages have quite different conventions for how iterators work, so it is impossible to give an exact specification for how this API should work, but the type names and methods should be similar to the language's mapping of the following:

    typedef struct cairo_path_iterator cairo_path_iterator_t;
    typedef struct cairo_path_element cairo_path_element_t;

    cairo_path_iterator_t *
    cairo_path_get_iterator (cairo_path_t *path);

    cairo_bool_t
    cairo_path_iterator_has_next (cairo_path_iterator_t *iterator);

    cairo_path_element_t *
    cairo_path_iterator_next (cairo_path_iterator_t *iterator);

    cairo_path_element_type_t
    cairo_path_element_get_type (cairo_path_element_t *element);

    void
    cairo_path_element_get_point (cairo_path_element_t *element,
                                  int                   index,
                                  double                *x,
                                  double                *y);

The above is written using the Java conventions for iterators. To illustrate how the API for PathIterator might depend on the native iteration conventions of the API, examine three versions of the loop, first written in a hypothetical Java binding:

    PathIterator iter = cr.copyPath().iterator();
    while (cr.hasNext()) {
        PathElement element = iter.next();
        if (element.getType() == PathElementType.MOVE_TO) {
            Point p = element.getPoint(0);
            doMoveTo (p.x, p.y);
        }
    }

And then in a hypothetical C++ binding:

    Path path = cr.copyPath();
    for (PathIterator iter = path.begin(); iter != path.end(); iter++) {
        PathElement element = *iter;
        if (element.getType() == PathElementType.MOVE_TO) {
            Point p = element.getPoint(0);
            doMoveTo (p.x, p.y);
        }
    }

And then finally in a Python binding:

    for element in cr.copy_path():
        if element.getType == cairo.PATH_ELEMENT_MOVE_TO:
            (x, y) = element.getPoint(0)
            doMoveTo (x, y);

While many of the API elements stay the same in the three examples, the exact iteration mechanism is quite different, to match how users of the language would expect to iterate over a container.

You should not present an API for mutating or for creating new cairo_path_t objects. In the future, these guidelines may be extended to present an API for creating a cairo_path_t from scratch for use with `cairo_append_path()` but the current expectation is that `cairo_append_path()` will mostly be used with paths from `cairo_copy_path()`.