如何正确构造简单的重复形状图案以用作开罗的填充?

How to correctly construct simple repeating-shape pattern for use as fill in Cairo?

我对 Cairo 很陌生,正在研究一个生成小型 SVG 图像的程序。我想用同样在开罗构建的重复图案填充其中一些图像的区域 - 换句话说,我一直在尝试在内存中的开罗表面上绘制,然后将其用作源图案来填充路径在另一个表面上。从 API 来看,这看起来应该相对简单,但我似乎遗漏了一些东西,因为尝试从具有背景颜色的表面和简单的形状中尝试像图案一样简单的东西只填充表面的背景颜色。

下面是一个相对最小化的示例(一直使用路径而不是矩形,因为我的预期用途涉及任意形状):

import cairo

def drawPattern(ctx):
    ctx.move_to(0.0, 0.0)
    ctx.line_to(0.0, 1.0)
    ctx.line_to(1.0, 1.0)
    ctx.line_to(1.0, 0.0)
    ctx.line_to(0.0, 0.0)
    ctx.set_source_rgb(0.8, 1.0, 0)
    ctx.fill()
    ctx.move_to(0.5, 0.8)
    ctx.line_to(0.8, 0.5)
    ctx.line_to(0.5, 0.2)
    ctx.line_to(0.2, 0.5)
    ctx.line_to(0.5, 0.8)
    ctx.set_source_rgb(0, 0, 0)
    ctx.fill()

surf = cairo.SVGSurface("test.svg", 256, 256)
context = cairo.Context(surf)
context.scale(256, 256)

patternSurf = cairo.SVGSurface(None, 32, 32)
patternCtx = cairo.Context(patternSurf)
patternCtx.scale(32, 32)
drawPattern(patternCtx)
patternSurf.flush()

context.move_to(0.0, 0.0)
context.line_to(0.0, 1.0)
context.line_to(1.0, 1.0)
context.line_to(1.0, 0.0)
context.line_to(0.0, 0.0)
context.set_source_rgb(0.0, 1.0, 0.0)
context.fill()

context.move_to(0.5, 0.0)
context.line_to(0.5, 1.0)
context.line_to(1.0, 1.0)
context.line_to(1.0, 0.0)
context.line_to(0.5, 0.0)
context.set_source_surface(patternSurf)
context.get_source().set_extend(cairo.Extend.REPEAT)
context.fill()

surf.finish()

我对这个例子的目标是它会产生一个简单的正方形图像,左半边是绿色,右半边是黄绿色,带有重复的黑色菱形。然而,钻石没有出现,尽管黄绿色背景颜色出现了(这代表了我一直遇到的更广泛的问题)。如何对此进行更正,以便将带有黑色菱形的表面正确用作另一个表面的重复图案填充?

我正在使用 Pycairo,安装了 Cairo 版本 1.14.12,但我想这个问题可能是 Cairo 用法的一般问题,而不是特定于 Python 绑定。

您在将图像绘制到 surf 时将其放大。由于初始 context.scale(256, 256)patternSurf 的表面内容在绘制前以 256 倍缩放。当我在调用 set_source_surface 之前添加 contxt.scale(1.0/256.0, 1.0/256.0) 时,我得到了我猜你期望的结果。