]> git.sur5r.net Git - glabels/blob - src/font-sample.c
Removed non-existent filenames from po/POTFILES.in
[glabels] / src / font-sample.c
1 /*
2  *  font-sample.c
3  *  Copyright (C) 2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <config.h>
22
23 #include "font-sample.h"
24
25 #include "marshal.h"
26 #include "color.h"
27
28
29 /*===========================================*/
30 /* Private macros and constants.             */
31 /*===========================================*/
32
33 #define MARGIN 2
34
35
36 /*===========================================*/
37 /* Private types                             */
38 /*===========================================*/
39
40 struct _glFontSamplePrivate {
41
42         gchar *sample_text;
43
44         gchar *font_family;
45 };
46
47
48 /*===========================================*/
49 /* Private globals                           */
50 /*===========================================*/
51
52
53 /*===========================================*/
54 /* Local function prototypes                 */
55 /*===========================================*/
56
57 static void       gl_font_sample_finalize     (GObject        *object);
58
59 static void       style_set_cb                (GtkWidget      *widget,
60                                                GtkStyle       *previous_style);
61
62 static void       redraw                      (glFontSample   *this);
63
64 static gboolean   expose_event_cb             (GtkWidget      *widget,
65                                                GdkEventExpose *event);
66
67 static void       draw_sample                 (glFontSample   *this,
68                                                cairo_t        *cr);
69
70
71
72 /****************************************************************************/
73 /* Boilerplate Object stuff.                                                */
74 /****************************************************************************/
75 G_DEFINE_TYPE (glFontSample, gl_font_sample, GTK_TYPE_DRAWING_AREA);
76
77
78 /*****************************************************************************/
79 /* Class Init Function.                                                      */
80 /*****************************************************************************/
81 static void
82 gl_font_sample_class_init (glFontSampleClass *class)
83 {
84         GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
85         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
86
87         gl_font_sample_parent_class = g_type_class_peek_parent (class);
88
89         gobject_class->finalize    = gl_font_sample_finalize;
90
91         widget_class->expose_event = expose_event_cb;
92         widget_class->style_set    = style_set_cb;
93 }
94
95
96 /*****************************************************************************/
97 /* Object Instance Init Function.                                            */
98 /*****************************************************************************/
99 static void
100 gl_font_sample_init (glFontSample *this)
101 {
102         GTK_WIDGET_SET_FLAGS (GTK_WIDGET (this), GTK_NO_WINDOW);
103
104         this->priv = g_new0 (glFontSamplePrivate, 1);
105 }
106
107
108 /*****************************************************************************/
109 /* Finalize Method.                                                          */
110 /*****************************************************************************/
111 static void
112 gl_font_sample_finalize (GObject *object)
113 {
114         glFontSample *this = GL_FONT_SAMPLE (object);
115
116         g_return_if_fail (object != NULL);
117         g_return_if_fail (GL_IS_FONT_SAMPLE (object));
118
119         g_free (this->priv->sample_text);
120         g_free (this->priv->font_family);
121         g_free (this->priv);
122
123         G_OBJECT_CLASS (gl_font_sample_parent_class)->finalize (object);
124 }
125
126
127 /*****************************************************************************/
128 /** New Object Generator.                                                    */
129 /*****************************************************************************/
130 GtkWidget *
131 gl_font_sample_new (gint         w,
132                     gint         h,
133                     const gchar *sample_text,
134                     const gchar *font_family)
135 {
136         glFontSample *this;
137
138         this = g_object_new (GL_TYPE_FONT_SAMPLE, NULL);
139
140         this->priv->sample_text = g_strdup (sample_text);
141         this->priv->font_family = g_strdup (font_family);
142
143         gtk_widget_set_size_request (GTK_WIDGET (this), w, h);
144
145         return GTK_WIDGET (this);
146 }
147
148
149 /*--------------------------------------------------------------------------*/
150 /* Style set handler (updates colors when style/theme changes).             */
151 /*--------------------------------------------------------------------------*/
152 static void
153 style_set_cb (GtkWidget        *widget,
154               GtkStyle         *previous_style)
155 {
156         redraw (GL_FONT_SAMPLE (widget));
157 }
158
159
160 /*****************************************************************************/
161 /* Request redraw.                                                           */
162 /*****************************************************************************/
163 static void
164 redraw (glFontSample  *this)
165 {
166         GdkRegion *region;
167
168         if (GTK_WIDGET_REALIZED (GTK_WIDGET (this)))
169         {
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);
174         }
175 }
176
177
178 /*****************************************************************************/
179 /* "Expose event" callback.                                                  */
180 /*****************************************************************************/
181 static gboolean
182 expose_event_cb (GtkWidget      *widget,
183                  GdkEventExpose *event)
184 {
185         cairo_t *cr;
186
187         cr = gdk_cairo_create (widget->window);
188
189         cairo_rectangle (cr,
190                         event->area.x, event->area.y,
191                         event->area.width, event->area.height);
192         cairo_clip (cr);
193
194         cairo_translate (cr, widget->allocation.x, widget->allocation.y);
195
196         draw_sample (GL_FONT_SAMPLE (widget), cr);
197
198         cairo_destroy (cr);
199
200         return FALSE;
201 }
202
203
204 /*****************************************************************************/
205 /* Draw sample.                                                              */
206 /*****************************************************************************/
207 static void
208 draw_sample (glFontSample *this,
209              cairo_t       *cr)
210 {
211         GtkStyle             *style;
212         gdouble               w, h;
213         guint                 fill_color, line_color;
214         PangoLayout          *layout;
215         PangoFontDescription *desc;
216         PangoRectangle        ink_rect, logical_rect;
217         gdouble               layout_x, layout_y, layout_width, layout_height;
218
219
220
221         w = GTK_WIDGET (this)->allocation.width;
222         h = GTK_WIDGET (this)->allocation.height;
223
224
225         style = gtk_widget_get_style (GTK_WIDGET (this));
226         if ( GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (this)) )
227         {
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]);
230         }
231         else
232         {
233                 fill_color = GL_COLOR_NONE;
234                 line_color = gl_color_from_gdk_color (&style->fg[GTK_STATE_INSENSITIVE]);
235         }
236
237
238         cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
239
240         cairo_rectangle( cr, 0, 0, w-1, h-1 );
241
242         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (fill_color));
243         cairo_fill_preserve( cr );
244
245         cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (line_color));
246         cairo_set_line_width (cr, 1.0);
247         cairo_stroke (cr);
248
249
250         cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
251
252
253         layout = pango_cairo_create_layout (cr);
254
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);
260         
261         pango_layout_set_font_description (layout, desc);
262         pango_font_description_free       (desc);
263
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);
269
270         layout_x = (w - layout_width) / 2.0;
271         layout_y = (h - layout_height) / 2.0;
272
273         if (ink_rect.x < logical_rect.x)
274         {
275                 layout_x += logical_rect.x - ink_rect.x;
276         }
277
278         if (ink_rect.y < logical_rect.y)
279         {
280                 layout_y += logical_rect.y - ink_rect.y;
281         }
282
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);
286
287         g_object_unref (layout);
288 }
289
290
291
292 /*
293  * Local Variables:       -- emacs
294  * mode: C                -- emacs
295  * c-basic-offset: 8      -- emacs
296  * tab-width: 8           -- emacs
297  * indent-tabs-mode: nil  -- emacs
298  * End:                   -- emacs
299  */