Draw text on Gtk canvas

I am trying to draw letters of a specific size, color, opacity, and location in a Gtk window. Here is an example of what the output might look like: example.

I am able to draw rectangles with the following code:

function draw_object!(ex, vo)
    c = ex.canvas
    win = ex.window
    w = vo.width
    pos = vo.location
    @guarded draw(c) do widget
        ctx = getgc(c)
        rectangle(ctx, pos..., w, w)
        set_source_rgb(ctx, 252, 3, 3)
        fill(ctx)
    end
    Gtk.showall(c)
    return nothing
end

Even though I went through the documentation and source code, it is not clear how to draw text and modify its properties. Any help would be greatly appreciated.

It’s somehow implict. A GtkCanvas is actually a libcairo surface and with the getgc you can get a Cairo context and use the calls provided by Cairo.jl (https://github.com/JuliaGraphics/Cairo.jl/blob/master/samples/Samples.md).
Note: For single letter drawing (and if you can live with the standard font(s)) it’s recommended to stay with the ‘simple’ interface (-> https://github.com/JuliaGraphics/Cairo.jl/blob/master/samples/sample_text.jl)

2 Likes

Thank you. This was very helpful.

I am still struggling with a few details. First, how do I set the location of the text? The rectangle appears to be based on the top left corner. However, the text location is different. Second, is it possible to set the alphacolor with RBG values instead of colarant?

Here is what I have so far:

using Gtk, Graphics, Cairo, Colors
c = @GtkCanvas()
win = GtkWindow(c, "Canvas",500, 500)
@guarded draw(c) do widget
    ctx = getgc(c)
    h = height(c)
    w = width(c)
    # draw text 
    select_font_face(ctx, "Sans", Cairo.FONT_SLANT_NORMAL,
         Cairo.FONT_WEIGHT_NORMAL);
    set_font_size(ctx, 52.0);
    set_source_rgb(ctx, 0.8,0.8,0.8)
    extents = text_extents(cr, "cairo");
    println(extents[4])
    x = 128.0-(extents[3]/2 + extents[1]);
    y = 128.0-(extents[4]/2 + extents[2]);
    move_to(ctx, x, y);
    show_text(ctx, "cairo");
    #draw red semi-transluecent rectangle
    rectangle(ctx, x-50, y-50, 200, 100)
    set_source(ctx, Cairo.alphacolor(colorant"red",.5))
    fill(ctx)
    restore(ctx)

end
show(c)

Thank you!

1 Like

The simple_text example paints a red dot at the position where the text is placed (10,135). The reference point is actually fontdependent, but you can assume a ‘lower, left corner’ of the textbox. And, yes, coordinates are x->right, y->down (if not rotated). Also in simple_test you can see the use of set_source_rgba(context, RED, GREEN, BLUE, ALPHA).

1 Like

Thanks again for your help.

In case it is useful for future reference, here is a simple example of what I am trying to accomplish

using Gtk, Graphics, Cairo, Colors
c = @GtkCanvas()
win = GtkWindow(c, "Canvas",500, 500)
@guarded draw(c) do widget
    ctx = getgc(c)
    # draw text 
    select_font_face(ctx, "Sans", Cairo.FONT_SLANT_NORMAL,
         Cairo.FONT_WEIGHT_NORMAL);
    set_font_size(ctx, 22.5);
    set_source_rgb(ctx, 0.8,0.8,0.8)
    extents = text_extents(cr, "X");
    x = 128.0-(extents[3]/2 + extents[1]);
    y = 128.0-(extents[4]/2 + extents[2]);
    move_to(ctx, x, y);
    show_text(ctx, "X");
    #draw red semi-transluecent rectangle
    circle(ctx, x + 15/2, y - 15/2, 15)
    set_source_rgba(ctx, 1, 0, 0, .5)
    # set_source(ctx, Cairo.alphacolor(colorant"red",.5))
    fill(ctx)
    restore(ctx)
end
show(c)