如何使用 pycairo 创建字母间距属性?
How to create a letter spacing attribute with pycairo?
我正在使用 Pango + Cairo(通过 GObject)渲染带有 python3.7 的文本,并希望通过创建属性来设置 字母间距并将该属性附加到我的 pango 布局。
在 pango 的 gnome 文档中,我可以看到应该有一个名为 pango_attr_letter_spacing_new
的函数(自 v1.6 起)。但是,如果我 运行 Pango.attr_letter_spacing_new
,我得到错误:
AttributeError: 'gi.repository.Pango' object has no attribute 'attr_letter_spacing_new'
这感觉有点奇怪,因为我可以使用应该从 v1.22 开始可用的 pango_attr_type_get_name
。
我有一个变通方法,可以将 markup 与 <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 属性
我已经能够找到枚举值 Pango.AttrType.LETTER_SPACING
,这让我可以做这样的事情:
c = Pango.AttrClass()
c.type = Pango.AttrType.LETTER_SPACING
a = Pango.Attribute()
a.init(c)
但是,我一直没能找到一种方法来设置它的值,这让我觉得这是处理事情的错误方法:|
将其插入到 Pango.AttrList
中,出现错误(不足为奇)并在我下次使用 Pango 执行某些操作时造成 python 进程段错误:
** (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 listing a function
pango.AttrLetterSpacing
Pango.AttrLetterSpacing
=> 'gi.repository.Pango' object has no attribute 'AttrLetterSpacing'
Pango.Attrbute.LetterSpacing
=> type object 'Attribute' has no attribute 'LetterSpacing'
- Vala 的 pango 包的文档(似乎也使用 GObject),也显示了
attr_letter_spacing_new
function——这并没有多大帮助,但表明该功能应该可用通过 GObject,虽然我没试过。
看起来这个问题已经解决了,使用 pycairo 1.20.0 和 PyGObject 3.40.1:
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)
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)
我正在使用 Pango + Cairo(通过 GObject)渲染带有 python3.7 的文本,并希望通过创建属性来设置 字母间距并将该属性附加到我的 pango 布局。
在 pango 的 gnome 文档中,我可以看到应该有一个名为 pango_attr_letter_spacing_new
的函数(自 v1.6 起)。但是,如果我 运行 Pango.attr_letter_spacing_new
,我得到错误:
AttributeError: 'gi.repository.Pango' object has no attribute 'attr_letter_spacing_new'
这感觉有点奇怪,因为我可以使用应该从 v1.22 开始可用的 pango_attr_type_get_name
。
我有一个变通方法,可以将 markup 与 <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 属性
我已经能够找到枚举值 Pango.AttrType.LETTER_SPACING
,这让我可以做这样的事情:
c = Pango.AttrClass()
c.type = Pango.AttrType.LETTER_SPACING
a = Pango.Attribute()
a.init(c)
但是,我一直没能找到一种方法来设置它的值,这让我觉得这是处理事情的错误方法:|
将其插入到 Pango.AttrList
中,出现错误(不足为奇)并在我下次使用 Pango 执行某些操作时造成 python 进程段错误:
** (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 listing a function
pango.AttrLetterSpacing
Pango.AttrLetterSpacing
=>'gi.repository.Pango' object has no attribute 'AttrLetterSpacing'
Pango.Attrbute.LetterSpacing
=>type object 'Attribute' has no attribute 'LetterSpacing'
- Vala 的 pango 包的文档(似乎也使用 GObject),也显示了
attr_letter_spacing_new
function——这并没有多大帮助,但表明该功能应该可用通过 GObject,虽然我没试过。
看起来这个问题已经解决了,使用 pycairo 1.20.0 和 PyGObject 3.40.1:
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)
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)