source: trunk/third/libgnomeprintui/libgnomeprintui/gnome-font-dialog.c @ 20964

Revision 20964, 25.3 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20963, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 *  gnome-font-dialog.c: A font selector dialog
4 *
5 *  This program is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Library General Public License
7 *  as published by the Free Software Foundation; either version 2 of
8 *  the License, or (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU Library General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Library General Public
16 *  License along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *  Authors:
20 *    Chris Lahey <clahey@ximian.com>
21 *    Lauris Kaplinski <lauris@ximian.com>
22 *
23 *  Copyright (C) 2000-2002 Ximian Inc.
24 *
25 */
26
27#include <config.h>
28
29#include <string.h>
30#include <stdlib.h>
31#include <atk/atk.h>
32#include <gtk/gtk.h>
33#include <libgnomeprint/gnome-pgl.h>
34
35#include "gnome-print-i18n.h"
36#include "gnome-font-dialog.h"
37#include "gnome-printui-marshal.h"
38
39struct _GnomeFontSelection
40{
41        GtkHBox hbox;
42 
43        GtkWidget * family;
44
45        GtkWidget * fontbox;
46
47        GtkWidget * stylebox;
48        GtkWidget * style;
49
50        GtkWidget * sizebox;
51        GtkWidget * size;
52
53        GtkWidget * previewframe;
54
55        guchar *selectedfamily;
56        GnomeFontFace *selectedface;
57        GnomeFont *selectedfont;
58        gdouble selectedsize;
59};
60
61
62struct _GnomeFontSelectionClass
63{
64        GtkHBoxClass parent_class;
65
66        void (* font_set) (GnomeFontSelection * fontsel, GnomeFont * font);
67};
68
69enum {FONT_SET, LAST_SIGNAL};
70
71/* This is the initial and maximum height of the preview entry (it expands
72   when large font sizes are selected). Initial height is also the minimum. */
73#define MIN_PREVIEW_HEIGHT 44
74#define MAX_PREVIEW_HEIGHT 300
75
76/* These are what we use as the standard font sizes, for the size combo.
77   Note that when using points we still show these integer point values but
78   we work internally in decipoints (and decipoint values can be typed in). */
79static gchar * font_sizes[] = {
80  "8", "9", "10", "11", "12", "13", "14", "16", "18", "20", "22", "24", "26", "28",
81  "32", "36", "40", "48", "56", "64", "72"
82};
83
84static void gnome_font_selection_class_init (GnomeFontSelectionClass *klass);
85static void gnome_font_selection_init (GnomeFontSelection *fontsel);
86static void gnome_font_selection_destroy (GtkObject *object);
87
88static void gnome_font_selection_select_family (GtkTreeSelection   *selection, gpointer data);
89static void gnome_font_selection_select_style  (GtkTreeSelection   *selection, gpointer data);
90static void gnome_font_selection_select_size   (GtkWidget          *combo,     gpointer data);
91static void gnome_font_selection_fill_families (GnomeFontSelection *fontsel);
92static void gnome_font_selection_fill_styles   (GnomeFontSelection *fontsel);
93static gboolean find_row_to_select_cb (GtkTreeModel *model,
94                                       GtkTreePath *path,
95                                       GtkTreeIter *iter,
96                                       gpointer user_data);
97
98static GtkHBoxClass *gfs_parent_class = NULL;
99static guint gfs_signals[LAST_SIGNAL] = {0};
100
101GType
102gnome_font_selection_get_type ()
103{
104        static GType type = 0;
105        if (!type) {
106                static const GTypeInfo info = {
107                        sizeof (GnomeFontSelectionClass),
108                        NULL, NULL,
109                        (GClassInitFunc) gnome_font_selection_class_init,
110                        NULL, NULL,
111                        sizeof (GnomeFontSelection),
112                        0,
113                        (GInstanceInitFunc) gnome_font_selection_init,
114                        NULL
115                };
116                type = g_type_register_static (GTK_TYPE_HBOX, "GnomeFontSelection", &info, 0);
117        }
118        return type;
119}
120
121static void
122gnome_font_selection_class_init (GnomeFontSelectionClass *klass)
123{
124        GtkObjectClass *gtk_object_class;
125        GObjectClass *object_class;
126 
127        object_class = (GObjectClass *) klass;
128        gtk_object_class = (GtkObjectClass *) klass;
129 
130        gfs_parent_class = gtk_type_class (GTK_TYPE_HBOX);
131 
132        gfs_signals[FONT_SET] = g_signal_new ("font_set",
133                                              G_OBJECT_CLASS_TYPE (object_class),
134                                              G_SIGNAL_RUN_FIRST,
135                                              G_STRUCT_OFFSET (GnomeFontSelectionClass, font_set),
136                                              NULL, NULL,
137                                              libgnomeprintui_marshal_VOID__POINTER,
138                                              G_TYPE_NONE,
139                                              1,
140                                              G_TYPE_POINTER);
141
142        gtk_object_class->destroy = gnome_font_selection_destroy;
143}
144
145static void
146gnome_font_selection_init (GnomeFontSelection * fontsel)
147{
148        GtkWidget * f, * sw, * tv, * vb, * hb, * c, * l;
149        GtkListStore *store;
150        GtkTreeSelection *selection;
151        GtkTreeViewColumn *col;
152        GtkCellRenderer *rend;
153        AtkRelationSet *relation_set;
154        AtkRelation *relation;
155        AtkObject *relation_targets[1];
156        AtkObject *atko;
157        gint i;
158        GtkTreeModel *model;
159        gtk_box_set_homogeneous ((GtkBox *) fontsel, TRUE);
160        gtk_box_set_spacing ((GtkBox *) fontsel, 4);
161
162        /* Family frame */
163
164        f = gtk_frame_new (_("Font family"));
165        gtk_widget_show (f);
166        gtk_box_pack_start ((GtkBox *) fontsel, f, TRUE, TRUE, 0);
167
168        sw = gtk_scrolled_window_new (NULL, NULL);
169        gtk_container_set_border_width ((GtkContainer *) sw, 4);
170        gtk_scrolled_window_set_policy ((GtkScrolledWindow *) sw, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
171        gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) sw,
172                                             GTK_SHADOW_IN);
173        gtk_widget_show (sw);
174        gtk_container_add ((GtkContainer *) f, sw);
175
176        store = gtk_list_store_new (1, G_TYPE_STRING);
177        tv = gtk_tree_view_new_with_model ((GtkTreeModel*) store);
178        selection = gtk_tree_view_get_selection ((GtkTreeView*) tv);
179        gtk_tree_selection_set_mode ((GtkTreeSelection*) selection,
180                                     GTK_SELECTION_SINGLE);
181        g_object_unref ((GObject*) store);
182        gtk_tree_view_set_headers_visible ((GtkTreeView*) tv, FALSE);
183
184        rend = gtk_cell_renderer_text_new ();
185        col = gtk_tree_view_column_new_with_attributes (NULL, rend,
186                                                        "text", 0,
187                                                        NULL);
188        gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
189        gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
190        gtk_widget_show (tv);
191        g_signal_connect ((GObject*) selection, "changed",
192                          GTK_SIGNAL_FUNC (gnome_font_selection_select_family),
193                          fontsel);
194        gtk_container_add ((GtkContainer *) sw, tv);
195        fontsel->family = tv;
196        fontsel->selectedfamily = NULL;
197
198        atko = gtk_widget_get_accessible (tv);
199        atk_object_set_name (atko, _("Font family"));
200        atk_object_set_description (atko, _("The list of font families available"));
201
202        /* Fontbox */
203        vb = gtk_vbox_new (FALSE, 4);
204        gtk_widget_show (vb);
205        gtk_box_pack_start ((GtkBox *) fontsel, vb, TRUE, TRUE, 0);
206        fontsel->fontbox = vb;
207
208        /* Style frame */
209        f = gtk_frame_new (_("Style"));
210        gtk_widget_show (f);
211        gtk_box_pack_start ((GtkBox *) vb, f, TRUE, TRUE, 0);
212
213        /* Stylebox */
214        vb = gtk_vbox_new (FALSE, 4);
215        gtk_container_set_border_width ((GtkContainer *) vb, 4);
216        gtk_widget_show (vb);
217        gtk_container_add ((GtkContainer *) f, vb);
218        fontsel->stylebox = vb;
219
220        sw = gtk_scrolled_window_new (NULL, NULL);
221        gtk_scrolled_window_set_policy ((GtkScrolledWindow *) sw, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
222        gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) sw,
223                                             GTK_SHADOW_IN);
224        gtk_widget_show (sw);
225        gtk_box_pack_start ((GtkBox *) vb, sw, TRUE, TRUE, 0);
226
227        store = gtk_list_store_new (1, G_TYPE_STRING);
228        tv = gtk_tree_view_new_with_model ((GtkTreeModel*) store);
229        selection = gtk_tree_view_get_selection ((GtkTreeView*) tv);
230        gtk_tree_selection_set_mode ((GtkTreeSelection*) selection,
231                                     GTK_SELECTION_SINGLE);
232        g_object_unref ((GObject*) store);
233        gtk_tree_view_set_headers_visible ((GtkTreeView*) tv, FALSE);
234
235        rend = gtk_cell_renderer_text_new ();
236        col = gtk_tree_view_column_new_with_attributes (NULL, rend,
237                                                        "text", 0,
238                                                        NULL);
239        gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
240        gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
241        gtk_widget_show (tv);
242        g_signal_connect ((GObject*) selection, "changed",
243                          GTK_SIGNAL_FUNC (gnome_font_selection_select_style),
244                          fontsel);
245        gtk_container_add ((GtkContainer *) sw, tv);
246        fontsel->style = tv;
247        fontsel->selectedface = NULL;
248
249        atko = gtk_widget_get_accessible (tv);
250        atk_object_set_name (atko, _("Font style"));
251        atk_object_set_description (atko, _("The list of styles available for the selected font family"));
252
253        /* Sizebox */
254
255        hb = gtk_hbox_new (FALSE, 4);
256        gtk_widget_show (hb);
257        gtk_box_pack_start ((GtkBox *) vb, hb, FALSE, FALSE, 0);
258        fontsel->sizebox = hb;
259
260        model = (GtkTreeModel *) gtk_list_store_new (1, G_TYPE_STRING);
261        c = gtk_combo_box_entry_new_with_model (model, 0);
262        gtk_widget_set_size_request (c, 64, -1);
263        gtk_widget_show (c);
264        g_signal_connect (G_OBJECT (c), "changed",
265                          (GCallback) gnome_font_selection_select_size, fontsel);
266        gtk_box_pack_end ((GtkBox *) hb, c, FALSE, FALSE, 0);
267        fontsel->size = c;
268
269        for (i = 0; i < G_N_ELEMENTS (font_sizes); i++) {
270                GtkTreeIter iter;
271
272                gtk_list_store_append (GTK_LIST_STORE (model), &iter);
273                gtk_list_store_set (GTK_LIST_STORE (model), &iter,
274                                    0, font_sizes[i],
275                                    -1);
276                if (! strcmp (font_sizes[i], "12"))
277                        gtk_combo_box_set_active (GTK_COMBO_BOX (c), i);
278        }
279        fontsel->selectedsize = 12.0;
280
281        l = gtk_label_new_with_mnemonic (_("Font _size:"));
282        gtk_widget_show (l);
283        gtk_box_pack_end ((GtkBox *) hb, l, FALSE, FALSE, 0);
284        gtk_label_set_mnemonic_widget ((GtkLabel *) l, c);
285
286        /* Add a LABELLED_BY relation from the combo to the label. */
287        atko = gtk_widget_get_accessible (c);
288        relation_set = atk_object_ref_relation_set (atko);
289        relation_targets[0] = gtk_widget_get_accessible (l);
290        relation = atk_relation_new (relation_targets, 1,
291                                     ATK_RELATION_LABELLED_BY);
292        atk_relation_set_add (relation_set, relation);
293        g_object_unref (G_OBJECT (relation));
294        g_object_unref (G_OBJECT (relation_set));
295}
296
297static void
298gnome_font_selection_destroy (GtkObject *object)
299{
300        GnomeFontSelection *fontsel;
301 
302        g_return_if_fail (object != NULL);
303        g_return_if_fail (GNOME_IS_FONT_SELECTION (object));
304 
305        fontsel = GNOME_FONT_SELECTION (object);
306
307        if (fontsel->selectedfont) {
308                gnome_font_unref (fontsel->selectedfont);
309                fontsel->selectedfont = NULL;
310        }
311
312        if (fontsel->selectedface) {
313                gnome_font_face_unref (fontsel->selectedface);
314                fontsel->selectedface = NULL;
315        }
316
317        if (fontsel->selectedfamily) {
318                g_free (fontsel->selectedfamily);
319                fontsel->selectedfamily = NULL;
320        }
321
322        if (GTK_OBJECT_CLASS (gfs_parent_class)->destroy)
323                (* GTK_OBJECT_CLASS (gfs_parent_class)->destroy) (object);
324}
325
326GtkWidget *
327gnome_font_selection_new ()
328{
329        GnomeFontSelection * fontsel;
330        GtkTreeModel *model;
331        GtkTreeIter iter;
332
333        fontsel = g_object_new (GNOME_TYPE_FONT_SELECTION, NULL);
334 
335        gnome_font_selection_fill_families (fontsel);
336
337        /* Select first font in family list */
338
339        model = gtk_tree_view_get_model ((GtkTreeView*) fontsel->family);
340        if (gtk_tree_model_get_iter_first (model, &iter)) {
341                GtkTreeSelection *selection;
342                selection = gtk_tree_view_get_selection ((GtkTreeView*) fontsel->family);
343                gtk_tree_selection_select_iter (selection, &iter);
344        }
345
346        return GTK_WIDGET (fontsel);
347}
348
349static void
350gnome_font_selection_select_family (GtkTreeSelection *selection, gpointer data)
351{
352        GnomeFontSelection * fontsel;
353        GtkTreeView *tree_view;
354        GtkTreeModel *model;
355        GtkTreeIter iter;
356        GValue value = { 0 };
357        const gchar * familyname;
358
359        fontsel = GNOME_FONT_SELECTION (data);
360
361        tree_view = gtk_tree_selection_get_tree_view (selection);
362        if (!gtk_tree_selection_get_selected (selection, &model, &iter))
363                return;
364
365        gtk_tree_model_get_value (model, &iter, 0, &value);
366        familyname = g_value_get_string (&value);
367
368        if (fontsel->selectedfamily) {
369                g_free (fontsel->selectedfamily);
370        }
371
372        if (familyname) {
373                fontsel->selectedfamily = g_strdup (familyname);
374        } else {
375                fontsel->selectedfamily = NULL;
376        }
377
378        g_value_unset(&value);
379
380        gnome_font_selection_fill_styles (fontsel);
381}
382
383static void
384gnome_font_selection_select_style (GtkTreeSelection *selection, gpointer data)
385{
386        GnomeFontSelection * fontsel;
387        GtkTreeView *tree_view;
388        GtkTreeModel *model;
389        GtkTreeIter iter;
390        GValue value = { 0 };
391        const gchar * style;
392
393        fontsel = GNOME_FONT_SELECTION (data);
394
395        if (!fontsel->selectedfamily)
396                return;
397
398        tree_view = gtk_tree_selection_get_tree_view (selection);
399        if (!gtk_tree_selection_get_selected (selection, &model, &iter))
400                return;
401
402        gtk_tree_model_get_value (model, &iter, 0, &value);
403        style = g_value_get_string (&value);
404
405        if (fontsel->selectedface)
406                gnome_font_face_unref (fontsel->selectedface);
407        fontsel->selectedface = gnome_font_face_find_from_family_and_style (fontsel->selectedfamily, style);
408
409        if (fontsel->selectedfont)
410                gnome_font_unref (fontsel->selectedfont);
411        fontsel->selectedfont = gnome_font_face_get_font_default (fontsel->selectedface, fontsel->selectedsize);
412
413        g_value_unset(&value);
414
415        g_signal_emit (G_OBJECT (fontsel), gfs_signals[FONT_SET], 0, fontsel->selectedfont);
416}
417
418static void
419gnome_font_selection_select_size (GtkWidget *combo, gpointer data)
420{
421        GnomeFontSelection * fontsel;
422        GtkWidget *entry;
423        gchar * sizestr;
424
425        fontsel = GNOME_FONT_SELECTION (data);
426
427        if (!fontsel->selectedface)
428                return;
429
430        entry = gtk_bin_get_child (GTK_BIN (combo));
431        sizestr = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
432
433        fontsel->selectedsize = MAX (atoi (sizestr), 1.0);
434
435        g_free (sizestr);
436
437        if (fontsel->selectedfont)
438                gnome_font_unref (fontsel->selectedfont);
439        fontsel->selectedfont = gnome_font_face_get_font_default (fontsel->selectedface, fontsel->selectedsize);
440
441        g_signal_emit (GTK_OBJECT (fontsel), gfs_signals[FONT_SET], 0, fontsel->selectedfont);
442}
443
444static void
445gnome_font_selection_fill_families (GnomeFontSelection * fontsel)
446{
447        GList * families, * l;
448        GtkListStore *store;
449
450        families = gnome_font_family_list ();
451        g_return_if_fail (families != NULL);
452
453        store = (GtkListStore*) gtk_tree_view_get_model ((GtkTreeView*) fontsel->family);
454
455        gtk_list_store_clear (store);
456
457        for (l = families; l != NULL; l = l->next) {
458                GtkTreeIter iter;
459
460                gtk_list_store_append (store, &iter);
461                gtk_list_store_set (store, &iter, 0, l->data, -1);
462        }
463
464        gnome_font_family_list_free (families);
465}
466
467static void
468gnome_font_selection_fill_styles (GnomeFontSelection * fontsel)
469{
470        GList * styles, * l;
471        GtkListStore *store;
472        GtkTreeIter iter;
473
474        store = (GtkListStore*) gtk_tree_view_get_model ((GtkTreeView*) fontsel->style);
475
476        gtk_list_store_clear (store);
477
478        if (fontsel->selectedfamily) {
479                styles = gnome_font_style_list (fontsel->selectedfamily);
480                for (l = styles; l != NULL; l = l->next) {
481                        GtkTreeIter iter;
482
483                        gtk_list_store_append (store, &iter);
484                        gtk_list_store_set (store, &iter, 0, l->data, -1);
485                }
486                gnome_font_style_list_free (styles);
487        }
488
489        /* Select first font in style list */
490        if (gtk_tree_model_get_iter_first ((GtkTreeModel *) store, &iter)) {
491                GtkTreeSelection *selection;
492                selection = gtk_tree_view_get_selection ((GtkTreeView*) fontsel->style);
493                gtk_tree_selection_select_iter (selection, &iter);
494        }
495}
496
497
498/*****************************************************************************
499 * These functions are the main public interface for getting/setting the font.
500 *****************************************************************************/
501
502gdouble
503gnome_font_selection_get_size (GnomeFontSelection * fontsel)
504{
505        return fontsel->selectedsize;
506}
507
508GnomeFont*
509gnome_font_selection_get_font (GnomeFontSelection * fontsel)
510{
511        g_return_val_if_fail (fontsel != NULL, NULL);
512        g_return_val_if_fail (GNOME_IS_FONT_SELECTION (fontsel), NULL);
513
514        if (!fontsel->selectedface)
515                return NULL;
516
517        return gnome_font_face_get_font_default (fontsel->selectedface, fontsel->selectedsize);
518}
519
520GnomeFontFace *
521gnome_font_selection_get_face (GnomeFontSelection * fontsel)
522{
523        g_return_val_if_fail (fontsel != NULL, NULL);
524        g_return_val_if_fail (GNOME_IS_FONT_SELECTION (fontsel), NULL);
525
526        if (fontsel->selectedface)
527                gnome_font_face_ref (fontsel->selectedface);
528
529        return fontsel->selectedface;
530}
531
532typedef struct _GnomeFontSelectionSetFontData GnomeFontSelectionSetFontData;
533struct _GnomeFontSelectionSetFontData
534{
535        GtkTreeSelection *selection;
536        const gchar *row_to_select;
537};
538
539void
540gnome_font_selection_set_font (GnomeFontSelection * fontsel, GnomeFont * font)
541{
542        const GnomeFontFace * face;
543        const gchar * familyname, * stylename;
544        gdouble size;
545        GtkTreeModel *model;
546        GnomeFontSelectionSetFontData data;
547        gchar b[32];
548
549        g_return_if_fail (fontsel != NULL);
550        g_return_if_fail (GNOME_IS_FONT_SELECTION (fontsel));
551        g_return_if_fail (font != NULL);
552        g_return_if_fail (GNOME_IS_FONT (font));
553
554        face = gnome_font_get_face (font);
555        familyname = gnome_font_face_get_family_name (face);
556        stylename = gnome_font_face_get_species_name (face);
557        size = gnome_font_get_size (font);
558
559        /* Select the matching family. */
560        model = gtk_tree_view_get_model ((GtkTreeView*) fontsel->family);
561        data.selection = gtk_tree_view_get_selection ((GtkTreeView*) fontsel->family);
562        data.row_to_select = familyname;
563        gtk_tree_model_foreach (model, find_row_to_select_cb, &data);
564
565        /* Select the matching style. */
566        model = gtk_tree_view_get_model ((GtkTreeView*) fontsel->style);
567        data.selection = gtk_tree_view_get_selection ((GtkTreeView*) fontsel->style);
568        data.row_to_select = stylename;
569        gtk_tree_model_foreach (model, find_row_to_select_cb, &data);
570
571        g_snprintf (b, 32, "%2.1f", size);
572        b[31] = '\0';
573        gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (fontsel->size))), b);
574        fontsel->selectedsize = size;
575}
576
577static gboolean
578find_row_to_select_cb (GtkTreeModel *model,
579                       GtkTreePath *path,
580                       GtkTreeIter *iter,
581                       gpointer user_data)
582{
583        GnomeFontSelectionSetFontData *data = user_data;
584        gchar *family;
585        gint cmp;
586       
587        gtk_tree_model_get (model, iter, 0, &family, -1);
588       
589        cmp = strcmp (family, data->row_to_select);
590        g_free (family);
591       
592        if (cmp != 0)
593                return FALSE;
594
595        gtk_tree_selection_select_path (data->selection, path);
596        return TRUE;
597}
598
599
600/********************************************
601 * GnomeFontPreview
602 ********************************************/
603
604struct _GnomeFontPreview
605{
606        GtkImage image;
607
608        guchar *text;
609        GnomeFont *font;
610        guint32 color;
611};
612
613
614struct _GnomeFontPreviewClass
615{
616        GtkImageClass parent_class;
617};
618
619static void gnome_font_preview_class_init (GnomeFontPreviewClass *klass);
620static void gnome_font_preview_init (GnomeFontPreview * preview);
621static void gnome_font_preview_destroy (GtkObject *object);
622static void gnome_font_preview_update (GnomeFontPreview * preview);
623
624static GtkImageClass *gfp_parent_class = NULL;
625
626GType
627gnome_font_preview_get_type ()
628{
629        static GType type = 0;
630        if (!type) {
631                static const GTypeInfo info = {
632                        sizeof (GnomeFontPreviewClass),
633                        NULL, NULL,
634                        (GClassInitFunc) gnome_font_preview_class_init,
635                        NULL, NULL,
636                        sizeof (GnomeFontPreview),
637                        0,
638                        (GInstanceInitFunc) gnome_font_preview_init,
639                        NULL
640                };
641                type = g_type_register_static (GTK_TYPE_IMAGE, "GnomeFontPreview", &info, 0);
642        }
643        return type;
644}
645
646static void
647gnome_font_preview_class_init (GnomeFontPreviewClass *klass)
648{
649        GtkObjectClass *object_class;
650 
651        object_class = (GtkObjectClass *) klass;
652 
653        gfp_parent_class = gtk_type_class (GTK_TYPE_IMAGE);
654 
655        object_class->destroy = gnome_font_preview_destroy;
656}
657
658static void
659gnome_font_preview_init (GnomeFontPreview * preview)
660{
661        GtkWidget * w;
662
663        w = (GtkWidget *) preview;
664
665        preview->text = NULL;
666        preview->font = NULL;
667        preview->color = 0x000000ff;
668
669        gtk_widget_set_size_request (w, 64, MIN_PREVIEW_HEIGHT);
670}
671
672static void
673gnome_font_preview_destroy (GtkObject *object)
674{
675        GnomeFontPreview *preview;
676 
677        preview = (GnomeFontPreview *) object;
678
679        if (preview->text) {
680                g_free (preview->text);
681                preview->text = NULL;
682        }
683
684        if (preview->font) {
685                gnome_font_unref (preview->font);
686                preview->font = NULL;
687        }
688
689        if (GTK_OBJECT_CLASS (gfp_parent_class)->destroy)
690                (* GTK_OBJECT_CLASS (gfp_parent_class)->destroy) (object);
691}
692
693GtkWidget *
694gnome_font_preview_new (void)
695{
696        GnomeFontPreview * preview;
697 
698        preview = g_object_new (GNOME_TYPE_FONT_PREVIEW, NULL);
699
700        return GTK_WIDGET (preview);
701}
702
703void
704gnome_font_preview_set_phrase (GnomeFontPreview * preview, const guchar *phrase)
705{
706        g_return_if_fail (preview != NULL);
707        g_return_if_fail (GNOME_IS_FONT_PREVIEW (preview));
708
709        if (preview->text)
710                g_free (preview->text);
711
712        if (phrase) {
713                preview->text = g_strdup (phrase);
714        } else {
715                preview->text = NULL;
716        }
717
718        gnome_font_preview_update (preview);
719}
720
721
722void
723gnome_font_preview_set_font (GnomeFontPreview * preview, GnomeFont * font)
724{
725        g_return_if_fail (preview != NULL);
726        g_return_if_fail (GNOME_IS_FONT_PREVIEW (preview));
727        g_return_if_fail (font != NULL);
728        g_return_if_fail (GNOME_IS_FONT (font));
729
730        gnome_font_ref (font);
731
732        if (preview->font)
733                gnome_font_unref (preview->font);
734
735        preview->font = font;
736
737        gnome_font_preview_update (preview);
738}
739
740void
741gnome_font_preview_set_color (GnomeFontPreview * preview, guint32 color)
742{
743        g_return_if_fail (preview != NULL);
744        g_return_if_fail (GNOME_IS_FONT_PREVIEW (preview));
745
746        preview->color = color;
747
748        gnome_font_preview_update (preview);
749}
750
751static void
752gnome_font_preview_update (GnomeFontPreview *preview)
753{
754        const gdouble identity[] = {1.0, 0.0, 0.0, -1.0, 0.0, 0.0};
755        GdkPixbuf *pixbuf;
756        gint width, height;
757        GnomePosGlyphList *pgl;
758
759        if (!preview->font) {
760                width = 256;
761                height = 32;
762                pgl = NULL;
763        } else {
764                const guchar *sample;
765                GnomeGlyphList *gl;
766                ArtDRect bbox;
767
768                if (preview->text) {
769                        sample = preview->text;
770                } else {
771                        sample = gnome_font_face_get_sample (gnome_font_get_face (preview->font));
772                        if (!sample)
773                                sample = _("This font does not have sample");
774                }
775                gl = gnome_glyphlist_from_text_dumb (preview->font, preview->color, 0.0, 0.0, sample);
776                pgl = gnome_pgl_from_gl (gl, identity, GNOME_PGL_RENDER_DEFAULT);
777                gnome_glyphlist_unref (gl);
778                gnome_pgl_bbox (pgl, &bbox);
779                width = CLAMP (bbox.x1 - bbox.x0 + 32, 128, 512);
780                height = CLAMP (bbox.y1 - bbox.y0 + 16, 32, 256);
781        }
782
783        pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
784        gdk_pixbuf_fill (pixbuf, 0xffffffff);
785
786        if (pgl) {
787                ArtDRect bbox;
788                gint x, y;
789                gnome_pgl_bbox (pgl, &bbox);
790                x = MAX ((width - (bbox.x1 - bbox.x0)) / 2 - bbox.x0, 0);
791                y = MIN (height - (height - (bbox.y1 - bbox.y0)) / 2 - bbox.y1, height);
792                gnome_pgl_render_rgb8 (pgl, x, y,
793                                       gdk_pixbuf_get_pixels (pixbuf),
794                                       gdk_pixbuf_get_width (pixbuf),
795                                       gdk_pixbuf_get_height (pixbuf),
796                                       gdk_pixbuf_get_rowstride (pixbuf),
797                                       GNOME_PGL_RENDER_DEFAULT);
798                gnome_pgl_destroy (pgl);
799        }
800
801        gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
802        g_object_unref (G_OBJECT (pixbuf));
803}
804
805/*****************************************************************************
806 * GtkFontSelectionDialog
807 *****************************************************************************/
808
809struct _GnomeFontDialog {
810        GtkDialog dialog;
811
812        GtkWidget *fontsel;
813        GtkWidget *preview;
814};
815
816struct _GnomeFontDialogClass {
817        GtkDialogClass parent_class;
818};
819
820static void gnome_font_dialog_class_init (GnomeFontDialogClass *klass);
821static void gnome_font_dialog_init (GnomeFontDialog *fontseldiag);
822
823static void gfsd_update_preview (GnomeFontSelection * fs, GnomeFont * font, GnomeFontDialog * gfsd);
824
825static GtkDialogClass *gfsd_parent_class = NULL;
826
827GType
828gnome_font_dialog_get_type (void)
829{
830        static GType type = 0;
831        if (!type) {
832                static const GTypeInfo info = {
833                        sizeof (GnomeFontDialogClass),
834                        NULL, NULL,
835                        (GClassInitFunc) gnome_font_dialog_class_init,
836                        NULL, NULL,
837                        sizeof (GnomeFontDialog),
838                        0,
839                        (GInstanceInitFunc) gnome_font_dialog_init
840                };
841                type = g_type_register_static (GTK_TYPE_DIALOG, "GnomeFontDialog", &info, 0);
842        }
843        return type;
844}
845
846static void
847gnome_font_dialog_class_init (GnomeFontDialogClass *klass)
848{
849        GtkObjectClass *object_class;
850 
851        object_class = (GtkObjectClass*) klass;
852 
853        gfsd_parent_class = gtk_type_class (GTK_TYPE_DIALOG);
854}
855
856static void
857gnome_font_dialog_init (GnomeFontDialog *fontseldiag)
858{
859        GnomeFont * font;
860        AtkObject *atko;
861
862        gtk_window_set_default_size (GTK_WINDOW (fontseldiag), 500, 300);
863       
864        gtk_dialog_add_button (GTK_DIALOG (fontseldiag), GTK_STOCK_OK, GTK_RESPONSE_OK);
865        gtk_dialog_add_button (GTK_DIALOG (fontseldiag), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
866
867        gtk_dialog_set_default_response (GTK_DIALOG (fontseldiag), GTK_RESPONSE_CANCEL);
868
869        gtk_container_set_border_width (GTK_CONTAINER (fontseldiag), 4);
870
871        fontseldiag->fontsel = gnome_font_selection_new ();
872        gtk_widget_show (fontseldiag->fontsel);
873        gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fontseldiag)->vbox), fontseldiag->fontsel, TRUE, TRUE, 0);
874
875        fontseldiag->preview = gnome_font_preview_new ();
876        gtk_widget_show (fontseldiag->preview);
877        gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fontseldiag)->vbox), fontseldiag->preview, TRUE, TRUE, 0);
878
879        atko = gtk_widget_get_accessible (fontseldiag->preview);
880        atk_object_set_name (atko, _("Font Preview"));
881        atk_object_set_description (atko, _("Displays some example text in the selected font"));
882
883        font = gnome_font_selection_get_font ((GnomeFontSelection *) fontseldiag->fontsel);
884        gnome_font_preview_set_font ((GnomeFontPreview *) fontseldiag->preview, font);
885
886        g_signal_connect (G_OBJECT (fontseldiag->fontsel), "font_set",
887                          (GCallback) gfsd_update_preview, fontseldiag);
888}
889
890GtkWidget*
891gnome_font_dialog_new   (const gchar      *title)
892{
893        GnomeFontDialog *fontseldiag;
894 
895        fontseldiag = g_object_new (GNOME_TYPE_FONT_DIALOG, NULL);
896        gtk_window_set_title (GTK_WINDOW (fontseldiag), title ? title : _("Font Selection"));
897
898        return GTK_WIDGET (fontseldiag);
899}
900
901GtkWidget *
902gnome_font_dialog_get_fontsel (GnomeFontDialog *gfsd)
903{
904        g_return_val_if_fail (gfsd != NULL, NULL);
905        g_return_val_if_fail (GNOME_IS_FONT_DIALOG (gfsd), NULL);
906
907        return gfsd->fontsel;
908}
909
910GtkWidget *
911gnome_font_dialog_get_preview (GnomeFontDialog *gfsd)
912{
913        g_return_val_if_fail (gfsd != NULL, NULL);
914        g_return_val_if_fail (GNOME_IS_FONT_DIALOG (gfsd), NULL);
915
916        return gfsd->preview;
917}
918
919static void
920gfsd_update_preview (GnomeFontSelection * fs, GnomeFont * font, GnomeFontDialog * gfsd)
921{
922        gnome_font_preview_set_font ((GnomeFontPreview *) gfsd->preview, font);
923}
924
Note: See TracBrowser for help on using the repository browser.