1# cairo support
2
3Cairo library is an important part of any GTK-based setup, because GTK
4internally uses cairo exclusively for painting.  However, cairo itself
5is not built using GObject technology and thus imposes quite a problem
6for any GObject Introspection based binding, such as lgi.
7
8## Basic binding description
9
10Although internal implementation is a bit different from other fully
11introspection-enabled libraries, this difference is not visible to lgi
12user.  cairo must be imported in the same way as other libraries, e.g.
13
14    local lgi = require 'lgi'
15    local cairo = lgi.cairo
16
17Cairo library itself is organized using object-oriented style, using C
18structures as objects (e.g. `cairo_t`, `cairo_surface_t`) and
19functions as methods acting upon these objects.  lgi exports objects
20as classes in the `cairo` namespace, e.g. `cairo.Context`,
21`cairo.Surface` etc.  To create new object instance, cairo offers
22assorted `create` methods, e.g. `cairo_create` or
23`cairo_pattern_create`, which are mapped as expected to
24`cairo.Context.create` and `cairo.Pattern.create`.  It is also
25possible to invoke them using lgi's 'constructor' syntax, i.e. to
26create new context on specified surface, it is possible to use either
27`local cr = cairo.Context.create(surface)` or `local cr =
28cairo.Context(surface)`.
29
30### Version checking
31
32`cairo.version` and `cairo.version_string` fields contain current
33runtime cairo library version, as returned by their C counterparts
34`cairo_version()` and `cairo_version_string()`.  Original
35`CAIRO_VERSION_ENCODE` macro is reimplemented as
36`cairo.version_encode(major, minor, micro)`.  For example, following
37section shows how to guard code which should be run only when cairo
38version is at least 1.12:
39
40    if cairo.version >= cairo.version_encode(1, 12, 0) then
41       -- Cairo 1.12-specific code
42    else
43       -- Fallback to older cairo version code
44    end
45
46### Synthetic properties
47
48There are many getter and setter functions for assorted cairo objects.
49lgi exports them in the form of method calls as the native C interface
50does, and it also provides property-like access, so that it is
51possible to query or assign named property of the object.  Following
52example demonstrates two identical ways to set and get line width on
53cairo.Context instance:
54
55    local cr = cairo.Context(surface)
56    cr:set_line_width(10)
57    print('line width ', cr:get_line_width())
58
59    cr.line_width = 10
60    print('line width ', cr.line_width)
61
62In general, any kind of `get_xxx()` method call on any cairo object
63can be replaced using `xxx` property on the object, and any
64`set_xxx()` method can be replaced by setting `xxx` property.
65
66### cairo.Surface hierarchy
67
68Cairo provides basic rendering surface object `cairo.Surface`, and a
69bunch of specialized surfaces implementing rendering to assorted
70targets, e.g. `cairo.ImageSurface`, `cairo.PdfSurface` etc.  These
71surface provide their own class, which is logically inherited from
72`cairo.Surface`.  lgi fully implements this inheritance, so that
73calling `cairo.ImageSurface()` actually creates an instance of
74`cairo.ImageSurface` class, which provides all methods abd properties
75of `cairo.Surface` and and some specialized methods and properties
76like `width` and `height`.
77
78In addition, lgi always assigns the real type of the surface, so that
79even when `cairo.Context.get_target()` method (or
80`cairo.Context.target` property) is designated as returning
81`cairo.Surface` instance, upon the call the type of the surface is
82queried and proper kind of surface type is really returned.  Following
83example demonstrates that it is possible to query
84`cairo.ImageSurface`-specific `width` property directly on the
85`cairo.Context.target` result.
86
87    -- Assumes the cr is cairo.Context instance with assigned surface
88    print('width of the surface' cr.target.width)
89
90It is also possible to use lgi generic typechecking machinery for
91checking the type of the surface:
92
93    if cairo.ImageSurface:is_type_of(cr.target) then
94	print('width of the surface' cr.target.width)
95    else
96	print('unsupported type of the surface')
97    end
98
99### cairo.Pattern hierarchy
100
101cairo's pattern API actually hides the inheritance of assorted pattern
102types.  lgi binding brings this hierarchy up in the same way as for
103surfaces described in previous section.  Following hierarchy exists:
104
105    cairo.Pattern
106        cairo.SolidPattern
107	cairo.SurfacePattern
108	cairo.GradientPattern
109	    cairo.LinearPattern
110	    cairo.RadialPattern
111	cairo.MeshPattern
112
113Patterns can be created using static factory methods on
114`cairo.Pattern` as documented in cairo documentation.  In addition,
115lgi maps creation methods to specific subclass constructors, so
116following snippets are equivalent:
117
118    local pattern = cairo.Pattern.create_linear(0, 0, 10, 10)
119    local pattern = cairo.LinearPattern(0, 0, 10, 10)
120
121### cairo.Context path iteration
122
123cairo library offers iteration over the drawing path returned via
124`cairo.Context.copy_path()` method.  Resulting path can be iterated
125using `pairs()` method of `cairo.Path` class.  `pairs()` method
126returns iterator suitable to be used in Lua 'generic for' construct.
127Iterator returns type of the path element, optionally followed by 0, 1
128or 3 points.  Following example shows how to iterate the path.
129
130    local path = cr:copy_path()
131    for kind, points in path:pairs() do
132       io.write(kind .. ':')
133          for pt in ipairs(points) do
134             io.write((' { %g, %g }'):format(pt.x, pt.y))
135	  end
136       end
137    end
138
139## Impact of cairo on other libraries
140
141In addition to cairo itself, there is a bunch of cairo-specific
142methods inside Gtk, Gdk and Pango libraries.  lgi wires them up so
143that they can be called naturally as if they were built in to the
144cairo core itself.
145
146### Gdk and Gtk
147
148`Gdk.Rectangle` is just a link to `cairo.RectangleInt` (similar to C,
149where `GdkRectangle` is just a typedef of `cairo_rectangle_int_t`).
150`gdk_rectangle_union` and `gdk_rectangle_intersect` are wired as a
151methods of `Gdk.Rectangle` as expected.
152
153`Gdk.cairo_create()` is aliased as a method
154`Gdk.Window.cairo_create()`.  `Gdk.cairo_region_create_from_surface()`
155is aliased as `cairo.Region.create_from_surface()`.
156
157`cairo.Context.set_source_rgba()` is overriden so that it also accepts
158`Gdk.RGBA` instance as an argument.  Similarly,
159`cairo.Context.rectangle()` alternatively accepts `Gdk.Rectangle` as
160an argument.
161
162`cairo.Context` has additional methods `get_clip_rectangle()`,
163`set_source_color()`, `set_source_pixbuf()`, `set_source_window` and
164`region`, implemented as calls to appropriate `Gdk.cairo_xxx`
165functions.
166
167Since all these extensions are implemented inside Gdk and Gtk
168libraries, they are present only when `lgi.Gdk` is loaded.  When
169loading just pure `lgi.cairo`, they are not available.
170
171### PangoCairo
172
173Pango library contains namespace `PangoCairo` which implements a bunch
174of cairo-specific helper functions to integrate Pango use with cairo
175library.  It is of course possible to call them as global methods of
176PangoCairo interface, however lgi override maps the also to methods
177and attributes of other classes to which they logically belong.
178