How to create a cairo_t on a Gtk 2 window

独自空忆成欢 提交于 2019-12-01 07:17:01

问题


I have an old app, now compiling on Gtk 2, but I need to introduce the use of Cairo. I can't figure out how to create the necessary cairo context (cairo_t) from my Widgets.

Here's the code I'm trying to learn with so far, modified (*ahem* cribbed) from a Gtk 3 tutorial. The crux of the matter is creating a cairo surface from the window widget. As it stands, that call is a sketch and it won't compile, let alone run. Remember, my target is Gtk2, not 3, at least at this point.

/* Snitched from http://zetcode.com/gfx/cairo/cairobackends/ on 13 Jan 2014 */
#include <cairo.h>
#include <cairo-xlib.h>
#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *darea;
  cairo_surface_t *surface;
  cairo_t *cr;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  darea = gtk_drawing_area_new();
  gtk_container_add(GTK_CONTAINER(window), darea);

  g_signal_connect(window,          "destroy", G_CALLBACK(gtk_main_quit), NULL);

  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size(GTK_WINDOW(window), 400, 90);
  gtk_window_set_title(GTK_WINDOW(window), "GTK window");

  surface = cairo_xlib_surface_create(
      gtk_widget_get_display(window),   /* must be Display *, not struct GdkDisplay * */
      window,                           /* must be Drawable (no star) */
      gtk_widget_get_visual(window),    /* must be Visual * */
      gtk_widget_get_width(window),     /* int */
      gtk_widget_get_height(window)     /* int */
      );
  cr = cairo_create(surface);
  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, 
     CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Discipline is power.");

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

回答1:


I hope the tutorial did not do cairo drawing in main()... The meaningful place to draw onto a GTK2 widget is in the expose-event (and if you want to force a redraw from somewhere else, just call gtk_widget_queue_draw()). It is easer to use gdk_cairo_create() get a cairo context.

Something like this:

static gboolean
on_expose_event (GtkWidget *widget,
                 GdkEventExpose *event,
                 gpointer data)
{
    cairo_t *cr;

    cr = gdk_cairo_create (gtk_widget_get_window (widget));
    cairo_move_to (cr, 30, 30);
    cairo_show_text (cr, "Text");

    cairo_destroy (cr);

    return FALSE;
}

g_signal_connect(darea, "expose-event",
                 G_CALLBACK(on_expose_event), NULL);

Jan Bodnar has a more complete example (in the end).

This is all a lot nicer in GTK3 in my opinion. Still, even if your goal is to port to GTK3 it may make sense to change the drawing to use cairo first as you're doing -- changing to GTK3 afterwards should just simplify the code.



来源:https://stackoverflow.com/questions/21102622/how-to-create-a-cairo-t-on-a-gtk-2-window

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!