3 * Copyright (C) 2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
23 #include "font-sample.h"
29 /*===========================================*/
30 /* Private macros and constants. */
31 /*===========================================*/
36 /*===========================================*/
38 /*===========================================*/
40 struct _glFontSamplePrivate {
48 /*===========================================*/
50 /*===========================================*/
53 /*===========================================*/
54 /* Local function prototypes */
55 /*===========================================*/
57 static void gl_font_sample_finalize (GObject *object);
59 static void style_set_cb (GtkWidget *widget,
60 GtkStyle *previous_style);
62 static void redraw (glFontSample *this);
64 static gboolean expose_event_cb (GtkWidget *widget,
65 GdkEventExpose *event);
67 static void draw_sample (glFontSample *this,
72 /****************************************************************************/
73 /* Boilerplate Object stuff. */
74 /****************************************************************************/
75 G_DEFINE_TYPE (glFontSample, gl_font_sample, GTK_TYPE_DRAWING_AREA);
78 /*****************************************************************************/
79 /* Class Init Function. */
80 /*****************************************************************************/
82 gl_font_sample_class_init (glFontSampleClass *class)
84 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
85 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
87 gl_font_sample_parent_class = g_type_class_peek_parent (class);
89 gobject_class->finalize = gl_font_sample_finalize;
91 widget_class->expose_event = expose_event_cb;
92 widget_class->style_set = style_set_cb;
96 /*****************************************************************************/
97 /* Object Instance Init Function. */
98 /*****************************************************************************/
100 gl_font_sample_init (glFontSample *this)
102 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (this), GTK_NO_WINDOW);
104 this->priv = g_new0 (glFontSamplePrivate, 1);
108 /*****************************************************************************/
109 /* Finalize Method. */
110 /*****************************************************************************/
112 gl_font_sample_finalize (GObject *object)
114 glFontSample *this = GL_FONT_SAMPLE (object);
116 g_return_if_fail (object != NULL);
117 g_return_if_fail (GL_IS_FONT_SAMPLE (object));
119 g_free (this->priv->sample_text);
120 g_free (this->priv->font_family);
123 G_OBJECT_CLASS (gl_font_sample_parent_class)->finalize (object);
127 /*****************************************************************************/
128 /** New Object Generator. */
129 /*****************************************************************************/
131 gl_font_sample_new (gint w,
133 const gchar *sample_text,
134 const gchar *font_family)
138 this = g_object_new (GL_TYPE_FONT_SAMPLE, NULL);
140 this->priv->sample_text = g_strdup (sample_text);
141 this->priv->font_family = g_strdup (font_family);
143 gtk_widget_set_size_request (GTK_WIDGET (this), w, h);
145 return GTK_WIDGET (this);
149 /*--------------------------------------------------------------------------*/
150 /* Style set handler (updates colors when style/theme changes). */
151 /*--------------------------------------------------------------------------*/
153 style_set_cb (GtkWidget *widget,
154 GtkStyle *previous_style)
156 redraw (GL_FONT_SAMPLE (widget));
160 /*****************************************************************************/
161 /* Request redraw. */
162 /*****************************************************************************/
164 redraw (glFontSample *this)
168 if (GTK_WIDGET_REALIZED (GTK_WIDGET (this)))
170 /* redraw the cairo canvas forcing an expose event */
171 region = gdk_drawable_get_clip_region (GTK_WIDGET (this)->window);
172 gdk_window_invalidate_region (GTK_WIDGET (this)->window, region, TRUE);
173 gdk_region_destroy (region);
178 /*****************************************************************************/
179 /* "Expose event" callback. */
180 /*****************************************************************************/
182 expose_event_cb (GtkWidget *widget,
183 GdkEventExpose *event)
187 cr = gdk_cairo_create (widget->window);
190 event->area.x, event->area.y,
191 event->area.width, event->area.height);
194 cairo_translate (cr, widget->allocation.x, widget->allocation.y);
196 draw_sample (GL_FONT_SAMPLE (widget), cr);
204 /*****************************************************************************/
206 /*****************************************************************************/
208 draw_sample (glFontSample *this,
213 guint fill_color, line_color;
215 PangoFontDescription *desc;
216 PangoRectangle ink_rect, logical_rect;
217 gdouble layout_x, layout_y, layout_width, layout_height;
221 w = GTK_WIDGET (this)->allocation.width;
222 h = GTK_WIDGET (this)->allocation.height;
225 style = gtk_widget_get_style (GTK_WIDGET (this));
226 if ( GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (this)) )
228 fill_color = gl_color_from_gdk_color (&style->light[GTK_STATE_NORMAL]);
229 line_color = gl_color_from_gdk_color (&style->fg[GTK_STATE_NORMAL]);
233 fill_color = GL_COLOR_NONE;
234 line_color = gl_color_from_gdk_color (&style->fg[GTK_STATE_INSENSITIVE]);
238 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
240 cairo_rectangle( cr, 0, 0, w-1, h-1 );
242 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (fill_color));
243 cairo_fill_preserve( cr );
245 cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (line_color));
246 cairo_set_line_width (cr, 1.0);
250 cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
253 layout = pango_cairo_create_layout (cr);
255 desc = pango_font_description_new ();
256 pango_font_description_set_family (desc, this->priv->font_family);
257 pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
258 pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);
259 pango_font_description_set_size (desc, 0.6 * h * PANGO_SCALE);
261 pango_layout_set_font_description (layout, desc);
262 pango_font_description_free (desc);
264 pango_layout_set_text (layout, this->priv->sample_text, -1);
265 pango_layout_set_width (layout, -1);
266 pango_layout_get_pixel_extents (layout, &ink_rect, &logical_rect);
267 layout_width = MAX (logical_rect.width, ink_rect.width);
268 layout_height = MAX (logical_rect.height, ink_rect.height);
270 layout_x = (w - layout_width) / 2.0;
271 layout_y = (h - layout_height) / 2.0;
273 if (ink_rect.x < logical_rect.x)
275 layout_x += logical_rect.x - ink_rect.x;
278 if (ink_rect.y < logical_rect.y)
280 layout_y += logical_rect.y - ink_rect.y;
283 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (line_color));
284 cairo_move_to (cr, layout_x, layout_y);
285 pango_cairo_show_layout (cr, layout);
287 g_object_unref (layout);
293 * Local Variables: -- emacs
295 * c-basic-offset: 8 -- emacs
296 * tab-width: 8 -- emacs
297 * indent-tabs-mode: nil -- emacs