Documentation for the cairo interface provided in OverLua
=========================================================

First, this file will mostly attempt to describe the differences between the
cairo C API and the provided Lua API. If you want more general and in-depth
information on cairo, please see the documentation for the C API:

<http://cairographics.org/manual/>


Note that almost all of the *_reference functions are unimplemented currently.
They should not be explicitly needed since Lua does its own management on
objects as well, you can just copy and keep a Lua cairo object and be
guaranteed the underlying cairo object won't be deleted until all Lua objects
referring to it are gone.
There are no *_destroy and *_get_reference_count functions either,
for this reason.

Finally the *_user_data functions are also removed from the API.


Conventions in this file
------------------------

Variable name   Cairo object

surf            Surface (cairo_surface_t)
ctx             Context (cairo_t)
face            Font face (cairo_font_face_t)
sf              Scaled font (cairo_scaled_font_t)
fo              Font options (cairo_font_options_t)
mat             Matrix (cairo_matrix_t)
path            Path (cairo_path_t)
pat             Pattern (cairo_pattern_t)
x, y            Coordinates
r, g, b, a      Colour values (red, green, blue, alpha)


If more than one of an object type is used they will get numeric suffixes.
For matrix operations you might also see "matR", this is "result matrix".


More "OO-like" syntax
---------------------

This Lua cairo API provides a more common "OO-like" syntax for calls.
For example, the cairo_set_source_surface(ctx, surf, x, y) function maps to
ctx.set_source_surface(surf, x, y).


Creating initial objects
------------------------

Many of the objects you will use are created from or by other objects, but
you will need to create some non-dependant objects, most importantly image
surface objects. All the object creation functions live in the global "cairo"
table.


surf = cairo.image_surface_create(width, height, pixel_format)

Create a blank image surface object.

width and height are in pixels. pixel_format is a string and must be one
of "argb32", "rgb24", "a8" and "a1".


fo = cairo.font_options_create()

Create a new font options object.


mat = cairo.matrix_create()

Create a new matrix. It is initially the identity matrix.


pat = cairo.pattern_create_rgb(r, g, b)
pat = cairo.pattern_create_rgba(r, g, b, a)
pat = cairo.pattern_create_for_surface(surf)
pat = cairo.pattern_create_linear(x0, y0, x1, y1)
pat = cairo.pattern_create_radial(x0, y0, r0, x1, y1, r1)

Create various kinds of pattern objects.


ctx = surf.create_context()

Not strictly an "initial object", but cairo context objects are important
enough to explicitly list here. They are created by calling the
create_context() method in a surface object. This will create a context
object that draws to the surface it was created with.


Other functions that have changed API
-------------------------------------

Some functions have changed API to better match the Lua programming model.


ctx.set_dash()
ctx.set_dash(0)
ctx.set_dash(num[, offset])
ctx.set_dash(dashes[, offset])

There are several forms of the set_dash function. The two first disable
dashing entirely.

The third creates a repeating pattern of equal length on and off potions,
each "num" units long. The offset argument is optional, its default is 0.

The last creates a complex pattern. "dashes" must be a table of numbers
describing the dashing pattern. offset is optional, default is 0.


dashes, offset = ctx.get_dash()

Returns current dashing setting, in same format as the last form of set_dash
takes. If dashing is disabled, dashes will be an empty table.

(You won't need to use the ctx.get_dash_count() function.)


x0, y0, x1, y1 = ctx.clip_extents()
x0, y0, x1, y1 = ctx.fill_extents()
x0, y0, x1, y1 = ctx.stroke_extents()

Return the smallest rectangle bounding the area that would be affected if
performing a clip/fill/stroke operation.


x, y = ctx.get_current_point()

Get the current point for path gneration operations.


mat = ctx.get_matrix()

Get the current geometry transformation matrix.


x, y = ctx.user_to_device(x, y)
x, y = ctx.user_to_device_distance(x, y)
x, y = ctx.device_to_user(x, y)
x, y = ctx.device_to_user_distance(x, y)

Returns the transformation of a point between device and user-space
coordinates.


offset, r, g, b, a = pat.get_color_stop_rgba(index)

Returns nothing if the pattern is not a gradient pattern or the stop index
is out of range.


r, g, b, a = pat.get_rgba()

Returns nothing if the pattern is not a solid colour fill pattern.


surf = pat.get_surface()

Returns nothing if the pattern is not a surface pattern.


x0, y0, x1, y1 = pat.get_linear_points()

Returns nothing if the pattern is not a linear gradient pattern.


x0, y0, r0, x1, y1, r1 = pat.get_radial_circles()

Returns nothing if the pattern is not a radial gradient pattern.


extents = ctx.font_extents()
extents = sf.font_extents()

Get extents metrics for current font. The returned object is a Lua table
with fields identical to the C struct cairo_font_extents_t.


extents = ctx.tex_extents(utf8)
extents = sf.text_extents(utf8)

Get extents metrics for writing text given in utf8 with current font. The
returned object is a Lua table with fields identical to the C
struct cairo_text_extents_t.


fo = sf.get_font_options()

Get font options for a scaled font.


mat = sf.get_font_matrix()

Get text transformation matrix.


mat = sf.get_ctm()

Get the CTM. (Character transformation matrix?)


fo1.merge(fo2)

Merge font options fo2 into fo1.


hash = fo.hash()

Returns a hexadecimal string hash of fo.


fo1.equal(fo2)

Return true is fo1 equals fo2.


fo = surf.get_font_options()

Get current font options for surface.


x, y = surf.get_device_offset()

Get current device offset for surface.


a, r, g, b = surf.get_pixel(x, y)
r, g, b = surf.get_pixel(x, y)
a = surf.get_pixel(x, y)

Get colour value of a pixel on an image surface. This function replaces the
cairo_image_surface_get_data(surf) function for reading surface contents.
The number and meanings of return values depend on the surface pixel format.

surf.set_pixel() is not implemented yet.


matR = mat.copy()

Duplicate a matrix. Not in cairo C API.


mat.xx, mat.yx, mat.xy, mat.yy, mat.x0, mat.y0

Access the individual numbers in a matrix. These are both read and write.


Functional programming on path objects
--------------------------------------

The path object still hasn't been completely implemented, but two useful
functions do exist for it. These are functional programming style map and
fold functions.


path.map_coords(func)

Transform every coordinate pair in path using func.

func must be a function of type (x,y)->(x,y) ie. takes two arguments which
are the x and y coordinates of the point and returns two numbers which are
the new x and y coordinates of the point.

Example: Produce a "wavy" effect.
path.map_coords(function(x,y) return x+math.sin(x), y+math.cos(y) end)


res = path.fold_coords(func, start)

Produce a value by combining all the coordinate pairs using func.

func must be a function of type (r,x,y)->(r) ie. takes three argument which
are the current result and the x/y coordinates of the point, and returns a
new result.
When all points have been processed path.fold_coords returns the final result.

Example: Find the maximum X coordinate.
maxx = path.fold_coords(
	function(maxx,x,y)
		if not maxx then
			return x
		elseif x > maxx then
			return x
		else
			return maxx
		end
	end, nil)


Enumeration mappings
--------------------

Everything represented by an enum in the cairo C API is represented by a
string in the Lua API. Any enums not listed here don't have any mappings
currently. (Which in turn means that any API requiring that enum is also
unimplemented.)


typedef enum _cairo_antialias {
    CAIRO_ANTIALIAS_DEFAULT,                "default"
    CAIRO_ANTIALIAS_NONE,                   "none"
    CAIRO_ANTIALIAS_GRAY,                   "gray"
    CAIRO_ANTIALIAS_SUBPIXEL                "subpixel"
} cairo_antialias_t;

typedef enum _cairo_fill_rule {
    CAIRO_FILL_RULE_WINDING,                "winding"
    CAIRO_FILL_RULE_EVEN_ODD                "even_odd"
} cairo_fill_rule_t;

typedef enum _cairo_line_cap {
    CAIRO_LINE_CAP_BUTT,                    "butt"
    CAIRO_LINE_CAP_ROUND,                   "round"
    CAIRO_LINE_CAP_SQUARE                   "square"
} cairo_line_cap_t;
                               
typedef enum _cairo_line_join {
    CAIRO_LINE_JOIN_MITER,                  "miter"
    CAIRO_LINE_JOIN_ROUND,                  "round"
    CAIRO_LINE_JOIN_BEVEL                   "bevel"
} cairo_line_join_t;
                               
typedef enum _cairo_operator {
    CAIRO_OPERATOR_CLEAR,                   "clear"

    CAIRO_OPERATOR_SOURCE,                  "source"
    CAIRO_OPERATOR_OVER,                    "over"
    CAIRO_OPERATOR_IN,                      "in"
    CAIRO_OPERATOR_OUT,                     "out"
    CAIRO_OPERATOR_ATOP,                    "atop"

    CAIRO_OPERATOR_DEST,                    "dest"
    CAIRO_OPERATOR_DEST_OVER,               "dest_over"
    CAIRO_OPERATOR_DEST_IN,                 "dest_in"
    CAIRO_OPERATOR_DEST_OUT,                "dest_out"
    CAIRO_OPERATOR_DEST_ATOP,               "dest_atop"

    CAIRO_OPERATOR_XOR,                     "xor"
    CAIRO_OPERATOR_ADD,                     "add"
    CAIRO_OPERATOR_SATURATE                 "saturate"
} cairo_operator_t;
                               
typedef enum _cairo_path_data_type {
    CAIRO_PATH_MOVE_TO,                     "move_to"
    CAIRO_PATH_LINE_TO,                     "line_to"
    CAIRO_PATH_CURVE_TO,                    "curve_to"
    CAIRO_PATH_CLOSE_PATH                   "close"
} cairo_path_data_type_t;

typedef enum _cairo_extend {
    CAIRO_EXTEND_NONE,                      "none"
    CAIRO_EXTEND_REPEAT,                    "repeat"
    CAIRO_EXTEND_REFLECT,                   "reflect"
    CAIRO_EXTEND_PAD                        "pad"
} cairo_extend_t;

typedef enum _cairo_filter {
    CAIRO_FILTER_FAST,                      "fast"
    CAIRO_FILTER_GOOD,                      "good"
    CAIRO_FILTER_BEST,                      "best"
    CAIRO_FILTER_NEAREST,                   "nearest"
    CAIRO_FILTER_BILINEAR,                  "bilinear"
    CAIRO_FILTER_GAUSSIAN                   "gaussian"
} cairo_filter_t;

typedef enum _cairo_pattern_type {
    CAIRO_PATTERN_TYPE_SOLID,               "solid"
    CAIRO_PATTERN_TYPE_SURFACE,             "surface"
    CAIRO_PATTERN_TYPE_LINEAR,              "linear"
    CAIRO_PATTERN_TYPE_RADIAL               "radial"
} cairo_pattern_type_t;

typedef enum _cairo_font_slant {
  CAIRO_FONT_SLANT_NORMAL,                  ""  (empty string)
  CAIRO_FONT_SLANT_ITALIC,                  "italic"
  CAIRO_FONT_SLANT_OBLIQUE                  "oblique"
} cairo_font_slant_t;
                               
typedef enum _cairo_font_weight {
  CAIRO_FONT_WEIGHT_NORMAL,                 ""  (empty string)
  CAIRO_FONT_WEIGHT_BOLD                    "bold"
} cairo_font_weight_t;

typedef enum _cairo_subpixel_order {
    CAIRO_SUBPIXEL_ORDER_DEFAULT,           "default"
    CAIRO_SUBPIXEL_ORDER_RGB,               "rgb"
    CAIRO_SUBPIXEL_ORDER_BGR,               "bgr"
    CAIRO_SUBPIXEL_ORDER_VRGB,              "vrgb"
    CAIRO_SUBPIXEL_ORDER_VBGR               "vbgr"
} cairo_subpixel_order_t;
                               
typedef enum _cairo_hint_style {
    CAIRO_HINT_STYLE_DEFAULT,               "default"
    CAIRO_HINT_STYLE_NONE,                  "none"
    CAIRO_HINT_STYLE_SLIGHT,                "slight"
    CAIRO_HINT_STYLE_MEDIUM,                "medium"
    CAIRO_HINT_STYLE_FULL                   "full"
} cairo_hint_style_t;
                               
typedef enum _cairo_hint_metrics {
    CAIRO_HINT_METRICS_DEFAULT,             "default"
    CAIRO_HINT_METRICS_OFF,                 "on"
    CAIRO_HINT_METRICS_ON                   "off"
} cairo_hint_metrics_t;
                               
typedef enum _cairo_content {
    CAIRO_CONTENT_COLOR,                    "c"
    CAIRO_CONTENT_ALPHA,                    "a"
    CAIRO_CONTENT_COLOR_ALPHA,              "ca"
} cairo_content_t;
Tnis enum and everything dependent on it is probably BROKEN.

typedef enum _cairo_format {
    CAIRO_FORMAT_ARGB32,                    "argb32"
    CAIRO_FORMAT_RGB24,                     "rgb24"
    CAIRO_FORMAT_A8,                        "a8"
    CAIRO_FORMAT_A1,                        "a1"
    /* CAIRO_FORMAT_RGB16_565               "rgb16_565"  (do not use) */
} cairo_format_t;
                               
typedef enum _cairo_status {
    CAIRO_STATUS_SUCCESS,                   "success"
    CAIRO_STATUS_NO_MEMORY,                 "no_memory"
    CAIRO_STATUS_INVALID_RESTORE,           "invalid_restore"
    CAIRO_STATUS_INVALID_POP_GROUP,         "invalid_pop_group"
    CAIRO_STATUS_NO_CURRENT_POINT,          "no_current_point"
    CAIRO_STATUS_INVALID_MATRIX,            "invalid_matrix"
    CAIRO_STATUS_INVALID_STATUS,            "invalid_status"
    CAIRO_STATUS_NULL_POINTER,              "null_pointer"
    CAIRO_STATUS_INVALID_STRING,            "invalid_string"
    CAIRO_STATUS_INVALID_PATH_DATA,         "invalid_path_data"
    CAIRO_STATUS_READ_ERROR,                "read_error"
    CAIRO_STATUS_WRITE_ERROR,               "write_error"
    CAIRO_STATUS_SURFACE_FINISHED,          "surface_finished"
    CAIRO_STATUS_SURFACE_TYPE_MISMATCH,     "surface_type_mismatch"
    CAIRO_STATUS_PATTERN_TYPE_MISMATCH,     "pattern_type_mismatch"
    CAIRO_STATUS_INVALID_CONTENT,           "invalid_content"
    CAIRO_STATUS_INVALID_FORMAT,            "invalid_format"
    CAIRO_STATUS_INVALID_VISUAL,            "invalid_visual"
    CAIRO_STATUS_FILE_NOT_FOUND,            "file_not_found"
    CAIRO_STATUS_INVALID_DASH,              "invalid_dash"
    CAIRO_STATUS_INVALID_DSC_COMMENT,       "invalid_dsc_comment"
    CAIRO_STATUS_INVALID_INDEX,             "invalid_index"
    CAIRO_STATUS_CLIP_NOT_REPRESENTABLE     "clip_not_representable"
} cairo_status_t;

