Cairo: A Vector Graphics Library: Multiple return values

## 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.

Q: Would it make sense here to define a standard `cairo_rectangle_round()` method that language bindings should map?

    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);