#include #include #include #include #include /* for test program */ #include /* a test of server side rotated text */ #define IROUND(x) (int)((x) > 0 ? (x) + .5 : (x) - .5) void gdk_draw_rotated_text(GdkDrawable *drawable, const gchar *xlfdtemplate, guint points, GdkGC *gc, gint x, gint y, gdouble angle, /* in radians */ const gchar *text, guint text_length) { gdouble matrix[4]; gchar *smatrix, *xlfd; GdkFont *font; XFontStruct *fontinfo; gdouble offset; guint i; g_return_if_fail(drawable != NULL); g_return_if_fail(xlfdtemplate != NULL); g_return_if_fail(gc != NULL); g_return_if_fail(text != NULL); /* build up rotated font XLFD */ matrix[0] = matrix[3] = points * cos(angle); matrix[1] = points * sin(angle); matrix[2] = -matrix[1]; smatrix = g_strdup_printf("[%g %g %g %g]", matrix[0], matrix[1], matrix[2], matrix[3]); for (i = 0; smatrix[i] != '\0'; i++) if (smatrix[i] == '-') smatrix[i] = '~'; xlfd = g_strdup_printf(xlfdtemplate, smatrix); g_free(smatrix); font = gdk_font_load(xlfd); g_free(xlfd); g_return_if_fail(font != NULL); fontinfo = GDK_FONT_XFONT(font); /* draw rotated text */ offset = 0.0; for (i = 0; i < text_length; i++) { int charno = (unsigned char)text[i]; int char_metric_offset = charno - fontinfo->min_char_or_byte2; gdk_draw_text(drawable, font, gc, IROUND((double)x + offset * matrix[0] / 1000.0), IROUND((double)y - offset * matrix[1] / 1000.0), &text[i], 1); offset += (double)(fontinfo->per_char ? fontinfo->per_char[char_metric_offset].attributes : fontinfo->min_bounds.attributes); } } void gdk_draw_rotated_string(GdkDrawable *drawable, const gchar *xlfdtemplate, guint points, GdkGC *gc, gint x, gint y, gdouble angle, /* in radians */ const gchar *string) { gdk_draw_rotated_text(drawable, xlfdtemplate, points, gc, x, y, angle, string, strlen(string)); } static gint expose_event(GtkWidget *drawing_area, GdkEventExpose *event) { GdkDrawable *drw = drawing_area->window; if (!drw) return; gdk_window_clear(drw); gdk_draw_rotated_text(drw, "-*-times-medium-r-normal-*-%s-*-*-*-p-*-iso8859-1", 48, drawing_area->style->text_gc[GTK_WIDGET_STATE(drawing_area)], 50, 40, 0, "Hello World", 11); gdk_draw_rotated_text(drw, "-*-times-medium-r-normal-*-%s-*-*-*-p-*-iso8859-1", 36, drawing_area->style->text_gc[GTK_WIDGET_STATE(drawing_area)], 36, 65, -M_PI/6.0, "Hello World", 11); gdk_draw_rotated_text(drw, "-*-times-medium-r-normal-*-%s-*-*-*-p-*-iso8859-1", 24, drawing_area->style->text_gc[GTK_WIDGET_STATE(drawing_area)], 20, 73, -M_PI/3.0, "Hello World", 11); gdk_draw_rotated_text(drw, "-*-times-medium-r-normal-*-%s-*-*-*-p-*-iso8859-1", 18, drawing_area->style->text_gc[GTK_WIDGET_STATE(drawing_area)], 5, 75, -M_PI/2.0, "Hello World", 11); } gint main(int argc, char **argv) { GtkWidget *window; GtkWidget *da; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_main_quit), NULL); da = gtk_drawing_area_new(); gtk_drawing_area_size(GTK_DRAWING_AREA(da), 300, 200); gtk_signal_connect(GTK_OBJECT(da), "expose_event", GTK_SIGNAL_FUNC(expose_event), NULL); gtk_container_add(GTK_CONTAINER(window), da); gtk_widget_show_all(window); gtk_main(); return 0; }