gjs cairo 上下文绘图未显示在杂乱的窗口中

Posted

技术标签:

【中文标题】gjs cairo 上下文绘图未显示在杂乱的窗口中【英文标题】:gjs cairo context drawing not displaying in clutter window 【发布时间】:2011-07-06 00:04:06 【问题描述】:

我正在尝试使用 javascript 绑定将简单的 cairo 绘图绘制到杂乱的窗口中。我的问题是,除了一半的函数名称略有不同外,无论我尝试什么,cairo 绘图都不会出现。我使用了 python 中的一个示例,它确实有效,并将其移植到了 javascript。我还使用自省来获取 Clutter 模块实例。我也在使用 gjs 0.7.14 版。谁能告诉我出了什么问题。

下面是我正在使用的示例代码。


const cairo = imports.cairo;
const clutter =  imports.gi.Clutter;

function on_button_press_event (stage, event) 
    clutter.main_quit();


function draw(cairo_tex) 
    var context = cairo_tex.create();


    context.scale(200, 200);
    context.setLineWidth(0.1);
    var colour2 = new clutter.Color();
    colour2.from_string('#dd000088');
    clutter.cairo_set_source_color(context, colour2);
    context.translate(0.5, 0.5);
    context.arc(0, 0, 0.4, 0, Math.PI * 2);
    context.stroke();


function main () 
    clutter.init(0, null);
    var stage = new clutter.Stage();
    var colour = new clutter.Color();
    colour.from_string("#ffccccff");
    stage.set_color(colour);
    stage.set_size(400, 300);
    stage.connect('button-press-event',  on_button_press_event);
    stage.connect('destroy', clutter.main_quit);

    var cairo_tex = new clutter.CairoTexture.new(200, 200);
    cairo_tex.set_position((stage.get_width() - 200) / 2,
                       (stage.get_height() - 200) / 2);

    draw(cairo_tex);


    var center_x = cairo_tex.get_width() / 2;
    var center_z = cairo_tex.get_height() / 2;
    cairo_tex.set_rotation(clutter.AlignAxis.Y_AXIS, 45.0, center_x, 0, center_z);
    stage.add_actor(cairo_tex);
    cairo_tex.show();

    stage.show();

    clutter.main();


main();

我认为这不起作用的原因与删除 javascript 中的 cairo 上下文有关。 context.destroy 不存在,使用 delete 也不存在。事实上,如果我使用删除,那么我会收到警告

WARNING: 'applying the 'delete' operator to an unqualified name is deprecated'

这根本没有帮助。根据一些参与 gjs 的开发人员发布的有关它的信息,分配给 null 应该具有相同的效果,因为它被垃圾收集。我怀疑幕后是否有什么可以收集的。

如果有人能说这是真的还是假的,那么我会接受这个作为答案。

更新:

我已将问题范围缩小到 imports.gi.Clutter。我尝试了另一个示例,但这次使用 Gtk 而不是 Clutter,并且下面的代码确实有效

cairo = imports.cairo;
Gtk = imports.gi.Gtk;
Gdk = imports.gi.Gdk;

function draw_arc(drawing_area)
    var cr = Gdk.cairo_create(drawing_area.get_window());

    cr.scale(2, 2);

    cr.operator = cairo.Operator.CLEAR;
    cr.paint();
    cr.operator = cairo.Operator.OVER;

    cr.setSourceRGB(0,255,0);
    cr.arc(128, 128, 76.8, 0, 2*Math.PI);
    cr.fill();

    return false;


Gtk.init(0, null);

var w = new Gtk.Window();
w.connect('delete-event', Gtk.main_quit);

var d = new Gtk.DrawingArea();
w.add(d);

w.resize(500,600);
w.decorated = false;

d.connect('draw', draw_arc);

w.show_all();
Gtk.main();

这让我相信问题不在于 cairo 的 gjs 实现,而在于 Clutter Cairo 实现的 gjs 自省方法。我认为 clutter.CairoTexture.new 或 clutter.CairoTexture.create 没有正确实现。我怀疑是造成问题的 clutter.CairoTexture.create。

【问题讨论】:

我还应该提到库的库版本是混乱的 1.6.16 cairo 1.10.2-r1 ClutterTexture 已被弃用。 ClutterImage 是替代品,尽管对于 Cairo 集成,您可能需要考虑 ClutterCanvas 你是否让它在 GJS 中像在 Gnome-shell-extensions 中一样工作?如果是这样,您能否将其作为答案,因为我很想关闭这个? 我对此很陌生,但我有一些东西要出现。给我几天时间,我会找到一些时间来发布这个问题的答案。 那太棒了 【参考方案1】:

使用 Clutter 和 Cairo 之间的新集成,特别是 Clutter.Canvas,这将在屏幕上绘制一个圆圈:

const Clutter = imports.gi.Clutter;
const Cairo = imports.cairo;

const draw_stuff = function (canvas, cr, width, height) 
    cr.save ();
    cr.setOperator (Cairo.Operator.CLEAR);
    cr.paint ();
    cr.restore ();
    cr.setOperator (Cairo.Operator.OVER);
    cr.scale (width, height);
    cr.setLineCap (Cairo.LineCap.ROUND);
    cr.setLineWidth (0.1);

    cr.translate (0.5, 0.5);
    cr.arc (0, 0, 0.4, 0, Math.PI * 2);
    cr.stroke ();

    return true;
;

const test = function () 
    Clutter.init(null);

    let stage = new Clutter.Stage();
    stage.set_title ("Circle!");

    let color = new Clutter.Color(
        red : 255,
        green : 0,
        blue : 0,
        alpha : 128 // Just for the heck of it.
);
stage.set_background_color(color);
stage.set_size(300, 300);

let canvas = new Clutter.Canvas ();
canvas.set_size (155, 155);

let dummy = new Clutter.Actor ();
dummy.set_content (canvas);
dummy.set_size(155, 155);
stage.add_child (dummy);

stage.connect ("destroy", Clutter.main_quit);
canvas.connect ("draw", draw_stuff);
canvas.invalidate ();
stage.show_all();

Clutter.main ();
;

test ();

【讨论】:

谢谢你,虽然我之前没有得到关于它为什么失败的答案,我也不希望你知道,它至少现在可以工作了。我已经等了一年多的东西,事件只是骨头。我觉得我可以关闭它,我已经关闭了。

以上是关于gjs cairo 上下文绘图未显示在杂乱的窗口中的主要内容,如果未能解决你的问题,请参考以下文章

Gtk+:如何从 Cairo 上下文中设置窗口的光标?

让 Cairo 图形与 MFC 一起工作的小例子?

如何转置 cairo 上下文或更改轴的方向?

重新粉刷开罗的窗户?

如何在 Opengl windows 上加速使用 Cairo 绘图?

有时在绘图期间设备上下文大小会减小