我一直在通过gtkd搞乱一些非常简单的网格模式 - 围绕GTK + 3的包装,我很困惑。我有两个并行的代码片段。一个使用Mesh Pattern moveTo(),lineTo()和curveTo()方法,以及一个相应的Cairo上下文方法
double x = 30, y = 50, r = 100;
MeshPattern mesh = new MeshPattern();
mesh.beginPatch();
mesh.moveTo(x,y);
mesh.lineTo(x+r, y);
//mesh.curveTo(x+25, y-25, x+r-25, y+25, x+r,y);
//mesh.curveTo(x-25, y-25, x+r-25, y+25, x+r,y);
//mesh.curveTo(x, y-50, x+r, y-50, x+r,y);
//mesh.curveTo(x+r+50, y, x+r+50, y+r, x+r, y+r);
//mesh.lineTo(x+r, y+r);
mesh.lineTo(x, y+r);
mesh.lineTo(x, y);
for (int i = 0; i < 4; i++)
mesh.setCornerColorRgba(i,0,0,0,1);
mesh.endPatch();
double x = 180, y = 50, r = 100;
c.moveTo(x,y);
c.lineTo(x+r, y);
//c.curveTo(x+25, y-25, x+r-25, y+25, x+r, y);
//c.curveTo(x-25, y-25, x+r-25, y+25, x+r, y);
//c.curveTo(x, y-50, x+r, y-50, x+r,y);
//c.curveTo(x+r+50, y, x+r+50, y+r, x+r, y+r);
c.stroke();
注释掉的行是我尝试的序列,导致以下结果。四个lineTo()案例符合我的预期:
Four lines http://britseyeview.com/patch0.png
curveTo()的第一次使用也做了我的预期,除了在线上有一些抗锯齿,而补丁的边缘非常可怕:
Control points between corner 0 and corner 1 http://britseyeview.com/patch1.png
下一次尝试将第一个bezier控制点放在从第0角到第1角的一行之外。这不是我所期望的,尽管该行是:
One control point not between corner 0 and corner 1 http://britseyeview.com/patch2.png
我觉得第四面是一条直线现在是弯曲的,这似乎是不对的。我继续调查当控制点刚刚达到极限时发生了什么 - 这似乎没问题:
Control points on the limit http://britseyeview.com/patch3.png
推动我的运气,我添加了第二条曲线。在这种情况下,角落1的终点不受尊重:
Adding a second similar curve between corner 1 and corner 2 http://britseyeview.com/patch4.png
然而,我认为bezier曲线控制的是颜色,而不是补丁的形状,所以改变那个角落的颜色应该会对正在发生的事情有所了解,并且确实如此:
With a different color http://britseyeview.com/patch5.png
此行为是否符合预期?
答案 0 :(得分:1)
我对你的问题没什么可说的(对不起!),但我不想丢失你所做的代码的以下C语言翻译:
#include <cairo.h>
static inline void move_to(cairo_pattern_t *mesh, cairo_t *cr, double x, double y)
{
cairo_move_to(cr, x, y);
cairo_mesh_pattern_move_to(mesh, x, y);
}
static inline void line_to(cairo_pattern_t *mesh, cairo_t *cr, double x, double y)
{
cairo_line_to(cr, x, y);
cairo_mesh_pattern_line_to(mesh, x, y);
}
static inline void curve_to(cairo_pattern_t *mesh, cairo_t *cr, double a, double b, double c, double d, double e, double f)
{
cairo_curve_to(cr, a, b, c, d, e, f);
cairo_mesh_pattern_curve_to(mesh, a, b, c, d, e, f);
}
static inline cairo_pattern_t *create_mesh(cairo_t *cr)
{
cairo_pattern_t *mesh = cairo_pattern_create_mesh();
double x = 30, y = 50, r = 100;
cairo_mesh_pattern_begin_patch(mesh);
move_to(mesh, cr, x, y);
#define CASE 3
#if CASE == 1
line_to(mesh, cr, x+r, y);
line_to(mesh, cr, x+r, y+r);
#elif CASE == 2
curve_to(mesh, cr, x+25, y-25, x+r-25, y+25, x+r,y);
line_to(mesh, cr, x+r, y+r);
#elif CASE == 3
curve_to(mesh, cr, x-25, y-25, x+r-25, y+25, x+r,y);
line_to(mesh, cr, x+r, y+r);
#elif CASE == 4
curve_to(mesh, cr, x, y-50, x+r, y-50, x+r,y);
curve_to(mesh, cr, x+r+50, y, x+r+50, y+r, x+r, y+r);
#else
#error
#endif
line_to(mesh, cr, x, y+r);
line_to(mesh, cr, x, y);
cairo_mesh_pattern_set_corner_color_rgba(mesh, 0, 1, 0, 0, 1);
cairo_mesh_pattern_set_corner_color_rgba(mesh, 1, 0, 1, 0, 1);
cairo_mesh_pattern_set_corner_color_rgba(mesh, 2, 0, 0, 1, 1);
cairo_mesh_pattern_set_corner_color_rgba(mesh, 3, 1, 1, 1, 1);
cairo_mesh_pattern_end_patch(mesh);
return mesh;
}
int main()
{
cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 500, 500);
cairo_t *cr = cairo_create (s);
cairo_set_source(cr, create_mesh(cr));
cairo_paint(cr);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_stroke(cr);
cairo_destroy(cr);
cairo_surface_write_to_png(s, "out.png");
cairo_surface_destroy(s);
return 0;
}
答案 1 :(得分:1)
是的,这种行为是预期的。请参阅PDF规范的第195页:
http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf
缺少抗锯齿是因为cairo网格渲染器没有抗锯齿补丁并且使它这样做会非常困难。如果它做了抗锯片补丁,那么从多个相邻补丁构建的图像将显示可见的接缝。这可能是为什么Adobe Reader和Ghostscript不会消除网格渐变的原因。
获得抗锯齿边缘的一种方法是在边缘周围设置剪辑路径。您可能需要使补丁略大于剪辑路径才能生效。