~kroq-gar78/ubuntu/precise/gnome-control-center/fix-885947

« back to all changes in this revision

Viewing changes to font-viewer/font-view.c

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Moya
  • Date: 2011-05-17 10:47:27 UTC
  • mfrom: (0.1.11 experimental) (1.1.45 upstream)
  • Revision ID: james.westby@ubuntu.com-20110517104727-lqel6m8vhfw5jby1
Tags: 1:3.0.1.1-1ubuntu1
* Rebase on Debian, remaining Ubuntu changes:
* debian/control:
  - Build-Depend on hardening-wrapper, dpkg-dev and dh-autoreconf
  - Add dependency on ubuntu-system-service
  - Remove dependency on gnome-icon-theme-symbolic
  - Move dependency on apg, gnome-icon-theme-symbolic and accountsservice to
    be a Recommends: until we get them in main
* debian/rules:
  - Use autoreconf
  - Add binary-post-install rule for gnome-control-center-data
  - Run dh-autoreconf
* debian/gnome-control-center.dirs:
* debian/gnome-control-center.links:
  - Add a link to the control center shell for indicators
* debian/patches/00_disable-nm.patch:
  - Temporary patch to disable building with NetworkManager until we get
    the new one in the archive
* debian/patches/01_git_remove_gettext_calls.patch:
  - Remove calls to AM_GNU_GETTEXT, IT_PROG_INTLTOOL should be enough
* debian/patches/01_git_kill_warning.patch:
  - Kill warning
* debian/patches/50_ubuntu_systemwide_prefs.patch:
  - Ubuntu specific proxy preferences
* debian/patches/51_ubuntu_system_keyboard.patch:
  - Implement the global keyboard spec at https://wiki.ubuntu.com/DefaultKeyboardSettings

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: C; c-basic-offset: 4 -*-
2
 
 * fontilus - a collection of font utilities for GNOME
3
 
 * Copyright (C) 2002-2003  James Henstridge <james@daa.com.au>
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (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 General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
 */
19
 
 
20
 
#ifdef HAVE_CONFIG_H
21
 
#  include <config.h>
22
 
#endif
23
 
 
24
 
#include <ft2build.h>
25
 
#include FT_FREETYPE_H
26
 
#include FT_TYPE1_TABLES_H
27
 
#include FT_SFNT_NAMES_H
28
 
#include FT_TRUETYPE_IDS_H
29
 
#include <X11/Xlib.h>
30
 
#include <X11/Xft/Xft.h>
31
 
 
32
 
#include <gio/gio.h>
33
 
#include <gtk/gtk.h>
34
 
#include <gdk/gdkx.h>
35
 
#include <glib/gi18n.h>
36
 
 
37
 
FT_Error FT_New_Face_From_URI(FT_Library library,
38
 
                              const gchar *uri,
39
 
                              FT_Long face_index,
40
 
                              FT_Face *aface);
41
 
 
42
 
static const gchar lowercase_text[] = "abcdefghijklmnopqrstuvwxyz";
43
 
static const gchar uppercase_text[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
44
 
static const gchar punctuation_text[] = "0123456789.:,;(*!?')";
45
 
 
46
 
static inline XftFont *
47
 
get_font(Display *xdisplay, FT_Face face, gint size, FcCharSet *charset)
48
 
{
49
 
    FcPattern *pattern;
50
 
    XftFont *font;
51
 
    int screen = DefaultScreen (xdisplay);
52
 
 
53
 
    pattern = FcPatternBuild(NULL,
54
 
                             FC_FT_FACE, FcTypeFTFace, face,
55
 
                             FC_PIXEL_SIZE, FcTypeDouble, (double)size,
56
 
                             NULL);
57
 
 
58
 
    if (charset)
59
 
        FcPatternAddCharSet (pattern, "charset", charset);
60
 
 
61
 
    FcConfigSubstitute (NULL, pattern, FcMatchPattern);
62
 
    XftDefaultSubstitute (xdisplay, screen, pattern);
63
 
 
64
 
    font = XftFontOpenPattern(xdisplay, pattern);
65
 
 
66
 
    return font;
67
 
}
68
 
 
69
 
static inline void
70
 
draw_string(Display *xdisplay, XftDraw *draw, XftFont *font, XftColor *colour,
71
 
            const gchar *text, gint *pos_y)
72
 
{
73
 
    XGlyphInfo extents;
74
 
    gint len = strlen(text);
75
 
 
76
 
    XftTextExtentsUtf8(xdisplay, font, (guchar *)text, len, &extents);
77
 
    XftDrawStringUtf8(draw, colour, font, 4, *pos_y + extents.y, (guchar *)text, len);
78
 
    *pos_y += extents.height + 4;
79
 
}
80
 
 
81
 
static gboolean
82
 
check_font_contain_text (FT_Face face, const gchar *text)
83
 
{
84
 
    while (text && *text)
85
 
        {
86
 
            gunichar wc = g_utf8_get_char (text);
87
 
            if (!FT_Get_Char_Index (face, wc))
88
 
                return FALSE;
89
 
 
90
 
            text = g_utf8_next_char (text);
91
 
        }
92
 
 
93
 
    return TRUE;
94
 
}
95
 
 
96
 
 
97
 
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, GdkPixmap *pixmap);
98
 
 
99
 
static GdkPixmap *
100
 
create_text_pixmap(GtkWidget *drawing_area, FT_Face face)
101
 
{
102
 
    gint i, pixmap_width, pixmap_height, pos_y, textlen;
103
 
    GdkPixmap *pixmap = NULL;
104
 
    const gchar *text;
105
 
    Display *xdisplay;
106
 
    Drawable xdrawable;
107
 
    Visual *xvisual;
108
 
    Colormap xcolormap;
109
 
    XftDraw *draw;
110
 
    XftColor colour;
111
 
    XGlyphInfo extents;
112
 
    XftFont *font;
113
 
    gint *sizes = NULL, n_sizes, alpha_size;
114
 
    FcCharSet *charset = NULL;
115
 
    GdkWindow *window = gtk_widget_get_window (drawing_area);
116
 
 
117
 
    text = pango_language_get_sample_string(NULL);
118
 
    if (! check_font_contain_text (face, text))
119
 
        {
120
 
            pango_language_get_sample_string (pango_language_from_string ("en_US"));
121
 
        }
122
 
 
123
 
    textlen = strlen(text);
124
 
 
125
 
    /* create the XftDraw */
126
 
    xdisplay = GDK_PIXMAP_XDISPLAY(window);
127
 
    xvisual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(window));
128
 
    xcolormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(window));
129
 
    XftColorAllocName(xdisplay, xvisual, xcolormap, "black", &colour);
130
 
 
131
 
    /* work out what sizes to render */
132
 
    if (FT_IS_SCALABLE(face)) {
133
 
        n_sizes = 8;
134
 
        sizes = g_new(gint, n_sizes);
135
 
        sizes[0] = 8;
136
 
        sizes[1] = 10;
137
 
        sizes[2] = 12;
138
 
        sizes[3] = 18;
139
 
        sizes[4] = 24;
140
 
        sizes[5] = 36;
141
 
        sizes[6] = 48;
142
 
        sizes[7] = 72;
143
 
        alpha_size = 24;
144
 
    } else {
145
 
        /* use fixed sizes */
146
 
        n_sizes = face->num_fixed_sizes;
147
 
        sizes = g_new(gint, n_sizes);
148
 
        alpha_size = 0;
149
 
        for (i = 0; i < face->num_fixed_sizes; i++) {
150
 
            sizes[i] = face->available_sizes[i].height;
151
 
 
152
 
            /* work out which font size to render */
153
 
            if (face->available_sizes[i].height <= 24)
154
 
                alpha_size = face->available_sizes[i].height;
155
 
        }
156
 
    }
157
 
 
158
 
    /* calculate size of pixmap to use (with 4 pixels padding) ... */
159
 
    pixmap_width = 8;
160
 
    pixmap_height = 8;
161
 
 
162
 
    font = get_font(xdisplay, face, alpha_size, charset);
163
 
    charset = FcCharSetCopy (font->charset);
164
 
    XftTextExtentsUtf8(xdisplay, font,
165
 
                       (guchar *)lowercase_text, strlen(lowercase_text), &extents);
166
 
    pixmap_height += extents.height + 4;
167
 
    pixmap_width = MAX(pixmap_width, 8 + extents.width);
168
 
    XftTextExtentsUtf8(xdisplay, font,
169
 
                       (guchar *)uppercase_text, strlen(uppercase_text), &extents);
170
 
    pixmap_height += extents.height + 4;
171
 
    pixmap_width = MAX(pixmap_width, 8 + extents.width);
172
 
    XftTextExtentsUtf8(xdisplay, font,
173
 
                       (guchar *)punctuation_text, strlen(punctuation_text), &extents);
174
 
    pixmap_height += extents.height + 4;
175
 
    pixmap_width = MAX(pixmap_width, 8 + extents.width);
176
 
    XftFontClose(xdisplay, font);
177
 
 
178
 
    pixmap_height += 8;
179
 
 
180
 
    for (i = 0; i < n_sizes; i++) {
181
 
        font = get_font(xdisplay, face, sizes[i], charset);
182
 
        if (!font) continue;
183
 
        XftTextExtentsUtf8(xdisplay, font, (guchar *)text, textlen, &extents);
184
 
        pixmap_height += extents.height + 4;
185
 
        pixmap_width = MAX(pixmap_width, 8 + extents.width);
186
 
        XftFontClose(xdisplay, font);
187
 
    }
188
 
 
189
 
    /* create pixmap */
190
 
    gtk_widget_set_size_request(drawing_area, pixmap_width, pixmap_height);
191
 
    pixmap = gdk_pixmap_new(window,
192
 
                            pixmap_width, pixmap_height, -1);
193
 
    if (!pixmap)
194
 
        goto end;
195
 
    gdk_draw_rectangle(pixmap, gtk_widget_get_style(drawing_area)->white_gc,
196
 
                       TRUE, 0, 0, pixmap_width, pixmap_height);
197
 
 
198
 
    xdrawable = GDK_DRAWABLE_XID(pixmap);
199
 
    draw = XftDrawCreate(xdisplay, xdrawable, xvisual, xcolormap);
200
 
 
201
 
    /* draw text */
202
 
    pos_y = 4;
203
 
    font = get_font(xdisplay, face, alpha_size, charset);
204
 
    draw_string(xdisplay, draw, font, &colour, lowercase_text, &pos_y);
205
 
    draw_string(xdisplay, draw, font, &colour, uppercase_text, &pos_y);
206
 
    draw_string(xdisplay, draw, font, &colour, punctuation_text, &pos_y);
207
 
    XftFontClose(xdisplay, font);
208
 
 
209
 
    pos_y += 8;
210
 
    for (i = 0; i < n_sizes; i++) {
211
 
        font = get_font(xdisplay, face, sizes[i], charset);
212
 
        if (!font) continue;
213
 
        draw_string(xdisplay, draw, font, &colour, text, &pos_y);
214
 
        XftFontClose(xdisplay, font);
215
 
    }
216
 
 
217
 
    g_signal_connect(drawing_area, "expose-event", G_CALLBACK(expose_event),
218
 
                     pixmap);
219
 
 
220
 
 end:
221
 
    g_free(sizes);
222
 
    FcCharSetDestroy (charset);
223
 
    return pixmap;
224
 
}
225
 
 
226
 
static void
227
 
add_row(GtkWidget *table, gint *row_p,
228
 
        const gchar *name, const gchar *value, gboolean multiline,
229
 
        gboolean expand)
230
 
{
231
 
    gchar *bold_name;
232
 
    GtkWidget *name_w;
233
 
 
234
 
    bold_name = g_strconcat("<b>", name, "</b>", NULL);
235
 
    name_w = gtk_label_new(bold_name);
236
 
    g_free(bold_name);
237
 
    gtk_misc_set_alignment(GTK_MISC(name_w), 0.0, 0.0);
238
 
    gtk_label_set_use_markup(GTK_LABEL(name_w), TRUE);
239
 
 
240
 
    gtk_table_attach(GTK_TABLE(table), name_w, 0, 1, *row_p, *row_p + 1,
241
 
                     GTK_FILL, GTK_FILL, 0, 0);
242
 
 
243
 
    if (multiline) {
244
 
        GtkWidget *label, *viewport;
245
 
        GtkScrolledWindow *swin;
246
 
        guint flags;
247
 
 
248
 
        label = gtk_label_new (value);
249
 
        gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
250
 
        gtk_label_set_selectable (GTK_LABEL (label), TRUE);
251
 
        gtk_widget_set_size_request (label, 200, -1);
252
 
        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
253
 
 
254
 
 
255
 
        swin = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
256
 
        gtk_scrolled_window_set_policy(swin,
257
 
                                       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
258
 
 
259
 
        viewport = gtk_viewport_new (gtk_scrolled_window_get_hadjustment (swin),
260
 
                                     gtk_scrolled_window_get_vadjustment (swin));
261
 
        gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
262
 
 
263
 
        gtk_container_add (GTK_CONTAINER(swin), viewport);
264
 
        (*row_p)++;
265
 
        if (expand)
266
 
          flags = GTK_FILL|GTK_EXPAND;
267
 
        else
268
 
          flags = GTK_FILL;
269
 
        gtk_table_attach(GTK_TABLE(table), GTK_WIDGET(swin), 0, 2, *row_p, *row_p + 1,
270
 
                         GTK_FILL|GTK_EXPAND, flags, 0, 0);
271
 
 
272
 
        gtk_container_add (GTK_CONTAINER (viewport), label);
273
 
    } else {
274
 
        GtkWidget *label = gtk_label_new(value);
275
 
        gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
276
 
        gtk_label_set_selectable(GTK_LABEL(label), TRUE);
277
 
        gtk_table_attach(GTK_TABLE(table), label, 1, 2, *row_p, *row_p + 1,
278
 
                         GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
279
 
    }
280
 
 
281
 
 
282
 
    (*row_p)++;
283
 
}
284
 
 
285
 
static void
286
 
add_face_info(GtkWidget *table, gint *row_p, const gchar *uri, FT_Face face)
287
 
{
288
 
    gchar *s;
289
 
    GFile *file;
290
 
    GFileInfo *info;
291
 
    PS_FontInfoRec ps_info;
292
 
 
293
 
    add_row(table, row_p, _("Name:"), face->family_name, FALSE, FALSE);
294
 
 
295
 
    if (face->style_name)
296
 
        add_row(table, row_p, _("Style:"), face->style_name, FALSE, FALSE);
297
 
 
298
 
    file = g_file_new_for_uri (uri);
299
 
 
300
 
    info = g_file_query_info (file,
301
 
                              G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
302
 
                              G_FILE_ATTRIBUTE_STANDARD_SIZE,
303
 
                              G_FILE_QUERY_INFO_NONE,
304
 
                              NULL, NULL);
305
 
    g_object_unref (file);
306
 
 
307
 
    if (info) {
308
 
        s = g_content_type_get_description (g_file_info_get_content_type (info));
309
 
        add_row (table, row_p, _("Type:"), s, FALSE, FALSE);
310
 
        g_free (s);
311
 
 
312
 
        s = g_format_size_for_display (g_file_info_get_size (info));
313
 
        add_row (table, row_p, _("Size:"), s, FALSE, FALSE);
314
 
        g_free (s);
315
 
 
316
 
        g_object_unref (info);
317
 
    }
318
 
 
319
 
    if (FT_IS_SFNT(face)) {
320
 
        gint i, len;
321
 
        gchar *version = NULL, *copyright = NULL, *description = NULL;
322
 
 
323
 
        len = FT_Get_Sfnt_Name_Count(face);
324
 
        for (i = 0; i < len; i++) {
325
 
            FT_SfntName sname;
326
 
 
327
 
            if (FT_Get_Sfnt_Name(face, i, &sname) != 0)
328
 
                continue;
329
 
 
330
 
            /* only handle the unicode names for US langid */
331
 
            if (!(sname.platform_id == TT_PLATFORM_MICROSOFT &&
332
 
                  sname.encoding_id == TT_MS_ID_UNICODE_CS &&
333
 
                  sname.language_id == TT_MS_LANGID_ENGLISH_UNITED_STATES))
334
 
                continue;
335
 
 
336
 
            switch (sname.name_id) {
337
 
            case TT_NAME_ID_COPYRIGHT:
338
 
                g_free(copyright);
339
 
                copyright = g_convert((gchar *)sname.string, sname.string_len,
340
 
                                      "UTF-8", "UTF-16BE", NULL, NULL, NULL);
341
 
                break;
342
 
            case TT_NAME_ID_VERSION_STRING:
343
 
                g_free(version);
344
 
                version = g_convert((gchar *)sname.string, sname.string_len,
345
 
                                    "UTF-8", "UTF-16BE", NULL, NULL, NULL);
346
 
                break;
347
 
            case TT_NAME_ID_DESCRIPTION:
348
 
                g_free(description);
349
 
                description = g_convert((gchar *)sname.string, sname.string_len,
350
 
                                        "UTF-8", "UTF-16BE", NULL, NULL, NULL);
351
 
                break;
352
 
            default:
353
 
                break;
354
 
            }
355
 
        }
356
 
        if (version) {
357
 
            add_row(table, row_p, _("Version:"), version, FALSE, FALSE);
358
 
            g_free(version);
359
 
        }
360
 
        if (copyright) {
361
 
            add_row(table, row_p, _("Copyright:"), copyright, TRUE, TRUE);
362
 
            g_free(copyright);
363
 
        }
364
 
        if (description) {
365
 
            add_row(table, row_p, _("Description:"), description, TRUE, TRUE);
366
 
            g_free(description);
367
 
        }
368
 
    } else if (FT_Get_PS_Font_Info(face, &ps_info) == 0) {
369
 
        if (ps_info.version && g_utf8_validate(ps_info.version, -1, NULL))
370
 
            add_row(table, row_p, _("Version:"), ps_info.version, FALSE, FALSE);
371
 
        if (ps_info.notice && g_utf8_validate(ps_info.notice, -1, NULL))
372
 
            add_row(table, row_p, _("Copyright:"), ps_info.notice, TRUE, FALSE);
373
 
    }
374
 
}
375
 
 
376
 
static gboolean
377
 
expose_event(GtkWidget *widget, GdkEventExpose *event, GdkPixmap *pixmap)
378
 
{
379
 
    gdk_draw_drawable(gtk_widget_get_window (widget),
380
 
                      gtk_widget_get_style (widget)->fg_gc[gtk_widget_get_state (widget)],
381
 
                      pixmap,
382
 
                      event->area.x, event->area.y,
383
 
                      event->area.x, event->area.y,
384
 
                      event->area.width, event->area.height);
385
 
    return FALSE;
386
 
}
387
 
 
388
 
static void
389
 
set_icon(GtkWindow *window, const gchar *uri)
390
 
{
391
 
    GFile *file;
392
 
    GIcon *icon;
393
 
    GFileInfo *info;
394
 
    GdkScreen *screen;
395
 
    GtkIconTheme *icon_theme;
396
 
    const gchar *icon_name = NULL, *content_type;
397
 
 
398
 
    screen = gtk_widget_get_screen (GTK_WIDGET (window));
399
 
    icon_theme = gtk_icon_theme_get_for_screen (screen);
400
 
 
401
 
    file = g_file_new_for_uri (uri);
402
 
 
403
 
    info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
404
 
                              G_FILE_QUERY_INFO_NONE, NULL, NULL);
405
 
    g_object_unref (file);
406
 
 
407
 
    if (! info)
408
 
        return;
409
 
 
410
 
    content_type = g_file_info_get_content_type (info);
411
 
    icon = g_content_type_get_icon (content_type);
412
 
 
413
 
    if (G_IS_THEMED_ICON (icon)) {
414
 
       const gchar * const *names = NULL;
415
 
 
416
 
       names = g_themed_icon_get_names (G_THEMED_ICON (icon));
417
 
       if (names) {
418
 
          gint i;
419
 
          for (i = 0; names[i]; i++) {
420
 
              if (gtk_icon_theme_has_icon (icon_theme, names[i])) {
421
 
                  icon_name = names[i];
422
 
                  break;
423
 
              }
424
 
          }
425
 
       }
426
 
    }
427
 
 
428
 
    if (icon_name) {
429
 
        gtk_window_set_icon_name (window, icon_name);
430
 
    }
431
 
 
432
 
    g_object_unref (icon);
433
 
}
434
 
 
435
 
static void
436
 
font_install_finished_cb (GObject      *source_object,
437
 
                          GAsyncResult *res,
438
 
                          gpointer      data)
439
 
{
440
 
    GError *err = NULL;
441
 
 
442
 
    g_file_copy_finish (G_FILE (source_object), res, &err);
443
 
 
444
 
    if (!err) {
445
 
        gtk_button_set_label (GTK_BUTTON (data), _("Installed"));
446
 
    }
447
 
    else {
448
 
        gtk_button_set_label (GTK_BUTTON (data), _("Install Failed"));
449
 
        g_debug ("Install failed: %s", err->message);
450
 
        g_error_free (err);
451
 
    }
452
 
    gtk_widget_set_sensitive (GTK_WIDGET (data), FALSE);
453
 
}
454
 
 
455
 
static void
456
 
install_button_clicked_cb (GtkButton   *button,
457
 
                           const gchar *font_file)
458
 
{
459
 
    GFile *src, *dest;
460
 
    gchar *dest_path, *dest_filename;
461
 
 
462
 
    GError *err = NULL;
463
 
 
464
 
    /* first check if ~/.fonts exists */
465
 
    dest_path = g_build_filename (g_get_home_dir (), ".fonts", NULL);
466
 
    if (!g_file_test (dest_path, G_FILE_TEST_EXISTS)) {
467
 
        GFile *f = g_file_new_for_path (dest_path);
468
 
        g_file_make_directory_with_parents (f, NULL, &err);
469
 
        g_object_unref (f);
470
 
        if (err) {
471
 
            /* TODO: show error dialog */
472
 
            g_warning ("Could not create fonts directory: %s", err->message);
473
 
            g_error_free (err);
474
 
            g_free (dest_path);
475
 
            return;
476
 
        }
477
 
    }
478
 
    g_free (dest_path);
479
 
 
480
 
    /* create destination filename */
481
 
    src = g_file_new_for_uri (font_file);
482
 
 
483
 
    dest_filename = g_file_get_basename (src);
484
 
    dest_path = g_build_filename (g_get_home_dir (), ".fonts", dest_filename, NULL);
485
 
    g_free (dest_filename);
486
 
 
487
 
    dest = g_file_new_for_path (dest_path);
488
 
 
489
 
    /* TODO: show error dialog if file exists */
490
 
    g_file_copy_async (src, dest, G_FILE_COPY_NONE, 0, NULL, NULL, NULL,
491
 
                       font_install_finished_cb, button);
492
 
 
493
 
    g_object_unref (src);
494
 
    g_object_unref (dest);
495
 
    g_free (dest_path);
496
 
}
497
 
 
498
 
int
499
 
main(int argc, char **argv)
500
 
{
501
 
    FT_Error error;
502
 
    FT_Library library;
503
 
    FT_Face face;
504
 
    GFile *file;
505
 
    gchar *font_file, *title;
506
 
    gint row;
507
 
    GtkWidget *window, *hbox, *table, *swin, *drawing_area;
508
 
    GdkPixmap *pixmap;
509
 
    GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
510
 
    GtkWidget *button, *align;
511
 
 
512
 
    bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR);
513
 
    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
514
 
    textdomain(GETTEXT_PACKAGE);
515
 
 
516
 
    gtk_init(&argc, &argv);
517
 
 
518
 
    if (argc != 2) {
519
 
        g_printerr(_("usage: %s fontfile\n"), argv[0]);
520
 
        return 1;
521
 
    }
522
 
 
523
 
    if (!XftInitFtLibrary()) {
524
 
        g_printerr("could not initialise freetype library\n");
525
 
        return 1;
526
 
    }
527
 
 
528
 
    error = FT_Init_FreeType(&library);
529
 
    if (error) {
530
 
        g_printerr("could not initialise freetype\n");
531
 
        return 1;
532
 
    }
533
 
 
534
 
    file = g_file_new_for_commandline_arg (argv[1]);
535
 
    font_file = g_file_get_uri (file);
536
 
    g_object_unref (file);
537
 
 
538
 
    if (!font_file) {
539
 
        g_printerr("could not parse argument into a URI\n");
540
 
        return 1;
541
 
    }
542
 
 
543
 
    error = FT_New_Face_From_URI(library, font_file, 0, &face);
544
 
    if (error) {
545
 
        g_printerr("could not load face '%s'\n", font_file);
546
 
        return 1;
547
 
    }
548
 
 
549
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
550
 
    title = g_strconcat(face->family_name,
551
 
                        face->style_name ? ", " : "",
552
 
                        face->style_name, NULL);
553
 
    gtk_window_set_title(GTK_WINDOW(window), title);
554
 
    set_icon(GTK_WINDOW(window), font_file);
555
 
    g_free(title);
556
 
    gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
557
 
 
558
 
    hbox = gtk_hbox_new(FALSE, 0);
559
 
    gtk_container_add(GTK_CONTAINER(window), hbox);
560
 
 
561
 
    swin = gtk_scrolled_window_new(NULL, NULL);
562
 
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
563
 
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
564
 
    gtk_box_pack_start(GTK_BOX(hbox), swin, TRUE, TRUE, 0);
565
 
 
566
 
    drawing_area = gtk_drawing_area_new();
567
 
    gtk_widget_modify_bg(drawing_area, GTK_STATE_NORMAL, &white);
568
 
    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin),
569
 
                                          drawing_area);
570
 
    g_signal_connect (drawing_area, "realize", create_text_pixmap, face);
571
 
 
572
 
    /* set the minimum size on the scrolled window to prevent
573
 
     * unnecessary scrolling */
574
 
    gtk_widget_set_size_request(swin, 500, -1);
575
 
 
576
 
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
577
 
 
578
 
    table = gtk_table_new(1, 2, FALSE);
579
 
    gtk_container_set_border_width(GTK_CONTAINER(table), 5);
580
 
    gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, TRUE, 0);
581
 
 
582
 
    row = 0;
583
 
    add_face_info(table, &row, font_file, face);
584
 
 
585
 
    /* add install button */
586
 
    align = gtk_alignment_new (1.0, 0.5, 0.0, 0.0);
587
 
    gtk_table_attach (GTK_TABLE (table), align, 0, 2, row, row + 1,
588
 
                      GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
589
 
 
590
 
    button = gtk_button_new_with_mnemonic (_("I_nstall Font"));
591
 
    g_signal_connect (button, "clicked",
592
 
                      G_CALLBACK (install_button_clicked_cb), font_file);
593
 
    gtk_container_add (GTK_CONTAINER (align), button);
594
 
 
595
 
 
596
 
    gtk_table_set_col_spacings(GTK_TABLE(table), 8);
597
 
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
598
 
    gtk_widget_show_all(window);
599
 
 
600
 
    gtk_main();
601
 
    return 0;
602
 
}