53
62
-- Load definitions of all boxed records.
54
63
cairo._struct = cairo._struct or {}
55
for _, struct in pairs {
64
for index, struct in pairs {
56
65
'Context', 'Device', 'Surface', 'Rectangle', 'ScaledFont', 'FontFace',
57
66
'FontOptions', 'Region', 'RectangleInt', 'Path', 'TextExtents',
58
67
'FontExtents', 'Matrix', 'ImageSurface', 'PdfSurface', 'PsSurface',
59
68
'RecordingSurface', 'SvgSurface', 'ToyFontFace', 'RectangleList',
69
'SolidPattern', 'SurfacePattern', 'GradientPattern', 'LinearPattern',
71
MeshPattern = cairo.version_encode(1, 12, 0),
61
local lower = struct:gsub('([%l%d])([%u])', '%1_%2'):lower()
62
local gtype = ffi.load_gtype(
63
module_gobject, 'cairo_gobject_' .. lower .. '_get_type')
64
local obj = component.create(gtype, record.struct_mt, 'cairo.' .. struct)
65
cairo._struct[struct] = obj
74
if type(index) == 'string' then
78
if cairo.version >= since then
79
local lower = struct:gsub('([%l%d])([%u])', '%1_%2'):lower()
80
local gtype = ffi.load_gtype(
81
module_gobject, 'cairo_gobject_' .. lower .. '_get_type')
82
local obj = component.create(gtype, record.struct_mt, 'cairo.' .. struct)
83
cairo._struct[struct] = obj
68
87
local path_data_header = component.create(nil, record.struct_mt)
322
status = { ret = cairo.Status },
323
set_extend = { cairo.Extend },
324
get_extend = { ret = cairo.Extend },
325
set_filter = { cairo.Filter },
326
get_filter = { ret = cairo.Filter },
327
set_matrix = { cairo.Matrix },
328
get_matrix = { cairo.Matrix },
329
get_type = { ret = cairo.PatternType },
331
properties = { 'status', 'extend', 'filter', 'type' },
334
{ 'SolidPattern', parent = cairo.Pattern,
335
cprefix = 'pattern_',
337
create_rgb = { static = true, ret = { cairo.Pattern, xfer = true },
338
ti.double, ti.double, ti.double },
339
create_rgba = { static = true, ret = { cairo.Pattern, xfer = true },
340
ti.double, ti.double, ti.double, ti.double },
341
get_rgba = { ret = cairo.Status,
342
{ ti.double, dir = 'out' },
343
{ ti.double, dir = 'out' },
344
{ ti.double, dir = 'out' },
345
{ ti.double, dir = 'out' } },
349
{ 'SurfacePattern', parent = cairo.Pattern,
350
cprefix = 'pattern_',
353
cname = 'cairo_pattern_create_for_surface', static = true,
354
ret = { cairo.Pattern, xfer = true },
356
get_surface = { ret = cairo.Status, { cairo.Surface, dir = 'out' } },
360
{ 'GradientPattern', parent = cairo.Pattern,
361
cprefix = 'pattern_',
281
363
add_color_stop_rgb = { ti.double, ti.double, ti.double, ti.double },
282
364
add_color_stop_rgba = { ti.double, ti.double, ti.double,
283
365
ti.double, ti.double },
288
370
{ ti.double, dir = 'out' },
289
371
{ ti.double, dir = 'out' },
290
372
{ ti.double, dir = 'out' } },
291
create_rgb = { static = true, ret = { cairo.Pattern, xfer = true },
292
ti.double, ti.double, ti.double },
293
create_rgba = { static = true, ret = { cairo.Pattern, xfer = true },
294
ti.double, ti.double, ti.double, ti.double },
295
get_rgba = { ret = cairo.Status, { ti.double, dir = 'out' },
296
{ ti.double, dir = 'out' }, { ti.double, dir = 'out' } },
297
create_for_surface = { static = true,
298
ret = { cairo.Pattern, xfer = true },
300
get_surface = { ret = cairo.Status, { cairo.Surface, dir = 'out' } },
301
create_linear = { static = true, ret = { cairo.Pattern, xfer = true },
302
ti.double, ti.double, ti.double, ti.double },
303
get_linear_points = { ret = cairo.Status, ti.int,
376
{ 'LinearPattern', parent = cairo.GradientPattern,
377
cprefix = 'pattern_',
379
create = { cname = 'cairo_pattern_create_linear', static = true,
380
ret = { cairo.Pattern, xfer = true },
381
ti.double, ti.double, ti.double, ti.double },
382
get_linear_points = { ret = cairo.Status,
304
383
{ ti.double, dir = 'out' },
305
384
{ ti.double, dir = 'out' },
306
385
{ ti.double, dir = 'out' },
307
386
{ ti.double, dir = 'out' } },
308
create_radial = { static = true, ret = { cairo.Pattern, xfer = true },
309
ti.double, ti.double, ti.double, ti.double,
310
ti.double, ti.double },
311
get_radial_circles = { ret = cairo.Status, ti.int,
390
{ 'RadialPattern', parent = cairo.GradientPattern,
391
cprefix = 'pattern_',
393
create = { cname = 'cairo_pattern_create_radial', static = true,
394
ret = { cairo.Pattern, xfer = true },
395
ti.double, ti.double, ti.double, ti.double,
396
ti.double, ti.double },
397
get_radial_circles = { ret = cairo.Status,
312
398
{ ti.double, dir = 'out' },
313
399
{ ti.double, dir = 'out' },
314
400
{ ti.double, dir = 'out' },
315
401
{ ti.double, dir = 'out' },
316
402
{ ti.double, dir = 'out' },
317
403
{ ti.double, dir = 'out' } },
318
status = { ret = cairo.Status },
319
set_extend = { cairo.Extend },
320
get_extend = { ret = cairo.Extend },
321
set_filter = { cairo.Filter },
322
get_filter = { ret = cairo.Filter },
323
set_matrix = { cairo.Matrix },
324
get_matrix = { cairo.Matrix },
325
get_type = { ret = cairo.PatternType },
327
properties = { 'status', 'extend', 'filter', 'type' },
407
{ 'MeshPattern', parent = cairo.Pattern,
408
since = cairo.version_encode(1, 12, 0),
410
create = { cname = 'cairo_pattern_create_mesh', static = true,
411
ret = { cairo.Pattern, xfer = true } },
414
move_to = { ti.double, ti.double },
415
line_to = { ti.double, ti.double },
416
curve_to = { ti.double, ti.double, ti.double, ti.double,
417
ti.double, ti.double },
418
set_control_point = { ti.int, ti.double, ti.double },
419
set_corner_color_rgb = { ti.int, ti.double, ti.double, ti.double },
420
set_corner_color_rgba = { ti.int, ti.double, ti.double, ti.double,
422
get_patch_count = { ret = cairo.Status, { ti.int, dir = 'out' } },
423
get_path = { ret = { cairo.Path, xfer = true }, ti.int },
424
get_control_point = { ret = cairo.Status, ti.int, ti.int,
425
{ ti.double, dir = 'out' },
426
{ ti.double, dir = 'out' },
427
{ ti.double, dir = 'out' } },
428
get_corner_color_rgba = { ret = cairo.Status, ti.int, ti.int,
429
{ ti.double, dir = 'out' },
430
{ ti.double, dir = 'out' },
431
{ ti.double, dir = 'out' },
432
{ ti.double, dir = 'out' } },
545
653
properties = { 'status', 'extents', },
549
local obj = assert(cairo[name])
550
obj._parent = info.parent
552
-- Go through description of the methods and create functions
555
local prefix = 'cairo_'
556
if name ~= 'Context' then
557
prefix = prefix .. name:gsub('([%l%d])([%u])', '%1_%2'):lower() .. '_'
559
local self_arg = { obj }
560
for method_name, method_info in pairs(info.methods) do
561
method_info.name = 'cairo.' .. name .. '.' .. method_name
562
method_info.addr = cairo._module[
563
prefix .. (method_info.cname or method_name)]
564
if not method_info.static then
565
table.insert(method_info, 1, self_arg)
567
method_info.ret = method_info.ret or ti.void
568
obj._method[method_name] = core.callable.new(method_info)
572
-- Fill in addition enum/bitflag values.
573
for n, v in pairs(info.values) do
577
if info.properties then
578
-- Aggregate getters/setters into pseudoproperties implemented
581
for _, attr in pairs(info.properties) do
582
obj._attribute[attr] = {
583
get = obj._method['get_' .. attr] or obj._method[attr],
584
set = obj._method['set_' .. attr],
589
-- Load record fields definition
590
ffi.load_fields(obj, info.fields)
594
for _, struct in pairs(cairo._struct) do
595
local create = struct._method and struct._method.create
597
function struct._new(typetable, ...)
656
if cairo.version >= (info.since or 0) then
658
local obj = assert(cairo[name], name)
659
obj._parent = info.parent
661
-- Go through description of the methods and create functions
664
local cprefix = 'cairo_' ..
666
name:gsub('([%l%d])([%u])', '%1_%2'):lower() .. '_')
667
local self_arg = { obj }
668
for method_name, method_info in pairs(info.methods) do
669
if cairo.version >= (method_info.since or 0) then
670
method_info.name = 'cairo.' .. name .. '.' .. method_name
671
method_info.addr = assert(
673
method_info.cname or (cprefix .. method_name)])
674
if not method_info.static then
675
table.insert(method_info, 1, self_arg)
677
method_info.ret = method_info.ret or ti.void
678
obj._method[method_name] = core.callable.new(method_info)
683
-- Fill in addition enum/bitflag values.
684
for n, v in pairs(info.values) do
688
if info.properties then
689
-- Aggregate getters/setters into pseudoproperties
690
-- implemented as attributes.
692
for _, attr in pairs(info.properties) do
693
obj._attribute[attr] = {
694
get = obj._method['get_' .. attr] or obj._method[attr],
695
set = obj._method['set_' .. attr],
700
-- Load record fields definition
701
ffi.load_fields(obj, info.fields)
625
727
return font_options
730
-- Fix all methods using caller-alloc attribute, which is not
731
-- supported by ffi. Emulate it 'by-hand', creating Lua wrapper for
628
733
for _, info in pairs {
629
734
{ cairo.Context, 'matrix', cairo.Matrix },
630
735
{ cairo.Context, 'font_matrix', cairo.Matrix },
631
736
{ cairo.Context, 'font_options', cairo.FontOptions },
737
{ cairo.Context, 'font_extents', cairo.FontExtents },
738
{ cairo.Context, 'text_extents', cairo.TextExtents, args = 1 },
632
739
{ cairo.Pattern, 'matrix', cairo.Matrix },
633
740
{ cairo.Surface, 'font_options', cairo.FontOptions },
634
741
{ cairo.ScaledFont, 'font_matrix', cairo.Matrix },
635
742
{ cairo.ScaledFont, 'ctm', cairo.Matrix },
636
743
{ cairo.ScaledFont, 'scale_matrix', cairo.Matrix },
637
744
{ cairo.ScaledFont, 'font_options', cairo.FontOptions },
745
{ cairo.ScaledFont, 'extents', cairo.FontExtents },
746
{ cairo.ScaledFont, 'text_extents', cairo.TextExtents, args = 1 },
747
{ cairo.RecordingSurface, 'extents', cairo.Rectangle },
748
{ cairo.Region, 'extents', cairo.RectangleInt },
749
{ cairo.Region, 'get_rectangle', cairo.RectangleInt, args = 1 },
639
751
local getter_name = 'get_' ..info[2]
640
local raw_getter = assert(info[1]._method[getter_name])
641
info[1]._method[getter_name] = function(self)
642
local ret = info[3]()
643
raw_getter(self, ret)
646
info[1]._attribute[info[2]] = {
647
get = info[1][getter_name],
648
set = info[1]['set_' .. info[2]],
752
local raw_getter = info[1]._method[getter_name]
753
if not raw_getter then
754
getter_name = info[2]
755
raw_getter = info[1]._method[getter_name]
758
if info.args == 1 then
759
info[1]._method[getter_name] = function(self, arg1)
760
local ret = info[3]()
761
local res = raw_getter(self, arg1, ret)
762
return (res == nil or res) and ret or nil
765
info[1]._method[getter_name] = function(self)
766
local ret = info[3]()
767
local res = raw_getter(self, ret)
768
return (res == nil or res) and ret or nil
770
info[1]._attribute[info[2]] = {
771
get = info[1][getter_name],
772
set = info[1]['set_' .. info[2]],
652
778
-- Choose correct 'subclass' of surface on attaching to surface instances.
794
-- Also choose correct 'subclass' for patterns.
795
local pattern_type_map = {
796
SOLID = cairo.SolidPattern,
797
SURFACE = cairo.SurfacePattern,
798
LINEAR = cairo.LinearPattern,
799
RADIAL = cairo.RadialPattern,
800
MESH = cairo.MeshPattern
802
function cairo.Pattern:_attach(pattern)
803
local type = cairo.Pattern._method.get_type(pattern)
804
local repotype = pattern_type_map[type]
806
core.record.set(pattern, repotype)
810
-- Solid pattern constructor, calling either rgb or rgba variant
811
-- according to the number of arguments.
812
function cairo.SolidPattern._method.create(red, green, blue, alpha)
814
return cairo.SolidPattern._method.create_rgba(red, green, blue, alpha)
816
return cairo.SolidPattern._method.create_rgb(red, green, blue)
820
-- For backward compatibility, propagate pattern creation methods from
821
-- specific subpattern types into base cairo.Pattern class.
822
cairo.Pattern._method.create_rgb = cairo.SolidPattern.create_rgb
823
cairo.Pattern._method.create_rgba = cairo.SolidPattern.create_rgba
824
cairo.Pattern._method.create_for_surface = cairo.SurfacePattern.create
825
cairo.Pattern._method.create_linear = cairo.LinearPattern.create
826
cairo.Pattern._method.create_radial = cairo.RadialPattern.create
827
if cairo.MeshPattern then
828
cairo.Pattern._method.create_mesh = cairo.MeshPattern.create
831
-- Map all 'create' methods to constructors.
832
for _, struct in pairs(cairo._struct) do
833
local create = struct._method and struct._method.create
835
function struct._new(typetable, ...)
670
841
-- Implementation of Context.dash operations. Since ffi does not
671
842
-- support arrays of doubles, we cheat here and use array of structs
672
843
-- containing only single 'double' field.