From aced9be8bd883391f7047a17877b4d7e489903d8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 27 Jul 2018 19:26:19 -0400 Subject: [PATCH] Add a font rendering demo This renders a magnified version of the text, to make the effect of various font rendering options more visible. --- demos/gtk-demo/Makefile.am | 1 + demos/gtk-demo/demo.gresource.xml | 4 + demos/gtk-demo/fontrendering.c | 196 ++++++++++++++++++++++++++++++ demos/gtk-demo/fontrendering.ui | 180 +++++++++++++++++++++++++++ 4 files changed, 381 insertions(+) create mode 100644 demos/gtk-demo/fontrendering.c create mode 100644 demos/gtk-demo/fontrendering.ui diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index 64245b4b6e..1fb1640826 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -29,6 +29,7 @@ demos_base = \ filtermodel.c \ fishbowl.c \ foreigndrawing.c \ + fontrendering.c \ gestures.c \ glarea.c \ headerbar.c \ diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index 3fac7342eb..c0f9487fb0 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -159,6 +159,7 @@ flowbox.c foreigndrawing.c font_features.c + fontrendering.c gestures.c glarea.c headerbar.c @@ -243,4 +244,7 @@ modelbutton.ui + + fontrendering.ui + diff --git a/demos/gtk-demo/fontrendering.c b/demos/gtk-demo/fontrendering.c new file mode 100644 index 0000000000..146bcf1c45 --- /dev/null +++ b/demos/gtk-demo/fontrendering.c @@ -0,0 +1,196 @@ +/* Pango/Font rendering + * + * Demonstrates variations in font rendering. + */ + +#include + +static GtkWidget *window = NULL; +static GtkWidget *font_button = NULL; +static GtkWidget *entry = NULL; +static GtkWidget *image = NULL; +static GtkWidget *hinting = NULL; +static GtkWidget *hint_metrics = NULL; +static GtkWidget *up_button = NULL; +static GtkWidget *down_button = NULL; + +static PangoContext *context; + +static int scale = 1; + +static GdkPixbuf *pb; + +static void +on_destroy (gpointer data) +{ + window = NULL; +} + +static void +update_image (void) +{ + const char *text; + PangoFontDescription *desc; + PangoLayout *layout; + PangoRectangle ink, logical; + cairo_surface_t *surface; + cairo_t *cr; + GdkPixbuf *pixbuf; + GdkPixbuf *pixbuf2; + const char *hint; + cairo_font_options_t *fopt; + cairo_hint_style_t hintstyle; + cairo_hint_metrics_t hintmetrics; + + if (!context) + context = gtk_widget_create_pango_context (image); + + text = gtk_entry_get_text (GTK_ENTRY (entry)); + desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button)); + + fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context)); + + hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting)); + if (strcmp (hint, "none") == 0) + hintstyle = CAIRO_HINT_STYLE_NONE; + else if (strcmp (hint, "slight") == 0) + hintstyle = CAIRO_HINT_STYLE_SLIGHT; + else if (strcmp (hint, "medium") == 0) + hintstyle = CAIRO_HINT_STYLE_MEDIUM; + else if (strcmp (hint, "full") == 0) + hintstyle = CAIRO_HINT_STYLE_FULL; + else + hintstyle = CAIRO_HINT_STYLE_DEFAULT; + cairo_font_options_set_hint_style (fopt, hintstyle); + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (hint_metrics))) + hintmetrics = CAIRO_HINT_METRICS_ON; + else + hintmetrics = CAIRO_HINT_METRICS_OFF; + cairo_font_options_set_hint_metrics (fopt, hintmetrics); + + pango_cairo_context_set_font_options (context, fopt); + cairo_font_options_destroy (fopt); + + layout = pango_layout_new (context); + pango_layout_set_text (layout, text, -1); + pango_layout_set_font_description (layout, desc); + pango_layout_get_extents (layout, &ink, &logical); + + pango_extents_to_pixels (&logical, NULL); + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width, logical.height); + cr = cairo_create (surface); + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_paint (cr); + + cairo_set_source_rgb (cr, 0, 0, 0); + pango_cairo_show_layout (cr, layout); + + cairo_destroy (cr); + + pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, logical.width, logical.height); + pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, logical.width * scale, logical.height * scale, GDK_INTERP_NEAREST); + + g_set_object (&pb, pixbuf2); + + gtk_widget_set_size_request (image, gdk_pixbuf_get_width (pb), gdk_pixbuf_get_height (pb)); + + g_object_unref (pixbuf); + g_object_unref (pixbuf2); + + cairo_surface_destroy (surface); + pango_font_description_free (desc); + + +} + +static void +update_buttons (void) +{ + gtk_widget_set_sensitive (up_button, scale < 32); + gtk_widget_set_sensitive (down_button, scale > 1); +} + +static void +scale_up (void) +{ + scale += 1; + update_buttons (); + update_image (); +} + +static void +scale_down (void) +{ + scale -= 1; + update_buttons (); + update_image (); +} + +static gboolean +draw (GtkWidget *widget, cairo_t *cr, gpointer data) +{ + guint width, height; + GtkStyleContext *context; + + context = gtk_widget_get_style_context (widget); + + width = gtk_widget_get_allocated_width (widget); + height = gtk_widget_get_allocated_height (widget); + + gtk_render_background (context, cr, 0, 0, width, height); + + if (pb) + { + gdk_cairo_set_source_pixbuf (cr, pb, 0, 0); + cairo_paint (cr); + } + + return FALSE; +} + +GtkWidget * +do_fontrendering (GtkWidget *do_widget) +{ + if (!window) + { + GtkBuilder *builder; + + builder = gtk_builder_new_from_resource ("/fontrendering/fontrendering.ui"); + gtk_builder_connect_signals (builder, NULL); + window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (do_widget)); + g_signal_connect (window, "destroy", + G_CALLBACK (on_destroy), NULL); + g_object_set_data_full (G_OBJECT (window), "builder", builder, g_object_unref); + font_button = GTK_WIDGET (gtk_builder_get_object (builder, "font_button")); + up_button = GTK_WIDGET (gtk_builder_get_object (builder, "up_button")); + down_button = GTK_WIDGET (gtk_builder_get_object (builder, "down_button")); + entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry")); + image = GTK_WIDGET (gtk_builder_get_object (builder, "image")); + hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting")); + hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics")); + + g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL); + g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL); + g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL); + g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL); + g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL); + g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL); + + g_signal_connect (image, "draw", G_CALLBACK (draw), NULL); + + update_image (); + } + + if (!gtk_widget_get_visible (window)) + gtk_widget_show (window); + else + { + gtk_widget_destroy (window); + } + + return window; +} diff --git a/demos/gtk-demo/fontrendering.ui b/demos/gtk-demo/fontrendering.ui new file mode 100644 index 0000000000..205b2ff01a --- /dev/null +++ b/demos/gtk-demo/fontrendering.ui @@ -0,0 +1,180 @@ + + + + + 0 + 0 + 24 + 1 + 4 + 0 + + + 600 + 300 + Font rendering + + + 1 + 10 + 10 + 10 + + + 1 + 10 + Text + 1 + + + + 0 + 0 + + + + + 1 + Fonts render + + + 1 + 0 + + + + + 1 + 10 + Font + 1 + + + + 0 + 1 + + + + + 1 + + + 1 + 1 + + + + + 1 + Hinting + 1 + + + + 2 + 0 + + + + + 1 + 0 + center + + None + Slight + Medium + Full + + + + 3 + 0 + + + + + 1 + + + 1 + Hint Metrics + + + + + + 3 + 1 + + + + + 1 + + + 1 + list-add-symbolic + + + + + + 4 + 0 + + + + + 1 + + + 1 + list-remove-symbolic + + + + + + 4 + 1 + + + + + 1 + + 1 + + + 6 + 0 + + + + + 1 + automatic + automatic + 1 + 1 + 1 + + + 1 + center + center + + + + + 0 + 3 + 7 + + + + + +