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