开罗保存的路径与变换呈现“向后”

时间:2015-07-21 20:45:47

标签: cairo

以下代码示例位于Lua中,旨在与Conky一起使用。我的想法是计算一个复杂的路径,保存它,然后渲染两次 - 一次作为填充区域,然后再作为描边路径,从而创建一个轮廓区域。

问题在于,与直接渲染相比,保存的路径似乎呈现“向后”。

第一部分创建一个绿色的旋转L形,按预期显示。

第二部分尝试创建与保存路径相同的L形,然后将其渲染为红色。生成的路径不是旋转出来的,但是因为在添加路径之前我没有调用cairo_rotate(),所以我认为这是有道理的。

第三部分呈现一组逐渐旋转的青色L形,显示为预期。

第四部分尝试与第三部分做同样的事情,这次使用保存的路径,并以黄色渲染。但这些路径走向了错误的方向。

我的 guess 是cairo转换函数将它们的转换应用于cairo_t上下文中累积的未转录路径组件(如果有)。但是我不太明白为什么它会以一种方式“前进”而另一种方式“倒退”。

我对开罗路径和变形的误解是什么?

function tests (cr)
    local wiggle
    local mat_base = cairo_matrix_t:create ()
    tolua.takeownership (mat_base)

    cairo_set_line_width (cr, 4)
    cairo_identity_matrix (cr)

    ---
    -- Direct stroke of L-shaped figure.
    cairo_save (cr)

        cairo_translate (cr, 128, 128)
        cairo_new_path (cr)
        cairo_rotate (cr, math.pi / 6)
        cairo_move_to (cr, 150, 0)
        cairo_line_to (cr, 0, 0)
        cairo_line_to (cr, 0, 50)

        cairo_set_source_rgb (cr, 0, 1, 0)
        cairo_stroke (cr)

    cairo_restore (cr)
    ---
    -- Capture L-shaped figure as path, then render.
    cairo_save (cr)

        cairo_translate (cr, 384, 128)
        cairo_new_path (cr)
        cairo_rotate (cr, math.pi / 6)
        cairo_move_to (cr, 150, 0)
        cairo_line_to (cr, 0, 0)
        cairo_line_to (cr, 0, 50)
        wiggle = cairo_copy_path (cr)

    cairo_restore (cr)
    cairo_save (cr)

        cairo_translate (cr, 384, 128)
        cairo_new_path (cr)
        cairo_append_path (cr, wiggle)
        cairo_set_source_rgb (cr, 1, 0, 0)
        cairo_stroke (cr)

        cairo_path_destroy (wiggle)

    cairo_restore (cr)
    ---
    -- Direct stroke of a set of rotated L-shaped figures.
    cairo_save (cr)

        cairo_translate (cr, 640, 128)
        cairo_get_matrix (cr, mat_base)
        cairo_new_path (cr)
        for i = 0, 4 do
            cairo_set_matrix (cr, mat_base)
            cairo_rotate (cr, i * math.pi / 6)
            cairo_move_to (cr, 150, 0)
            cairo_line_to (cr, 0, 0)
            cairo_line_to (cr, 0, 50)
        end
        cairo_set_source_rgb (cr, 0, 1, 1)
        cairo_stroke (cr)

    cairo_restore (cr)
    ---
    -- Capture rotated L-shaped figures as path, then render.
    cairo_save (cr)

        cairo_translate (cr, 896, 128)
        cairo_get_matrix (cr, mat_base)
        cairo_new_path (cr)
        for i = 0, 4 do
            cairo_set_matrix (cr, mat_base)
            cairo_rotate (cr, i * math.pi / 6)
            cairo_move_to (cr, 150, 0)
            cairo_line_to (cr, 0, 0)
            cairo_line_to (cr, 0, 50)
        end
        wiggle = cairo_copy_path (cr)

    cairo_restore (cr)
    cairo_save (cr)

        cairo_new_path (cr)
        cairo_translate (cr, 896, 128)
        cairo_append_path (cr, wiggle)
        cairo_set_source_rgb (cr, 1, 1, 0)
        cairo_stroke (cr)

        cairo_path_destroy (wiggle)

    cairo_restore (cr)
    --
end

Path rendering

1 个答案:

答案 0 :(得分:0)

当您致电cairo_copy_path时,路径以当前用户空间表示。因此,如果您先绘制一条路径,然后再调用cairo_rotate(), cairo_copy_path(),则生成的路径将包含完全相同的最后一次旋转。

因此,在红色示例中,您在撤消旋转之前复制路径,因此看起来没有旋转。

在黄色示例中,您在所有旋转后复制路径,因此第一次旋转的方向与蓝色方向不同。

尝试将a = cairo_copy_path(cr)替换为cairo_save(cr) ; cairo_identity_matrix(cr) ; a = cairo_copy_path(cr) ; cairo_restore(cr)。这样你就可以获得表面坐标中的路径,这似乎更像你期望的那样。