How to create a letter spacing attribute with pycairo? : <p>I'm using Pango + Cairo (through GObject) to render text with python3.7, and would like to set the <em>letter spacing</em> by creating an attribute and attaching that attribute to my pango layout.</p>

<p>In the gnome documentation for pango, I can see that there should be a function called <a href="https://developer.gnome.org/pango/stable/pango-Text-Attributes.html#pango-attr-letter-spacing-new" rel="noreferrer"><code>pango_attr_letter_spacing_new</code></a> (since v1.6). However, if I run <code>Pango.attr_letter_spacing_new</code>, I get the error:</p>

<pre><code>AttributeError: 'gi.repository.Pango' object has no attribute 'attr_letter_spacing_new'
</code></pre>

<p>This feels a bit strange, since I can use the <a href="https://developer.gnome.org/pango/stable/pango-Text-Attributes.html#pango-attr-type-get-name" rel="noreferrer"><code>pango_attr_type_get_name</code></a> which should only have been available since v1.22.</p>

<p>I have a work-around by using markup with <code>&lt;span letter_spacing="1234"&gt;</code> but I would rather not go down this route.</p>

<h2>Minimal "Working" Example</h2>

<pre class="lang-py prettyprint-override"><code># pip install pycairo==1.18.0 pygobject==3.32.0

import cairo
import gi
gi.require_version('Pango', '1.0')
gi.require_version('PangoCairo', '1.0')
from gi.repository import Pango, PangoCairo

width, height = 328, 48

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
context = cairo.Context(surface)
layout = PangoCairo.create_layout(context)

font_desc = Pango.font_description_from_string('Sans, 40px')
layout.set_font_description(font_desc)

# What I can do
layout.set_markup(f'&lt;span letter_spacing="{1024 * 10}"&gt;Hello World&lt;/span&gt;')

# What I would like to do
if False:
    letter_spacing_attr = Pango.attr_letter_spacing_new(1024 * 10)

    attr_list = Pango.AttrList()
    attr_list.insert(letter_spacing_attr)
    layout.set_attributes(attr_list)

    layout.set_text('Hello World')

PangoCairo.show_layout(context, layout)

with open('help-me.png', 'wb') as image_file:
    surface.write_to_png(image_file)
</code></pre>

<h3>Manually creating a LetterSpacing attribute</h3>

<p>I have been able to find the enum value <code>Pango.AttrType.LETTER_SPACING</code>, which allows me to do something like this:</p>

<pre><code>c = Pango.AttrClass()
c.type = Pango.AttrType.LETTER_SPACING
a = Pango.Attribute()
a.init(c)
</code></pre>

<p>However, I haven't been able to find a way to set the value of it, and it makes me think it is the wrong way to approach things :|</p>

<p>Insert this into an <code>Pango.AttrList</code>, gave an error (not surprisingly) and made the python process segfault next time I did something with Pango: </p>

<pre><code>** (process:17183): WARNING **: 12:00:56.985: (gi/pygi-struct-marshal.c:287):pygi_arg_struct_from_py_marshal: runtime check failed: (g_type_is_a (g_type, G_TYPE_VARIANT) || !is_pointer || transfer == GI_TRANSFER_NOTHING)
</code></pre>

<h3>Other leads</h3>

<p>.. that sadly have lead nowhere :(</p>

<ul>
<li><a href="https://developer.gnome.org/pygtk/stable/class-pangoattribute.html" rel="noreferrer">pygtk listing a function <code>pango.AttrLetterSpacing</code></a>

<ul>
<li><code>Pango.AttrLetterSpacing</code> => <code>'gi.repository.Pango' object has no attribute 'AttrLetterSpacing'</code></li>
<li><code>Pango.Attrbute.LetterSpacing</code> => <code>type object 'Attribute' has no attribute 'LetterSpacing'</code></li>
</ul></li>
<li>the documentation for the pango packge for Vala (which seems to use GObject as well), also shows the <a href="https://valadoc.org/pango/Pango.attr_letter_spacing_new.html" rel="noreferrer"><code>attr_letter_spacing_new</code> function</a> -- this doesn't really help that much, but suggests that the function should be available through GObject, although I haven't tried.</li>
</ul>
