Drawing Area, Rotated Text (Gtk3-demo) examples added.
This commit is contained in:
parent
a22dcfc186
commit
2ab018f7dd
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
/usr/lib/colorgcc/bin/gcc `pkg-config --cflags gtk+-3.0` main.c `pkg-config --libs gtk+-3.0` || exit -1
|
||||||
|
./a.out
|
|
@ -0,0 +1,294 @@
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
/* Pixmap for scribble area, to store current scribbles */
|
||||||
|
static cairo_surface_t *surface = NULL;
|
||||||
|
|
||||||
|
/* Create a new surface of the appropriate size to store our scribbles */
|
||||||
|
static gboolean
|
||||||
|
scribble_configure_event (GtkWidget *widget,
|
||||||
|
GdkEventConfigure *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkAllocation allocation;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
if (surface)
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
|
surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
|
||||||
|
CAIRO_CONTENT_COLOR,
|
||||||
|
allocation.width,
|
||||||
|
allocation.height);
|
||||||
|
|
||||||
|
/* Initialize the surface to white */
|
||||||
|
cr = cairo_create (surface);
|
||||||
|
|
||||||
|
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||||
|
cairo_paint (cr);
|
||||||
|
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
/* We've handled the configure event, no need for further processing. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Redraw the screen from the surface */
|
||||||
|
static gboolean
|
||||||
|
scribble_draw (GtkWidget *widget,
|
||||||
|
cairo_t *cr,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
cairo_set_source_surface (cr, surface, 0, 0);
|
||||||
|
cairo_paint (cr);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw a rectangle on the screen */
|
||||||
|
static void
|
||||||
|
draw_brush (GtkWidget *widget,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y)
|
||||||
|
{
|
||||||
|
GdkRectangle update_rect;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
update_rect.x = x - 3;
|
||||||
|
update_rect.y = y - 3;
|
||||||
|
update_rect.width = 6;
|
||||||
|
update_rect.height = 6;
|
||||||
|
|
||||||
|
/* Paint to the surface, where we store our state */
|
||||||
|
cr = cairo_create (surface);
|
||||||
|
|
||||||
|
gdk_cairo_rectangle (cr, &update_rect);
|
||||||
|
cairo_fill (cr);
|
||||||
|
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
/* Now invalidate the affected region of the drawing area. */
|
||||||
|
gdk_window_invalidate_rect (gtk_widget_get_window (widget),
|
||||||
|
&update_rect,
|
||||||
|
FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
scribble_button_press_event (GtkWidget *widget,
|
||||||
|
GdkEventButton *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (surface == NULL)
|
||||||
|
return FALSE; /* paranoia check, in case we haven't gotten a configure event */
|
||||||
|
|
||||||
|
if (event->button == GDK_BUTTON_PRIMARY)
|
||||||
|
draw_brush (widget, event->x, event->y);
|
||||||
|
|
||||||
|
/* We've handled the event, stop processing */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
scribble_motion_notify_event (GtkWidget *widget,
|
||||||
|
GdkEventMotion *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
GdkModifierType state;
|
||||||
|
|
||||||
|
if (surface == NULL)
|
||||||
|
return FALSE; /* paranoia check, in case we haven't gotten a configure event */
|
||||||
|
|
||||||
|
/* This call is very important; it requests the next motion event.
|
||||||
|
* If you don't call gdk_window_get_pointer() you'll only get
|
||||||
|
* a single motion event. The reason is that we specified
|
||||||
|
* GDK_POINTER_MOTION_HINT_MASK to gtk_widget_set_events().
|
||||||
|
* If we hadn't specified that, we could just use event->x, event->y
|
||||||
|
* as the pointer location. But we'd also get deluged in events.
|
||||||
|
* By requesting the next event as we handle the current one,
|
||||||
|
* we avoid getting a huge number of events faster than we
|
||||||
|
* can cope.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gdk_window_get_device_position (event->window, event->device, &x, &y, &state);
|
||||||
|
|
||||||
|
if (state & GDK_BUTTON1_MASK)
|
||||||
|
draw_brush (widget, x, y);
|
||||||
|
|
||||||
|
/* We've handled it, stop processing */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
checkerboard_draw (GtkWidget *da,
|
||||||
|
cairo_t *cr,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
gint i, j, xcount, ycount, width, height;
|
||||||
|
|
||||||
|
#define CHECK_SIZE 10
|
||||||
|
#define SPACING 2
|
||||||
|
|
||||||
|
/* At the start of a draw handler, a clip region has been set on
|
||||||
|
* the Cairo context, and the contents have been cleared to the
|
||||||
|
* widget's background color. The docs for
|
||||||
|
* gdk_window_begin_paint_region() give more details on how this
|
||||||
|
* works.
|
||||||
|
*/
|
||||||
|
|
||||||
|
xcount = 0;
|
||||||
|
width = gtk_widget_get_allocated_width (da);
|
||||||
|
height = gtk_widget_get_allocated_height (da);
|
||||||
|
i = SPACING;
|
||||||
|
while (i < width)
|
||||||
|
{
|
||||||
|
j = SPACING;
|
||||||
|
ycount = xcount % 2; /* start with even/odd depending on row */
|
||||||
|
while (j < height)
|
||||||
|
{
|
||||||
|
if (ycount % 2)
|
||||||
|
cairo_set_source_rgb (cr, 0.45777, 0, 0.45777);
|
||||||
|
else
|
||||||
|
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||||
|
|
||||||
|
/* If we're outside the clip, this will do nothing.
|
||||||
|
*/
|
||||||
|
cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE);
|
||||||
|
cairo_fill (cr);
|
||||||
|
|
||||||
|
j += CHECK_SIZE + SPACING;
|
||||||
|
++ycount;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += CHECK_SIZE + SPACING;
|
||||||
|
++xcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return TRUE because we've handled this event, so no
|
||||||
|
* further processing is required.
|
||||||
|
*/
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
close_window (void)
|
||||||
|
{
|
||||||
|
window = NULL;
|
||||||
|
|
||||||
|
if (surface)
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
|
surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_drawingarea (GtkWidget *do_widget)
|
||||||
|
{
|
||||||
|
GtkWidget *frame;
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *da;
|
||||||
|
GtkWidget *label;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
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), "Drawing Area");
|
||||||
|
|
||||||
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (close_window), NULL);
|
||||||
|
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
|
||||||
|
|
||||||
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the checkerboard area
|
||||||
|
*/
|
||||||
|
|
||||||
|
label = gtk_label_new (NULL);
|
||||||
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
|
"<u>Checkerboard pattern</u>");
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
da = gtk_drawing_area_new ();
|
||||||
|
/* set a minimum size */
|
||||||
|
gtk_widget_set_size_request (da, 100, 100);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), da);
|
||||||
|
|
||||||
|
g_signal_connect (da, "draw",
|
||||||
|
G_CALLBACK (checkerboard_draw), NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the scribble area
|
||||||
|
*/
|
||||||
|
|
||||||
|
label = gtk_label_new (NULL);
|
||||||
|
gtk_label_set_markup (GTK_LABEL (label),
|
||||||
|
"<u>Scribble area</u>");
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
da = gtk_drawing_area_new ();
|
||||||
|
/* set a minimum size */
|
||||||
|
gtk_widget_set_size_request (da, 100, 100);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), da);
|
||||||
|
|
||||||
|
/* Signals used to handle backing surface */
|
||||||
|
|
||||||
|
g_signal_connect (da, "draw",
|
||||||
|
G_CALLBACK (scribble_draw), NULL);
|
||||||
|
g_signal_connect (da,"configure-event",
|
||||||
|
G_CALLBACK (scribble_configure_event), NULL);
|
||||||
|
|
||||||
|
/* Event signals */
|
||||||
|
|
||||||
|
g_signal_connect (da, "motion-notify-event",
|
||||||
|
G_CALLBACK (scribble_motion_notify_event), NULL);
|
||||||
|
g_signal_connect (da, "button-press-event",
|
||||||
|
G_CALLBACK (scribble_button_press_event), NULL);
|
||||||
|
|
||||||
|
|
||||||
|
/* Ask to receive events the drawing area doesn't normally
|
||||||
|
* subscribe to
|
||||||
|
*/
|
||||||
|
gtk_widget_set_events (da, gtk_widget_get_events (da)
|
||||||
|
| GDK_LEAVE_NOTIFY_MASK
|
||||||
|
| GDK_BUTTON_PRESS_MASK
|
||||||
|
| GDK_POINTER_MOTION_MASK
|
||||||
|
| GDK_POINTER_MOTION_HINT_MASK);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (window))
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
else
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
GtkWidget *window;
|
||||||
|
|
||||||
|
gtk_init(&argc, &argv);
|
||||||
|
window = do_drawingarea(NULL);
|
||||||
|
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||||
|
gtk_main();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
/usr/lib/colorgcc/bin/gcc `pkg-config --cflags gtk+-3.0` main.c `pkg-config --libs gtk+-3.0` || exit -1
|
||||||
|
./a.out
|
|
@ -0,0 +1,229 @@
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define HEART "♥"
|
||||||
|
const char text[] = "I ♥ GTK+";
|
||||||
|
|
||||||
|
static void
|
||||||
|
fancy_shape_renderer (cairo_t *cr,
|
||||||
|
PangoAttrShape *attr,
|
||||||
|
gboolean do_path,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
double x, y;
|
||||||
|
cairo_get_current_point (cr, &x, &y);
|
||||||
|
cairo_translate (cr, x, y);
|
||||||
|
|
||||||
|
cairo_scale (cr,
|
||||||
|
(double) attr->ink_rect.width / PANGO_SCALE,
|
||||||
|
(double) attr->ink_rect.height / PANGO_SCALE);
|
||||||
|
|
||||||
|
switch (GPOINTER_TO_UINT (attr->data))
|
||||||
|
{
|
||||||
|
case 0x2665: /* U+2665 BLACK HEART SUIT */
|
||||||
|
{
|
||||||
|
cairo_move_to (cr, .5, .0);
|
||||||
|
cairo_line_to (cr, .9, -.4);
|
||||||
|
cairo_curve_to (cr, 1.1, -.8, .5, -.9, .5, -.5);
|
||||||
|
cairo_curve_to (cr, .5, -.9, -.1, -.8, .1, -.4);
|
||||||
|
cairo_close_path (cr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!do_path) {
|
||||||
|
cairo_set_source_rgb (cr, 1., 0., 0.);
|
||||||
|
cairo_fill (cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PangoAttrList *
|
||||||
|
create_fancy_attr_list_for_layout (PangoLayout *layout)
|
||||||
|
{
|
||||||
|
PangoAttrList *attrs;
|
||||||
|
PangoFontMetrics *metrics;
|
||||||
|
int ascent;
|
||||||
|
PangoRectangle ink_rect, logical_rect;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
/* Get font metrics and prepare fancy shape size */
|
||||||
|
metrics = pango_context_get_metrics (pango_layout_get_context (layout),
|
||||||
|
pango_layout_get_font_description (layout),
|
||||||
|
NULL);
|
||||||
|
ascent = pango_font_metrics_get_ascent (metrics);
|
||||||
|
logical_rect.x = 0;
|
||||||
|
logical_rect.width = ascent;
|
||||||
|
logical_rect.y = -ascent;
|
||||||
|
logical_rect.height = ascent;
|
||||||
|
ink_rect = logical_rect;
|
||||||
|
pango_font_metrics_unref (metrics);
|
||||||
|
|
||||||
|
/* Set fancy shape attributes for all hearts */
|
||||||
|
attrs = pango_attr_list_new ();
|
||||||
|
for (p = text; (p = strstr (p, HEART)); p += strlen (HEART))
|
||||||
|
{
|
||||||
|
PangoAttribute *attr;
|
||||||
|
|
||||||
|
attr = pango_attr_shape_new_with_data (&ink_rect,
|
||||||
|
&logical_rect,
|
||||||
|
GUINT_TO_POINTER (g_utf8_get_char (p)),
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
attr->start_index = p - text;
|
||||||
|
attr->end_index = attr->start_index + strlen (HEART);
|
||||||
|
|
||||||
|
pango_attr_list_insert (attrs, attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
rotated_text_draw (GtkWidget *widget,
|
||||||
|
cairo_t *cr,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
#define RADIUS 150
|
||||||
|
#define N_WORDS 5
|
||||||
|
#define FONT "Serif 18"
|
||||||
|
|
||||||
|
PangoContext *context;
|
||||||
|
PangoLayout *layout;
|
||||||
|
PangoFontDescription *desc;
|
||||||
|
|
||||||
|
cairo_pattern_t *pattern;
|
||||||
|
|
||||||
|
PangoAttrList *attrs;
|
||||||
|
|
||||||
|
double device_radius;
|
||||||
|
int width, height;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Create a cairo context and 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. */
|
||||||
|
width = gtk_widget_get_allocated_width (widget);
|
||||||
|
height = gtk_widget_get_allocated_height (widget);
|
||||||
|
device_radius = MIN (width, height) / 2.;
|
||||||
|
cairo_translate (cr,
|
||||||
|
device_radius + (width - 2 * device_radius) / 2,
|
||||||
|
device_radius + (height - 2 * device_radius) / 2);
|
||||||
|
cairo_scale (cr, device_radius / RADIUS, device_radius / RADIUS);
|
||||||
|
|
||||||
|
/* Create and a subtle gradient source and use it. */
|
||||||
|
pattern = cairo_pattern_create_linear (-RADIUS, -RADIUS, RADIUS, RADIUS);
|
||||||
|
cairo_pattern_add_color_stop_rgb (pattern, 0., .5, .0, .0);
|
||||||
|
cairo_pattern_add_color_stop_rgb (pattern, 1., .0, .0, .5);
|
||||||
|
cairo_set_source (cr, pattern);
|
||||||
|
|
||||||
|
/* Create a PangoContext and set up our shape renderer */
|
||||||
|
context = gtk_widget_create_pango_context (widget);
|
||||||
|
pango_cairo_context_set_shape_renderer (context,
|
||||||
|
fancy_shape_renderer,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
/* Create a PangoLayout, set the text, font, and attributes */
|
||||||
|
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);
|
||||||
|
|
||||||
|
attrs = create_fancy_attr_list_for_layout (layout);
|
||||||
|
pango_layout_set_attributes (layout, attrs);
|
||||||
|
pango_attr_list_unref (attrs);
|
||||||
|
|
||||||
|
/* Draw the layout N_WORDS times in a circle */
|
||||||
|
for (i = 0; i < N_WORDS; i++)
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
/* Inform Pango to re-layout the text with the new transformation matrix */
|
||||||
|
pango_cairo_update_layout (cr, layout);
|
||||||
|
|
||||||
|
pango_layout_get_pixel_size (layout, &width, &height);
|
||||||
|
cairo_move_to (cr, - width / 2, - RADIUS * .9);
|
||||||
|
pango_cairo_show_layout (cr, layout);
|
||||||
|
|
||||||
|
/* Rotate for the next turn */
|
||||||
|
cairo_rotate (cr, G_PI*2 / N_WORDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free the objects we created */
|
||||||
|
pango_font_description_free (desc);
|
||||||
|
g_object_unref (layout);
|
||||||
|
g_object_unref (context);
|
||||||
|
cairo_pattern_destroy (pattern);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_rotated_text (GtkWidget *do_widget)
|
||||||
|
{
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
GtkWidget *box;
|
||||||
|
GtkWidget *drawing_area;
|
||||||
|
GtkWidget *label;
|
||||||
|
PangoLayout *layout;
|
||||||
|
PangoAttrList *attrs;
|
||||||
|
|
||||||
|
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");
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW (window), 4 * RADIUS, 2 * RADIUS);
|
||||||
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
|
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), box);
|
||||||
|
|
||||||
|
/* Add a drawing area */
|
||||||
|
drawing_area = gtk_drawing_area_new ();
|
||||||
|
gtk_container_add (GTK_CONTAINER (box), drawing_area);
|
||||||
|
gtk_style_context_add_class (gtk_widget_get_style_context (drawing_area),
|
||||||
|
GTK_STYLE_CLASS_VIEW);
|
||||||
|
|
||||||
|
g_signal_connect (drawing_area, "draw",
|
||||||
|
G_CALLBACK (rotated_text_draw), NULL);
|
||||||
|
|
||||||
|
/* And a label */
|
||||||
|
label = gtk_label_new (text);
|
||||||
|
gtk_container_add (GTK_CONTAINER (box), label);
|
||||||
|
|
||||||
|
gtk_label_set_angle (GTK_LABEL (label), 45);
|
||||||
|
|
||||||
|
/* Set up fancy stuff on the label */
|
||||||
|
layout = gtk_label_get_layout (GTK_LABEL (label));
|
||||||
|
pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout),
|
||||||
|
fancy_shape_renderer,
|
||||||
|
NULL, NULL);
|
||||||
|
attrs = create_fancy_attr_list_for_layout (layout);
|
||||||
|
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||||
|
pango_attr_list_unref (attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (window))
|
||||||
|
gtk_widget_show_all (window);
|
||||||
|
else
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
GtkWidget *window;
|
||||||
|
|
||||||
|
gtk_init(&argc, &argv);
|
||||||
|
window = do_rotated_text(NULL);
|
||||||
|
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||||
|
gtk_main();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue