ink_extents() 和 text_extents() 在 cairo RecordingSurface 中产生奇怪的结果

问题描述

以下已在 Arch Linux 上使用 Python 3.9.1、python-cairo 1.20.0 和 cairo 1.17.4 进行测试。

我正在尝试使用 cairo RecordingSurface 绘制包含初始大小未知的文本的图形。这应该稍后在 PDFSurface 上呈现。

一个问题:当我的 RecordingSurface 只包含文本时,ink_extents() 返回的大小似乎有点错误

#!/usr/bin/env python
import math
import cairo

text = "Ay"

with cairo.RecordingSurface(cairo.Content.COLOR_ALPHA,None) as recsrf:
    ctx = cairo.Context(recsrf)

    ctx.select_font_face("Arial",cairo.FontSlant.norMAL,cairo.FontWeight.norMAL);
    ctx.show_text(text)

    ext = recsrf.ink_extents()
    print(ext)
    x0,y0,recwidth,recheight = recsrf.ink_extents()

    with cairo.PDFSurface("RecordingSurface.pdf",recheight) as pdfsrf:
        ctx = cairo.Context(pdfsrf)
        ctx.set_source_surface(recsrf,-x0,-y0)
        ctx.paint()

产生this image。显然,字母的某些部分被剪掉了,而左边的空间太大了。输出ink_extents() 的结果是:

(-1.0,-7.0,13.0,9.0)

这看起来像四舍五入丢失了细节。

接下来,我尝试在 RecordingSurface 和直接在 PDFSurface 中使用 text_extents 在我的文本周围绘制一个矩形:

#!/usr/bin/env python
import math
import cairo

text = "Ay"

with cairo.RecordingSurface(cairo.Content.COLOR_ALPHA,cairo.FontWeight.norMAL);
    ctx.show_text(text)

    ext = ctx.text_extents(text)
    print(ext)
    x_bearing,y_bearing,width,height,x_advance,y_advance = ext

    ctx.set_source_rgba(1.0,0.0,0.5)
    ctx.set_line_width(0.01)
    ctx.rectangle(x_bearing,height)
    ctx.stroke()

    ext2 = recsrf.ink_extents()
    print(ext2)
    x0,recheight = ext2

    with cairo.PDFSurface("RecordingSurface.pdf",-y0)
        ctx.paint()

with cairo.PDFSurface("PDFSurface.pdf",15,15) as pdfsrf2:
    ctx2 = cairo.Context(pdfsrf2)

    ctx2.move_to(1,10)
    ctx2.select_font_face("Arial",cairo.FontWeight.norMAL);
    ctx2.show_text(text)

    ext3 = ctx2.text_extents(text)
    print(ext3)
    x_bearing2,y_bearing2,width2,height2,x_advance2,y_advance2 = ext3

    ctx2.set_source_rgba(1.0,0.5)
    ctx2.set_line_width(0.01)
    ctx2.rectangle(1 + x_bearing2,10 + y_bearing2,height2)
    ctx2.stroke()

image for the PDFSurface 看起来不错,而 image for the RecordingSurface 的矩形位置错误(但看起来与上面 ink_extents() 的裁剪一致)。另外,第二张图片中的白框出乎意料。

查看输出,RecordingSurface 中的 text_extents() 看起来“几乎是圆的”,但存在十进制/二进制分数转换错误(?)。

cairo.TextExtents(x_bearing=-1.0,y_bearing=-7.000000000000001,width=13.0,height=9.000000000000002,x_advance=12.0,y_advance=0.0)

ink_extents() 再次返回完全整数:

(-2.0,-8.0,15.0,11.0)

PDFSurface 中只有 text_extents() 返回精确结果:

cairo.TextExtents(x_bearing=-0.0146484375,y_bearing=-7.158203125,width=11.5966796875,height=9.2626953125,x_advance=11.669921875,y_advance=0.0)

最后的问题是:当我简单地交换两个代码块时,RecordingSurface上的结果仍然是错误的,但方式不同:

#!/usr/bin/env python
import math
import cairo

text = "Ay"

with cairo.PDFSurface("PDFSurface.pdf",height2)
    ctx2.stroke()

with cairo.RecordingSurface(cairo.Content.COLOR_ALPHA,-y0)
        ctx.paint()

现在,image from the RecordingSurface 的框架太大而不是太小,四舍五入的数字看起来不同:

cairo.TextExtents(x_bearing=-0.0146484375,y_advance=0.0)
cairo.TextExtents(x_bearing=-1.0,y_bearing=-8.0,height=11.0,y_advance=0.0)
(-2.0,-9.0,13.0)

这是一个错误,还是该机制在 RecordingSurface 上根本不可靠?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)