Как создать атрибут межбуквенного интервала с помощью Pycairo? - PullRequest
9 голосов
/ 05 апреля 2019

Я использую Pango + Cairo (через GObject) для рендеринга текста с помощью python3.7 и хотел бы установить межбуквенный интервал , создав атрибут и прикрепив этот атрибут к моему макету pango.

В документации gnome для pango я вижу, что должна быть функция с именем pango_attr_letter_spacing_new (начиная с v1.6).Однако, если я запускаю Pango.attr_letter_spacing_new, я получаю ошибку:

AttributeError: 'gi.repository.Pango' object has no attribute 'attr_letter_spacing_new'

Это немного странно, так как я могу использовать pango_attr_type_get_name, который должен был быть доступен только послеv1.22.

У меня есть обходной путь с использованием разметки с <span letter_spacing="1234">, но я бы не хотел идти по этому пути.

Минимальный "Рабочий" пример

# 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'<span letter_spacing="{1024 * 10}">Hello World</span>')

# 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)

Создание атрибута LetterSpacing вручную

Мне удалось найти значение enum Pango.AttrType.LETTER_SPACING, которое позволяет мне сделать что-то вроде этого:

c = Pango.AttrClass()
c.type = Pango.AttrType.LETTER_SPACING
a = Pango.Attribute()
a.init(c)

Однако я неЯ не смог найти способ установить его значение, и это заставляет меня думать, что это неправильный подход к вещам: |

Вставить это в Pango.AttrList, выдал ошибку (неудивительно)и в следующий раз я сделал segfault для процесса Python, когда я что-то сделал с Pango:

** (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)

Другие отведения

.. которые, к сожалению, ни к чему не привели: (

  • pygtk с перечислением функции pango.AttrLetterSpacing
    • Pango.AttrLetterSpacing => 'gi.repository.Pango' object has no attribute 'AttrLetterSpacing'
    • Pango.Attrbute.LetterSpacing => type object 'Attribute' has no attribute 'LetterSpacing'
  • документация для пакета pango для Vala (который, похоже, также использует GObject), также показывает attr_letter_spacing_new функцию - это не очень помогает, но предполагает, чтофункция должна быть доступна через GObject, хотя я не пробовал.
...