2014-01-06 19 views
0

我一直在通过gtkd - 一个围绕GTK + 3的包装来解决一些非常简单的网格模式,我很困惑。我有两个并行的代码片段。一个使用网格图案的moveTo(),了lineTo()和curveTo()方法,以及一个相应的开罗上下文方法开罗1.12网格模式是否正常工作

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()也做什么,我希望,除了有上线的一些抗锯齿,而修补OS的边缘漂亮可怕的:

Control points between corner 0 and corner 1 http://britseyeview.com/patch1.png

下一次尝试将第一个贝塞尔控制点的直线“外部”从角落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

然而,我推定该贝塞尔曲线控制颜色,贴剂的不形状,因此更改在该拐角的颜色应该抛出刚刚发生了一些光,它的作用:

With a different color http://britseyeview.com/patch5.png

如预期这种行为?

回答

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

是这种行为是期待。查看PDF规范的195页:

http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf

缺乏抗锯齿是因为开罗网格渲染器不抗混叠补丁,并使它这样做将是非常困难的。如果它做了antialias修补程序,那么从多个相邻修补程序构建的图像将显示可见的接缝。这可能是Adobe Reader和Ghostscript没有抗锯齿网格渐变的原因。

获得抗锯齿边缘的一种方法是在边缘周围设置剪辑路径。您可能需要使修补程序稍微大于剪辑路径才能运行。