以下是在ArchLinux上使用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", recwidth, 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, None) as recsrf:
ctx = cairo.Context(recsrf)
ctx.select_font_face("Arial", cairo.FontSlant.NORMAL, 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.0, 0.5)
ctx.set_line_width(0.01)
ctx.rectangle(x_bearing, y_bearing, width, height)
ctx.stroke()
ext2 = recsrf.ink_extents()
print(ext2)
x0, y0, recwidth, recheight = ext2
with cairo.PDFSurface("RecordingSurface.pdf", recwidth, recheight) as pdfsrf:
ctx = cairo.Context(pdfsrf)
ctx.set_source_surface(recsrf, -x0, -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.FontSlant.NORMAL, 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.0, 0.0, 0.5)
ctx2.set_line_width(0.01)
ctx2.rectangle(1 + x_bearing2, 10 + y_bearing2, width2, 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", 15, 15) as pdfsrf2:
ctx2 = cairo.Context(pdfsrf2)
ctx2.move_to(1, 10)
ctx2.select_font_face("Arial", cairo.FontSlant.NORMAL, 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.0, 0.0, 0.5)
ctx2.set_line_width(0.01)
ctx2.rectangle(1 + x_bearing2, 10 + y_bearing2, width2, height2)
ctx2.stroke()
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 = 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.0, 0.5)
ctx.set_line_width(0.01)
ctx.rectangle(x_bearing, y_bearing, width, height)
ctx.stroke()
ext2 = recsrf.ink_extents()
print(ext2)
x0, y0, recwidth, recheight = ext2
with cairo.PDFSurface("RecordingSurface.pdf", recwidth, recheight) as pdfsrf:
ctx = cairo.Context(pdfsrf)
ctx.set_source_surface(recsrf, -x0, -y0)
ctx.paint()
现在,image from the RecordingSurface的帧太大而不是太小,取整后的数字看起来不同:
cairo.TextExtents(x_bearing=-0.0146484375, y_bearing=-7.158203125, width=11.5966796875, height=9.2626953125, x_advance=11.669921875, y_advance=0.0)
cairo.TextExtents(x_bearing=-1.0, y_bearing=-8.0, width=13.0, height=11.0, x_advance=12.0, y_advance=0.0)
(-2.0, -9.0, 15.0, 13.0)
这是一个bug,还是该机制在RecordingSurface上根本不可靠
目前没有回答
相关问题 更多 >
编程相关推荐