如何防止 cairo 栅格化我的图案填充?
How can I prevent cairo from rasterizing my pattern fills?
2011 年左右的某个时候,我编写了一个 Pycairo 脚本来生成一个 PDF,其中包含多个自定义矢量图案填充。今天我重新运行它(Python 3.5.2,Pycairo 1.10.0),惊讶地发现所有这些图案都被渲染为低分辨率的光栅化位图。我将我的脚本缩减为这个最小的例子:
#!/usr/bin/python3
import cairo
def main():
surface = cairo.PDFSurface("test.pdf", 100, 100)
ctx = cairo.Context(surface)
pattern = make_pattern()
ctx.rectangle(10, 10, 80, 80)
ctx.set_source(pattern)
ctx.fill()
surface.finish()
def make_pattern():
pattern_surface = cairo.PDFSurface(None, 32, 8)
ctx = cairo.Context(pattern_surface)
ctx.set_line_width(.5)
ctx.set_source_rgb(0,0,0)
ctx.move_to(5, 6)
ctx.line_to(27, 2)
ctx.stroke()
pattern = cairo.SurfacePattern(pattern_surface)
pattern.set_extend(cairo.EXTEND_REPEAT)
return pattern
if __name__ == "__main__":
main()
生成的 PDF 高度缩放后呈现如下图案:
目测 PDF 文件的文本确认这是位图。使用 SVGSurface 会产生类似的结果。有没有办法恢复到旧行为,即 PDF 图案填充在最终 PDF 中呈现为矢量填充,而不是像这样被栅格化?我在网上找到的关于该问题的唯一参考是 this unanswered question on the cairo mailing list 从 2012 年 1 月开始。
我仍然没有找到严格使用 Pycairo 来执行此操作的方法,但我找到了使用 cairocffi, an improved, drop-in replacement for Pycairo. cairocffi offers the class RecordingSurface
、
的解决方案
a surface that records all drawing operations at the highest level of the surface backend interface, (that is, the level of paint, mask, stroke, fill, and show_text_glyphs). The recording surface can then be “replayed” against any target surface by using it as a source surface.
我修改了脚本以使用 cairocffi 和 RecordingSurface
:
#!/usr/bin/python3
import cairocffi as cairo
def main():
surface = cairo.PDFSurface("test.pdf", 100, 100)
ctx = cairo.Context(surface)
pattern = make_pattern()
ctx.rectangle(10, 10, 80, 80)
ctx.set_source(pattern)
ctx.fill()
surface.finish()
def make_pattern():
pattern_surface = \
cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, (0, 0, 32, 8))
ctx = cairo.Context(pattern_surface)
ctx.set_line_width(.5)
ctx.set_source_rgb(0,0,0)
ctx.move_to(5, 6)
ctx.line_to(27, 2)
ctx.stroke()
pattern = cairo.SurfacePattern(pattern_surface)
pattern.set_extend(cairo.EXTEND_REPEAT)
return pattern
if __name__ == "__main__":
main()
这导致了非光栅化模式:
2011 年左右的某个时候,我编写了一个 Pycairo 脚本来生成一个 PDF,其中包含多个自定义矢量图案填充。今天我重新运行它(Python 3.5.2,Pycairo 1.10.0),惊讶地发现所有这些图案都被渲染为低分辨率的光栅化位图。我将我的脚本缩减为这个最小的例子:
#!/usr/bin/python3
import cairo
def main():
surface = cairo.PDFSurface("test.pdf", 100, 100)
ctx = cairo.Context(surface)
pattern = make_pattern()
ctx.rectangle(10, 10, 80, 80)
ctx.set_source(pattern)
ctx.fill()
surface.finish()
def make_pattern():
pattern_surface = cairo.PDFSurface(None, 32, 8)
ctx = cairo.Context(pattern_surface)
ctx.set_line_width(.5)
ctx.set_source_rgb(0,0,0)
ctx.move_to(5, 6)
ctx.line_to(27, 2)
ctx.stroke()
pattern = cairo.SurfacePattern(pattern_surface)
pattern.set_extend(cairo.EXTEND_REPEAT)
return pattern
if __name__ == "__main__":
main()
生成的 PDF 高度缩放后呈现如下图案:
目测 PDF 文件的文本确认这是位图。使用 SVGSurface 会产生类似的结果。有没有办法恢复到旧行为,即 PDF 图案填充在最终 PDF 中呈现为矢量填充,而不是像这样被栅格化?我在网上找到的关于该问题的唯一参考是 this unanswered question on the cairo mailing list 从 2012 年 1 月开始。
我仍然没有找到严格使用 Pycairo 来执行此操作的方法,但我找到了使用 cairocffi, an improved, drop-in replacement for Pycairo. cairocffi offers the class RecordingSurface
、
a surface that records all drawing operations at the highest level of the surface backend interface, (that is, the level of paint, mask, stroke, fill, and show_text_glyphs). The recording surface can then be “replayed” against any target surface by using it as a source surface.
我修改了脚本以使用 cairocffi 和 RecordingSurface
:
#!/usr/bin/python3
import cairocffi as cairo
def main():
surface = cairo.PDFSurface("test.pdf", 100, 100)
ctx = cairo.Context(surface)
pattern = make_pattern()
ctx.rectangle(10, 10, 80, 80)
ctx.set_source(pattern)
ctx.fill()
surface.finish()
def make_pattern():
pattern_surface = \
cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, (0, 0, 32, 8))
ctx = cairo.Context(pattern_surface)
ctx.set_line_width(.5)
ctx.set_source_rgb(0,0,0)
ctx.move_to(5, 6)
ctx.line_to(27, 2)
ctx.stroke()
pattern = cairo.SurfacePattern(pattern_surface)
pattern.set_extend(cairo.EXTEND_REPEAT)
return pattern
if __name__ == "__main__":
main()
这导致了非光栅化模式: