1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
------------------------------------------------------------------------------
--
-- LGI Pango override module.
--
-- Copyright (c) 2012 Pavel Holejsovsky
-- Licensed under the MIT license:
-- http://www.opensource.org/licenses/mit-license.php
--
------------------------------------------------------------------------------
local pairs, rawget = pairs, rawget
local table = require 'table'
local lgi = require 'lgi'
local Pango = lgi.Pango
local core = require 'lgi.core'
local gi = core.gi
local ffi = require 'lgi.ffi'
local ti = ffi.types
local record = require 'lgi.record'
local component = require 'lgi.component'
-- Provide defines which are not present in the GIR
local _ = Pango.SCALE
for name, value in pairs {
SCALE_XX_SMALL = 1 / (1.2 * 1.2 * 1.2),
SCALE_X_SMALL = 1 / (1.2 * 1.2),
SCALE_SMALL = 1 / 1.2,
SCALE_MEDIUM = 1,
SCALE_LARGE = 1.2,
SCALE_X_LARGE = 1.2 * 1.2,
SCALE_XX_LARGE = 1.2 * 1.2 * 1.2,
} do
if not Pango[name] then
Pango._constant[name] = value
end
end
-- Because of https://bugzilla.gnome.org/show_bug.cgi?id=672133 Pango
-- enums are not gtype based on some platforms. If we detect non-gtype
-- enum, reload it using ffi and GEnumInfo machinery.
for _, enum in pairs {
'AttrType', 'Underline', 'BidiType', 'Direction', 'CoverageLevel',
'Style', 'Variant', 'Weight', 'Stretch', 'FontMask', 'Gravity',
'GravityHint', 'Alignment', 'WrapMode', 'EllipsizeMode', 'RenderPart',
'Script', 'TabAlign',
} do
if not Pango[enum]._gtype then
local gtype = ffi.load_gtype(
core.gi.Pango.resolve,
'pango_' .. core.uncamel(enum) .. '_get_type')
Pango._enum[enum] = ffi.load_enum(gtype, 'Pango.' .. enum)
end
end
local pango_layout_set_text = Pango.Layout.set_text
function Pango.Layout:set_text(text, len)
pango_layout_set_text(self, text, len or -1)
end
local pango_layout_set_markup = Pango.Layout.set_markup
function Pango.Layout:set_markup(text, len)
pango_layout_set_markup(self, text, len or -1)
end
-- Pango.Layout:set_attributes() has incorrect transfer-full
-- annotation on its attrs argument. Workaround for
-- https://github.com/pavouk/lgi/issues/60
if gi.Pango.Layout.methods.set_attributes.args[1].transfer ~= 'none' then
local _ = Pango.Layout.set_attributes
Pango.Layout.set_attributes = core.callable.new {
addr = core.gi.Pango.resolve.pango_layout_set_attributes,
name = 'Pango.Layout.set_attributes',
ret = ti.void,
gi.Pango.Layout.methods.new.return_type,
gi.Pango.Layout.methods.set_attributes.args[1].typeinfo,
}
end
-- Add attributes simulating logically missing properties in Pango classes.
for compound, attrs in pairs {
[Pango.Layout] = {
'attributes', 'font_description', 'width', 'height', 'wrap', 'context',
'is_wrapped', 'ellipsize', 'is_ellipsized', 'indent', 'spacing',
'justify', 'auto_dir', 'alignment', 'tabs', 'single_paragraph_mode',
'baseline', 'line_count', 'lines', 'log_attrs', 'character_count',
'text', 'markup',
},
[Pango.Context] = {
'base_dir', 'base_gravity', 'font_description', 'font_map', 'gravity',
'gravity_hint', 'language', 'matrix',
},
[Pango.FontMetrics] = {
'ascent', 'descent', 'approximate_char_width', 'approximate_digit_width',
'underline_thickness', 'underline_position',
'strikethrough_thinkess', 'strikethrough_position',
},
} do
compound._attribute = rawget(compound, '_attribute') or {}
for _, name in pairs(attrs) do
if not compound._property or not compound._property[name] then
compound._attribute[name] = {
get = compound['get_' .. name] or compound[name],
set = compound['set_' .. name],
}
end
end
end
-- Handling of poor-man's OO invented by Pango.Attribute related
-- pseudoclasses.
Pango.Attribute._free = core.gi.Pango.Attribute.methods.destroy
for name, def in pairs {
language_new = { Pango.Language },
family_new = { ti.utf8 },
style_new = { Pango.Style },
variant_new = { Pango.Variant },
stretch_new = { Pango.Stretch },
weight_new = { Pango.Weight },
size_new = { ti.int },
size_new_absolute = { ti.int },
desc_new = { Pango.FontDescription },
foreground_new = { ti.uint16, ti.uint16, ti.uint16 },
background_new = { ti.uint16, ti.uint16, ti.uint16 },
strikethrough_new = { ti.boolean },
strikethrough_color_new = { ti.uint16, ti.uint16, ti.uint16 },
underline_new = { Pango.Underline },
underline_color_new = { ti.uint16, ti.uint16, ti.uint16 },
shape_new = { Pango.Rectangle, Pango.Rectangle },
scale_new = { ti.double },
rise_new = { ti.int },
letter_spacing_new = { ti.int },
fallback_new = { ti.boolean },
gravity_new = { Pango.Gravity },
gravity_hint_new = { Pango.GravityHint },
} do
def.addr = core.gi.Pango.resolve['pango_attr_' .. name]
def.name = 'Pango.Attribute.' .. name
def.ret = { Pango.Attribute, xfer = true }
Pango.Attribute[name] = core.callable.new(def)
end
-- Adding Pango.Attribute into the Pango.AttrList takes ownership of
-- the record. Pfft, crappy API, wrap and handle.
for _, name in pairs { 'insert', 'insert_before', 'change' } do
local raw_method = Pango.AttrList[name]
Pango.AttrList[name] = function(list, attr)
-- Invoke original method first, then unown the attribute.
raw_method(list, attr)
core.record.set(attr, false)
end
end
-- Pango.Layout:move_cursor_visually() is missing an (out) annotation
-- in older Pango releases. Work around this limitation by creating
-- custom ffi definition for this method.
if gi.Pango.Layout.methods.move_cursor_visually.args[6].direction ~= 'out' then
local _ = Pango.Layout.move_cursor_visually
Pango.Layout.move_cursor_visually = core.callable.new {
addr = core.gi.Pango.resolve.pango_layout_move_cursor_visually,
name = 'Pango.Layout.move_cursor_visually',
ret = ti.void,
gi.Pango.Layout.methods.new.return_type,
ti.boolean, ti.int, ti.int, ti.int,
{ ti.int, dir = 'out' }, { ti.int, dir = 'out' },
}
end
-- Pango.GlyphString is struct with counted array inside, until
-- Pango-1.38 which has fixed annotation. Fix for previous versions.
if gi.Pango.GlyphString.fields.glyphs.typeinfo.tag ~= 'array' then
Pango.GlyphString._attribute = { glyphs = {} }
function Pango.GlyphString._attribute.glyphs:get()
local array = core.record.field(self, Pango.GlyphString._field.glyphs)
local glyphs = {}
for i = 0, self.num_glyphs - 1 do
glyphs[i + 1] = core.record.fromarray(array, i)
end
return glyphs
end
end
|