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)
169 window = gtk_widget_get_window (GTK_WIDGET (this));
173 /* redraw the cairo canvas forcing an expose event */
174 region = gdk_drawable_get_clip_region (window);
175 gdk_window_invalidate_region (window, region, TRUE);
176 gdk_region_destroy (region);
181 /*****************************************************************************/
182 /* "Expose event" callback. */
183 /*****************************************************************************/
185 expose_event_cb (GtkWidget *widget,
186 GdkEventExpose *event)
191 window = gtk_widget_get_window (widget);
193 cr = gdk_cairo_create (window);
196 event->area.x, event->area.y,
197 event->area.width, event->area.height);
200 cairo_translate (cr, widget->allocation.x, widget->allocation.y);
202 draw_sample (GL_FONT_SAMPLE (widget), cr);
210 /*****************************************************************************/
212 /*****************************************************************************/
214 draw_sample (glFontSample *this,
219 guint fill_color, line_color;
221 PangoFontDescription *desc;
222 PangoRectangle ink_rect, logical_rect;
223 gdouble layout_x, layout_y, layout_width, layout_height;
227 w = GTK_WIDGET (this)->allocation.width;
228 h = GTK_WIDGET (this)->allocation.height;
231 style = gtk_widget_get_style (GTK_WIDGET (this));
232 if ( GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (this)) )
234 fill_color = gl_color_from_gdk_color (&style->light[GTK_STATE_NORMAL]);
235 line_color = gl_color_from_gdk_color (&style->fg[GTK_STATE_NORMAL]);
239 fill_color = GL_COLOR_NONE;
240 line_color = gl_color_from_gdk_color (&style->fg[GTK_STATE_INSENSITIVE]);
244 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
246 cairo_rectangle( cr, 0, 0, w-1, h-1 );
248 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (fill_color));
249 cairo_fill_preserve( cr );
251 cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (line_color));
252 cairo_set_line_width (cr, 1.0);
256 cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
259 layout = pango_cairo_create_layout (cr);
261 desc = pango_font_description_new ();
262 pango_font_description_set_family (desc, this->priv->font_family);
263 pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
264 pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);
265 pango_font_description_set_size (desc, 0.6 * h * PANGO_SCALE);
267 pango_layout_set_font_description (layout, desc);
268 pango_font_description_free (desc);
270 pango_layout_set_text (layout, this->priv->sample_text, -1);
271 pango_layout_set_width (layout, -1);
272 pango_layout_get_pixel_extents (layout, &ink_rect, &logical_rect);
273 layout_width = MAX (logical_rect.width, ink_rect.width);
274 layout_height = MAX (logical_rect.height, ink_rect.height);
276 layout_x = (w - layout_width) / 2.0;
277 layout_y = (h - layout_height) / 2.0;
279 if (ink_rect.x < logical_rect.x)
281 layout_x += logical_rect.x - ink_rect.x;
284 if (ink_rect.y < logical_rect.y)
286 layout_y += logical_rect.y - ink_rect.y;
289 cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (line_color));
290 cairo_move_to (cr, layout_x, layout_y);
291 pango_cairo_show_layout (cr, layout);
293 g_object_unref (layout);
299 * Local Variables: -- emacs
301 * c-basic-offset: 8 -- emacs
302 * tab-width: 8 -- emacs
303 * indent-tabs-mode: nil -- emacs