开罗中的笔画对齐

3
许多图形软件允许用户选择他们想要绘制形状周围区域的边框位置,可以是形状内部、外部或中心。例如,下面展示了同一个正方形,分别沿中心、内部和外部绘制边框:

enter image description here

我可以根据描边的宽度调整路径的大小,但我想先检查是否有内置支持。
我正在使用Ruby,但如果有C方法可以实现这个功能,那么它很可能也可以在Ruby绑定中使用。
在Cairo中,是否有一种方法可以在路径的外部或内部绘制描边,而不是沿着中心线绘制?
2个回答

2

要在路径内描边,需要将路径设置为剪切区域,然后描边路径;任何位于剪切区域之外的描边部分都将不可见...


1
谢谢,这个很好用,可以在路径内部描边。我使用了 clip_preserve() 将路径设置为剪辑区域,同时保持路径处于激活状态,然后使用两倍于所需描边宽度的线条进行描边。一半的描边宽度将位于剪辑区域内并可见。最后,使用 reset_clip() 恢复原始剪辑区域。 - drootang

2

不,没有这样的内置方法。

可以使用临时表面来近似实现此功能,该表面稍后将用作遮罩。例如,要执行“外部”操作,您首先需要使用“透明”填充临时表面,然后使用两倍于所需线宽度的“不透明”描边,最后使用“透明”填充形状以消除线宽度的内部部分。然后可以使用生成的表面作为遮罩。

“内部”类似,但需要一个额外的技巧:同样是透明表面和两倍线宽的描边。现在需要删除此描边的外部部分。对此,需要使用奇偶环绕规则的路径。通过在此路径中添加一个大小与表面相同的矩形来反转路径,从而允许通过填充删除所有外部内容。 对于非零环绕规则...我没有任何即时想法(好吧,另一个临时表面,然后通过使用SUBTRACT运算符对其进行反转?)。

绘制路径外部的示例代码(请参见注释):

static void draw_outside_of_path(cairo_t *cr) {
    double line_width = cairo_get_line_width(cr);
    cairo_pattern_t *mask;

    cairo_push_group_with_content(cr, CAIRO_CONTENT_ALPHA);

    cairo_set_line_width(cr, 2 * line_width);

    cairo_set_source_rgba(cr, 0, 0, 0, 1);
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    cairo_stroke_preserve(cr);

    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
    cairo_fill_preserve(cr);

    mask = cairo_pop_group(cr);

    cairo_mask(cr, mask);
    cairo_pattern_destroy(mask);
}

1
这个描述现在导向了一些C语言的示例代码:https://gitlab.freedesktop.org/cairo/cairo/-/issues/609 - Uli Schlachter
我已经为这个问题(“外部”)工作了很长时间,你在上面的评论中提供的代码非常有帮助。请在您的答案中包含该代码,以便如果其他人遇到此问题,他们不会错过它。我知道谷歌搜索“cairo draw a border outside a shape”将此页面作为我的顶级结果之一。 - twiddler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接