【问题标题】:Why does Cairo.set_source_rgb paint the whole canvas?为什么 Cairo.set_source_rgb 绘制整个画布?
【发布时间】:2013-04-15 03:53:13
【问题描述】:

我正在玩 Clutter/cairo,我正在尝试绘制一个矩形;但是,set_source_rgb 似乎会自动使用其源绘制整个画布,无论我是否告诉它绘制一个矩形(也就是说,即使我删除了 ctx.rectangle()ctx.fill() 线,矩形仍然被绘制)。为什么是这样?我需要做什么才能让矩形而不是 set_source_rgb 进行绘画?

public class AnActor : Clutter.Actor {

    public Clutter.Canvas canvas;

    public AnActor() {
        canvas = new Clutter.Canvas();
        canvas.set_size(300,300);

        this.set_content( canvas );
        this.set_size(300,300);

        //Connect to the draw signal.
        canvas.draw.connect(drawme);
    }

    private bool drawme( Cairo.Context ctx, int w, int h) {
        stdout.printf("Just to test this ran at all: %d\n", w);

        ctx.scale(w,h);
        ctx.set_source_rgb(0,0,0);

        //Why is this rectangle drawn even when I remove these lines?
        ctx.rectangle(0,0,200,200);
        ctx.fill();

        ctx.paint();

        return true;
    }
}



int main(string [] args) {
    // Start clutter.
    var result = Clutter.init(ref args);
    if (result != Clutter.InitError.SUCCESS) {
        stderr.printf("Error: %s\n", result.to_string());
        return 1;
    }

    var stage = Clutter.Stage.get_default();
    stage.destroy.connect(Clutter.main_quit);

    //Make my custom Actor:
    var a = new AnActor();
    stage.add_child(a);
    a.canvas.invalidate();

    stage.show_all();

    Clutter.main();
    return 0;
}

【问题讨论】:

    标签: cairo vala clutter


    【解决方案1】:

    在我看来,drawme方法其实有几个误区:

    ctx.scale(w,h);
    

    从您稍后所做的判断,您似乎认为这意味着您想要缩放您正在做的事情,以便您可以绘制 0,0 到 300,300 之间的内容。你实际上在做的是在另一个方向……如果你把这条线留在这里,你需要在 0,0 和 1,1 之间绘制。

    ctx.rectangle(0,0,200,200);
    ctx.fill();
    

    在这里,您需要一个从原点到 200 * 画布宽度和高度的矩形。如果您将其更改为ctx.rectangle (0, 0, 0.67, 0.67),结果应该更接近您想要的结果。或者,正如我之前提到的,您可以摆脱 ctx.scale(w,h); 调用。

    ctx.paint();
    

    查看cairo_paint 的文档:“在当前剪辑区域内随处绘制当前源的绘图运算符。”你想要的是填充当前的path,这就是cairo_fill 所做的。由于您尚未定义剪辑区域,因此整个上下文都会被填充。

    或者,您可以使用cairo_clip 创建一个剪辑区域;只需在ctx.paint (); 之前添加一个ctx.clip ();。您可能需要使用 cairo_save 和 cairo_restore——cairo_clip 的文档对此进行了说明。

    【讨论】:

    • 这解决了它。谢谢!我删除了对paint()scale() 的调用。
    猜你喜欢
    • 2018-04-26
    • 2013-08-25
    • 1970-01-01
    • 2018-10-20
    • 2021-03-02
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    相关资源
    最近更新 更多