Viewing file: rotated_text.c (4.78 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* Rotated Text * * This demo shows how to use GDK and Pango to draw rotated and transformed * text. The use of GdkPangoRenderer in this example is a somewhat advanced * technique; most applications can simply use gdk_draw_layout(). We use * it here mostly because that allows us to work in user coordinates - that is, * coordinates prior to the application of the transformation matrix, rather * than device coordinates. * * As of GTK+-2.6, the ability to draw transformed and anti-aliased graphics * as shown in this example is only present for text. With GTK+-2.8, a new * graphics system called "Cairo" will be introduced that provides these * capabilities and many more for all types of graphics. */ #include <math.h> #include <gtk/gtk.h>
static GtkWidget *window = NULL;
static gboolean rotated_text_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) { #define RADIUS 150 #define N_WORDS 10 #define FONT "Sans Bold 27" PangoRenderer *renderer; PangoMatrix matrix = PANGO_MATRIX_INIT; PangoContext *context; PangoLayout *layout; PangoFontDescription *desc;
int width = widget->allocation.width; int height = widget->allocation.height; double device_radius; int i;
/* Get the default renderer for the screen, and set it up for drawing */ renderer = gdk_pango_renderer_get_default (gtk_widget_get_screen (widget)); gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer), widget->window); gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer), widget->style->black_gc);
/* Set up a transformation matrix so that the user space coordinates for * the centered square where we draw are [-RADIUS, RADIUS], [-RADIUS, RADIUS] * We first center, then change the scale */ device_radius = MIN (width, height) / 2.; pango_matrix_translate (&matrix, device_radius + (width - 2 * device_radius) / 2, device_radius + (height - 2 * device_radius) / 2); pango_matrix_scale (&matrix, device_radius / RADIUS, device_radius / RADIUS);
/* Create a PangoLayout, set the font and text */ context = gtk_widget_create_pango_context (widget); layout = pango_layout_new (context); pango_layout_set_text (layout, "Text", -1); desc = pango_font_description_from_string (FONT); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc);
/* Draw the layout N_WORDS times in a circle */ for (i = 0; i < N_WORDS; i++) { GdkColor color; PangoMatrix rotated_matrix = matrix; int width, height; double angle = (360. * i) / N_WORDS;
/* Gradient from red at angle == 60 to blue at angle == 300 */ color.red = 65535 * (1 + cos ((angle - 60) * G_PI / 180.)) / 2; color.green = 0; color.blue = 65535 - color.red; gdk_pango_renderer_set_override_color (GDK_PANGO_RENDERER (renderer), PANGO_RENDER_PART_FOREGROUND, &color); pango_matrix_rotate (&rotated_matrix, angle);
pango_context_set_matrix (context, &rotated_matrix); /* Inform Pango to re-layout the text with the new transformation matrix */ pango_layout_context_changed (layout); pango_layout_get_size (layout, &width, &height); pango_renderer_draw_layout (renderer, layout, - width / 2, - RADIUS * PANGO_SCALE); }
/* Clean up default renderer, since it is shared */ gdk_pango_renderer_set_override_color (GDK_PANGO_RENDERER (renderer), PANGO_RENDER_PART_FOREGROUND, NULL); gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer), NULL); gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer), NULL);
/* free the objects we created */ g_object_unref (layout); g_object_unref (context); return FALSE; }
GtkWidget * do_rotated_text (GtkWidget *do_widget) { GtkWidget *drawing_area; if (!window) { const GdkColor white = { 0, 0xffff, 0xffff, 0xffff }; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (do_widget)); gtk_window_set_title (GTK_WINDOW (window), "Rotated Text");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
drawing_area = gtk_drawing_area_new (); gtk_container_add (GTK_CONTAINER (window), drawing_area);
/* This overrides the background color from the theme */ gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &white);
g_signal_connect (drawing_area, "expose-event", G_CALLBACK (rotated_text_expose_event), NULL);
gtk_window_set_default_size (GTK_WINDOW (window), 2 * RADIUS, 2 * RADIUS); }
if (!GTK_WIDGET_VISIBLE (window)) { gtk_widget_show_all (window); } else { gtk_widget_destroy (window); window = NULL; }
return window; }
|