如何防止cairo光栅化图案填充?

时间:2019-02-25 14:59:06

标签: pdf-generation vector-graphics cairo rasterizing pycairo

大约在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高度缩放,呈现出如下所示的图案:

script output

注视PDF文件的文本确认这是位图。使用SVGSurface会产生相似的结果。有没有一种方法可以还原到旧的行为,即在最终的PDF中将PDF模式填充作为矢量填充呈现,而不是像这样栅格化?我在网上找到的唯一对此问题的参考是this unanswered question on the cairo mailing list,从2012年1月开始。

1 个答案:

答案 0 :(得分:0)

我仍然没有找到使用Pycairo严格执行此操作的方法,但是我找到了使用cairocffi(一种对Pycairo的改进,直接替代)的解决方案。 cairocffi提供了RecordingSurface类,

  

一个表面,它在表面后端界面的最高级别(即绘画,蒙版,描边,填充和show_text_glyphs的级别)记录所有绘制操作。然后,可以通过将记录表面用作源表面来相对于任何目标表面“重播”。

我将脚本修改为使用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()

这导致了非栅格化模式:

script output