remove properly resurrect gnome-font-viewer and gnome-thumbnail-font from

2008-10-15  Davyd Madeley  <davyd@madeley.id.au>

        * vfs-methods/: remove properly
        * font-viewer/: resurrect gnome-font-viewer and gnome-thumbnail-font
          from revision 8786 (not yet added to toplevel Makefile)

svn path=/trunk/; revision=9066
This commit is contained in:
Davyd Madeley 2008-10-15 14:46:43 +00:00 committed by Davyd Madeley
parent 61d2cbfcba
commit a6e07cf5f6
8 changed files with 1192 additions and 1 deletions

View file

@ -1,3 +1,9 @@
2008-10-15 Davyd Madeley <davyd@madeley.id.au>
* vfs-methods/: remove properly
* font-viewer/: resurrect gnome-font-viewer and gnome-thumbnail-font
from revision 8786 (not yet added to toplevel Makefile)
2008-09-24 Vincent Untz <vuntz@gnome.org>
* configure.in: post-release bump to 2.24.1.

47
font-viewer/Makefile.am Normal file
View file

@ -0,0 +1,47 @@
INCLUDES = $(FONT_METHOD_CFLAGS) $(FONT_THUMBNAILER_CFLAGS) $(FONT_VIEW_CFLAGS) \
$(FONT_CONTEXT_MENU_CFLAGS) -DDIRECTORY_DIR=\"$(directorydir)\" \
-DGNOMELOCALEDIR=\"$(datadir)/locale\"
bin_PROGRAMS = gnome-thumbnail-font gnome-font-viewer
gnome_thumbnail_font_LDADD = $(FONT_THUMBNAILER_LIBS)
gnome_thumbnail_font_SOURCES = ftstream-vfs.c font-thumbnailer.c
gnome_font_viewer_LDADD = $(FONT_VIEW_LIBS)
gnome_font_viewer_SOURCES = ftstream-vfs.c font-view.c
schemasdir = $(GCONF_SCHEMA_FILE_DIR)
schemas_DATA = fontilus.schemas
desktopdir = $(datadir)/applications
desktop_in_files = gnome-font-viewer.desktop.in
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
install-data-local: install-gconf-schemas install-desktop-database
if GCONF_SCHEMAS_INSTALL
install-gconf-schemas:
if test -z "$(DESTDIR)"; then \
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule fontilus.schemas; \
fi
else
install-gconf-schemas:
endif
install-desktop-database: install-desktopDATA
update-desktop-database $(DESTDIR)$(desktopdir)
uninstall-local:
rm -f $(DESTDIR)$(desktopdir)/mimeinfo.cache
@INTLTOOL_DESKTOP_RULE@
@INTLTOOL_DIRECTORY_RULE@
@INTLTOOL_SCHEMAS_RULE@
CLEANFILES = $(desktop_in_files) $(desktop_DATA) \
$(schemas_DATA) $(directory_DATA)
EXTRA_DIST = \
fontilus.schemas.in \
gnome-font-viewer.desktop.in.in

View file

@ -0,0 +1,390 @@
/* -*- mode: C; c-basic-offset: 4 -*-
* fontilus - a collection of font utilities for GNOME
* Copyright (C) 2002-2003 James Henstridge <james@daa.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <locale.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include <libgnomevfs/gnome-vfs.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib/gi18n.h>
static const gchar *
get_ft_error(FT_Error error)
{
#undef __FTERRORS_H__
#define FT_ERRORDEF(e,v,s) case e: return s;
#define FT_ERROR_START_LIST
#define FT_ERROR_END_LIST
switch (error) {
#include FT_ERRORS_H
default:
return "unknown";
}
}
#define FONT_SIZE 64
#define PAD_PIXELS 4
FT_Error FT_New_Face_From_URI(FT_Library library,
const gchar *uri,
FT_Long face_index,
FT_Face *aface);
static void
draw_bitmap(GdkPixbuf *pixbuf, FT_Bitmap *bitmap, gint off_x, gint off_y)
{
guchar *buffer;
gint p_width, p_height, p_rowstride;
gint i, j;
buffer = gdk_pixbuf_get_pixels(pixbuf);
p_width = gdk_pixbuf_get_width(pixbuf);
p_height = gdk_pixbuf_get_height(pixbuf);
p_rowstride = gdk_pixbuf_get_rowstride(pixbuf);
for (j = 0; j < bitmap->rows; j++) {
if (j + off_y < 0 || j + off_y >= p_height)
continue;
for (i = 0; i < bitmap->width; i++) {
guchar pixel;
gint pos;
if (i + off_x < 0 || i + off_x >= p_width)
continue;
switch (bitmap->pixel_mode) {
case ft_pixel_mode_mono:
pixel = bitmap->buffer[j * bitmap->pitch + i/8];
pixel = 255 - ((pixel >> (7 - i % 8)) & 0x1) * 255;
break;
case ft_pixel_mode_grays:
pixel = 255 - bitmap->buffer[j*bitmap->pitch + i];
break;
default:
pixel = 255;
}
pos = (j + off_y) * p_rowstride + 3 * (i + off_x);
buffer[pos] = pixel;
buffer[pos+1] = pixel;
buffer[pos+2] = pixel;
}
}
}
static void
draw_char(GdkPixbuf *pixbuf, FT_Face face, FT_UInt glyph_index,
gint *pen_x, gint *pen_y)
{
FT_Error error;
FT_GlyphSlot slot;
slot = face->glyph;
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
if (error) {
g_printerr("could not load glyph index '%ud': %s\n", glyph_index,
get_ft_error(error));
return;
}
error = FT_Render_Glyph(slot, ft_render_mode_normal);
if (error) {
g_printerr("could not render glyph index '%ud': %s\n", glyph_index,
get_ft_error(error));
return;
}
draw_bitmap(pixbuf, &slot->bitmap,
*pen_x + slot->bitmap_left,
*pen_y - slot->bitmap_top);
*pen_x += slot->advance.x >> 6;
}
static void
save_pixbuf(GdkPixbuf *pixbuf, gchar *filename)
{
guchar *buffer;
gint p_width, p_height, p_rowstride;
gint i, j;
gint trim_left, trim_right, trim_top, trim_bottom;
GdkPixbuf *subpixbuf;
buffer = gdk_pixbuf_get_pixels(pixbuf);
p_width = gdk_pixbuf_get_width(pixbuf);
p_height = gdk_pixbuf_get_height(pixbuf);
p_rowstride = gdk_pixbuf_get_rowstride(pixbuf);
for (i = 0; i < p_width; i++) {
gboolean seen_pixel = FALSE;
for (j = 0; j < p_height; j++) {
gint offset = j * p_rowstride + 3*i;
seen_pixel = (buffer[offset] != 0xff ||
buffer[offset+1] != 0xff ||
buffer[offset+2] != 0xff);
if (seen_pixel)
break;
}
if (seen_pixel)
break;
}
trim_left = MIN(p_width, i);
trim_left = MAX(trim_left - PAD_PIXELS, 0);
for (i = p_width-1; i >= trim_left; i--) {
gboolean seen_pixel = FALSE;
for (j = 0; j < p_height; j++) {
gint offset = j * p_rowstride + 3*i;
seen_pixel = (buffer[offset] != 0xff ||
buffer[offset+1] != 0xff ||
buffer[offset+2] != 0xff);
if (seen_pixel)
break;
}
if (seen_pixel)
break;
}
trim_right = MAX(trim_left, i);
trim_right = MIN(trim_right + PAD_PIXELS, p_width-1);
for (j = 0; j < p_height; j++) {
gboolean seen_pixel = FALSE;
for (i = 0; i < p_width; i++) {
gint offset = j * p_rowstride + 3*i;
seen_pixel = (buffer[offset] != 0xff ||
buffer[offset+1] != 0xff ||
buffer[offset+2] != 0xff);
if (seen_pixel)
break;
}
if (seen_pixel)
break;
}
trim_top = MIN(p_height, j);
trim_top = MAX(trim_top - PAD_PIXELS, 0);
for (j = p_height-1; j >= trim_top; j--) {
gboolean seen_pixel = FALSE;
for (i = 0; i < p_width; i++) {
gint offset = j * p_rowstride + 3*i;
seen_pixel = (buffer[offset] != 0xff ||
buffer[offset+1] != 0xff ||
buffer[offset+2] != 0xff);
if (seen_pixel)
break;
}
if (seen_pixel)
break;
}
trim_bottom = MAX(trim_top, j);
trim_bottom = MIN(trim_bottom + PAD_PIXELS, p_height-1);
subpixbuf = gdk_pixbuf_new_subpixbuf(pixbuf, trim_left, trim_top,
trim_right - trim_left,
trim_bottom - trim_top);
gdk_pixbuf_save(subpixbuf, filename, "png", NULL, NULL);
gdk_pixbuf_unref(subpixbuf);
}
int
main(int argc, char **argv)
{
FT_Error error;
FT_Library library;
FT_Face face;
FT_UInt glyph_index1, glyph_index2;
gchar *uri;
GdkPixbuf *pixbuf;
guchar *buffer;
gint i, len, pen_x, pen_y;
gunichar *thumbstr = NULL;
glong thumbstr_len = 2;
gint font_size = FONT_SIZE;
gchar *thumbstr_utf8 = NULL;
gchar **arguments = NULL;
GOptionContext *context;
GError *gerror = NULL;
gboolean retval, default_thumbstr = TRUE;
gint rv = 1;
const GOptionEntry options[] = {
{ "text", 't', 0, G_OPTION_ARG_STRING, &thumbstr_utf8,
N_("Text to thumbnail (default: Aa)"), N_("TEXT") },
{ "size", 's', 0, G_OPTION_ARG_INT, &font_size,
N_("Font size (default: 64)"), N_("SIZE") },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &arguments,
NULL, N_("FONT-FILE OUTPUT-FILE") },
{ NULL }
};
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
setlocale (LC_ALL, "");
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
retval = g_option_context_parse (context, &argc, &argv, &gerror);
g_option_context_free (context);
if (!retval) {
g_printerr (_("Error parsing arguments: %s\n"), gerror->message);
g_error_free (gerror);
return 1;
}
if (!arguments || g_strv_length (arguments) != 2) {
/* FIXME: once glib bug 336089 is fixed, use print_help here instead! */
g_printerr("usage: %s [--text TEXT] [--size SIZE] FONT-FILE OUTPUT-FILE\n", argv[0]);
goto out;
}
if (thumbstr_utf8 != NULL) {
/* build ucs4 version of string to thumbnail */
gerror = NULL;
thumbstr = g_utf8_to_ucs4 (thumbstr_utf8, strlen (thumbstr_utf8),
NULL, &thumbstr_len, &gerror);
default_thumbstr = FALSE;
/* Not sure this can really happen... */
if (gerror != NULL) {
g_printerr("Failed to convert: %s\n", gerror->message);
g_error_free (gerror);
goto out;
}
}
if (!gnome_vfs_init()) {
g_printerr("could not initialise gnome-vfs\n");
goto out;
}
error = FT_Init_FreeType(&library);
if (error) {
g_printerr("could not initialise freetype: %s\n", get_ft_error(error));
goto out;
}
uri = gnome_vfs_make_uri_from_shell_arg (arguments[0]);
error = FT_New_Face_From_URI(library, uri, 0, &face);
if (error) {
g_printerr("could not load face '%s': %s\n", uri,
get_ft_error(error));
g_free (uri);
goto out;
}
g_free (uri);
error = FT_Set_Pixel_Sizes(face, 0, font_size);
if (error) {
g_printerr("could not set pixel size: %s\n", get_ft_error(error));
/* goto out; */
}
for (i = 0; i < face->num_charmaps; i++) {
if (face->charmaps[i]->encoding == ft_encoding_latin_1 ||
face->charmaps[i]->encoding == ft_encoding_unicode ||
face->charmaps[i]->encoding == ft_encoding_apple_roman) {
error = FT_Set_Charmap(face, face->charmaps[i]);
if (error) {
g_printerr("could not set charmap: %s\n", get_ft_error(error));
/* goto out; */
}
break;
}
}
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
font_size*3*thumbstr_len/2, font_size*1.5);
if (!pixbuf) {
g_printerr("could not create pixbuf\n");
goto out;
}
buffer = gdk_pixbuf_get_pixels(pixbuf);
len = gdk_pixbuf_get_rowstride(pixbuf) * gdk_pixbuf_get_height(pixbuf);
for (i = 0; i < len; i++)
buffer[i] = 255;
pen_x = font_size/2;
pen_y = font_size;
if (default_thumbstr) {
glyph_index1 = FT_Get_Char_Index (face, 'A');
glyph_index2 = FT_Get_Char_Index (face, 'a');
/* if the glyphs for those letters don't exist, pick some other
* glyphs. */
if (glyph_index1 == 0) glyph_index1 = MIN (65, face->num_glyphs-1);
if (glyph_index2 == 0) glyph_index2 = MIN (97, face->num_glyphs-1);
draw_char(pixbuf, face, glyph_index1, &pen_x, &pen_y);
draw_char(pixbuf, face, glyph_index2, &pen_x, &pen_y);
}
else {
gunichar *p = thumbstr;
FT_Select_Charmap (face, FT_ENCODING_UNICODE);
i = 0;
while (i < thumbstr_len) {
glyph_index1 = FT_Get_Char_Index (face, *p);
draw_char(pixbuf, face, glyph_index1, &pen_x, &pen_y);
i++;
p++;
}
}
save_pixbuf(pixbuf, arguments[1]);
g_object_unref(pixbuf);
/* freeing the face causes a crash I haven't tracked down yet */
error = FT_Done_Face(face);
if (error) {
g_printerr("could not unload face: %s\n", get_ft_error(error));
goto out;
}
error = FT_Done_FreeType(library);
if (error) {
g_printerr("could not finalise freetype library: %s\n",
get_ft_error(error));
goto out;
}
rv = 0; /* success */
out:
g_strfreev (arguments);
g_free (thumbstr);
g_free (thumbstr_utf8);
return rv;
}

483
font-viewer/font-view.c Normal file
View file

@ -0,0 +1,483 @@
/* -*- mode: C; c-basic-offset: 4 -*-
* fontilus - a collection of font utilities for GNOME
* Copyright (C) 2002-2003 James Henstridge <james@daa.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TYPE1_TABLES_H
#include FT_SFNT_NAMES_H
#include FT_TRUETYPE_IDS_H
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
#include <libgnomeui/gnome-icon-lookup.h>
FT_Error FT_New_Face_From_URI(FT_Library library,
const gchar *uri,
FT_Long face_index,
FT_Face *aface);
static const gchar lowercase_text[] = "abcdefghijklmnopqrstuvwxyz";
static const gchar uppercase_text[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const gchar punctuation_text[] = "0123456789.:,;(*!?')";
static inline XftFont *
get_font(Display *xdisplay, FT_Face face, gint size, FcCharSet *charset)
{
FcPattern *pattern;
XftFont *font;
int screen = DefaultScreen (xdisplay);
pattern = FcPatternBuild(NULL,
FC_FT_FACE, FcTypeFTFace, face,
FC_PIXEL_SIZE, FcTypeDouble, (double)size,
NULL);
if (charset)
FcPatternAddCharSet (pattern, "charset", charset);
FcConfigSubstitute (NULL, pattern, FcMatchPattern);
XftDefaultSubstitute (xdisplay, screen, pattern);
font = XftFontOpenPattern(xdisplay, pattern);
return font;
}
static inline void
draw_string(Display *xdisplay, XftDraw *draw, XftFont *font, XftColor *colour,
const gchar *text, gint *pos_y)
{
XGlyphInfo extents;
gint len = strlen(text);
XftTextExtentsUtf8(xdisplay, font, text, len, &extents);
XftDrawStringUtf8(draw, colour, font, 4, *pos_y + extents.y, text, len);
*pos_y += extents.height + 4;
}
static gboolean
check_font_contain_text (FT_Face face, gchar *text)
{
while (text && *text)
{
gunichar wc = g_utf8_get_char (text);
if (!FT_Get_Char_Index (face, wc))
return FALSE;
text = g_utf8_next_char (text);
}
return TRUE;
}
static GdkPixmap *
create_text_pixmap(GtkWidget *drawing_area, FT_Face face)
{
gint i, pixmap_width, pixmap_height, pos_y, textlen;
GdkPixmap *pixmap = NULL;
gchar *text;
Display *xdisplay;
Drawable xdrawable;
Visual *xvisual;
Colormap xcolormap;
XftDraw *draw;
XftColor colour;
XGlyphInfo extents;
XftFont *font;
gint *sizes = NULL, n_sizes, alpha_size;
FcCharSet *charset = NULL;
text = _("The quick brown fox jumps over the lazy dog. 0123456789");
if (! check_font_contain_text (face, text))
{
text = "The quick brown fox jumps over the lazy dog. 0123456789";
}
textlen = strlen(text);
/* create pixmap */
gtk_widget_realize(drawing_area);
/* create the XftDraw */
xdisplay = GDK_PIXMAP_XDISPLAY(drawing_area->window);
xvisual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(drawing_area->window));
xcolormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(drawing_area->window));
XftColorAllocName(xdisplay, xvisual, xcolormap, "black", &colour);
/* work out what sizes to render */
if (FT_IS_SCALABLE(face)) {
n_sizes = 8;
sizes = g_new(gint, n_sizes);
sizes[0] = 8;
sizes[1] = 10;
sizes[2] = 12;
sizes[3] = 18;
sizes[4] = 24;
sizes[5] = 36;
sizes[6] = 48;
sizes[7] = 72;
alpha_size = 24;
} else {
/* use fixed sizes */
n_sizes = face->num_fixed_sizes;
sizes = g_new(gint, n_sizes);
alpha_size = 0;
for (i = 0; i < face->num_fixed_sizes; i++) {
sizes[i] = face->available_sizes[i].height;
/* work out which font size to render */
if (face->available_sizes[i].height <= 24)
alpha_size = face->available_sizes[i].height;
}
}
/* calculate size of pixmap to use (with 4 pixels padding) ... */
pixmap_width = 8;
pixmap_height = 8;
font = get_font(xdisplay, face, alpha_size, charset);
charset = FcCharSetCopy (font->charset);
XftTextExtentsUtf8(xdisplay, font,
lowercase_text, strlen(lowercase_text), &extents);
pixmap_height += extents.height + 4;
pixmap_width = MAX(pixmap_width, 8 + extents.width);
XftTextExtentsUtf8(xdisplay, font,
uppercase_text, strlen(uppercase_text), &extents);
pixmap_height += extents.height + 4;
pixmap_width = MAX(pixmap_width, 8 + extents.width);
XftTextExtentsUtf8(xdisplay, font,
punctuation_text, strlen(punctuation_text), &extents);
pixmap_height += extents.height + 4;
pixmap_width = MAX(pixmap_width, 8 + extents.width);
XftFontClose(xdisplay, font);
pixmap_height += 8;
for (i = 0; i < n_sizes; i++) {
font = get_font(xdisplay, face, sizes[i], charset);
if (!font) continue;
XftTextExtentsUtf8(xdisplay, font, text, textlen, &extents);
pixmap_height += extents.height + 4;
pixmap_width = MAX(pixmap_width, 8 + extents.width);
XftFontClose(xdisplay, font);
}
/* create pixmap */
gtk_widget_set_size_request(drawing_area, pixmap_width, pixmap_height);
pixmap = gdk_pixmap_new(drawing_area->window,
pixmap_width, pixmap_height, -1);
if (!pixmap)
goto end;
gdk_draw_rectangle(pixmap, drawing_area->style->white_gc,
TRUE, 0, 0, pixmap_width, pixmap_height);
xdrawable = GDK_DRAWABLE_XID(pixmap);
draw = XftDrawCreate(xdisplay, xdrawable, xvisual, xcolormap);
/* draw text */
pos_y = 4;
font = get_font(xdisplay, face, alpha_size, charset);
draw_string(xdisplay, draw, font, &colour, lowercase_text, &pos_y);
draw_string(xdisplay, draw, font, &colour, uppercase_text, &pos_y);
draw_string(xdisplay, draw, font, &colour, punctuation_text, &pos_y);
XftFontClose(xdisplay, font);
pos_y += 8;
for (i = 0; i < n_sizes; i++) {
font = get_font(xdisplay, face, sizes[i], charset);
if (!font) continue;
draw_string(xdisplay, draw, font, &colour, text, &pos_y);
XftFontClose(xdisplay, font);
}
end:
g_free(sizes);
FcCharSetDestroy (charset);
return pixmap;
}
static void
add_row(GtkWidget *table, gint *row_p,
const gchar *name, const gchar *value, gboolean multiline)
{
gchar *bold_name;
GtkWidget *name_w, *value_w;
bold_name = g_strconcat("<b>", name, "</b>", NULL);
name_w = gtk_label_new(bold_name);
g_free(bold_name);
gtk_misc_set_alignment(GTK_MISC(name_w), 1.0, 0.0);
gtk_label_set_use_markup(GTK_LABEL(name_w), TRUE);
if (multiline) {
GtkWidget *textview;
GtkTextBuffer *buffer;
textview = gtk_text_view_new();
gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview), FALSE);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
gtk_text_buffer_set_text(buffer, value, -1);
value_w = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(value_w),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(value_w),
GTK_SHADOW_IN);
gtk_widget_set_size_request(value_w, -1, 50);
gtk_container_add(GTK_CONTAINER(value_w), textview);
} else {
value_w = gtk_label_new(value);
gtk_misc_set_alignment(GTK_MISC(value_w), 0.0, 0.5);
gtk_label_set_selectable(GTK_LABEL(value_w), TRUE);
}
gtk_table_attach(GTK_TABLE(table), name_w, 0, 1, *row_p, *row_p + 1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach(GTK_TABLE(table), value_w, 1, 2, *row_p, *row_p + 1,
GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
(*row_p)++;
}
static void
add_face_info(GtkWidget *table, gint *row_p, const gchar *uri, FT_Face face)
{
GnomeVFSFileInfo *file_info;
GnomeVFSResult res;
PS_FontInfoRec ps_info;
add_row(table, row_p, _("Name:"), face->family_name, FALSE);
if (face->style_name)
add_row(table, row_p, _("Style:"), face->style_name, FALSE);
file_info = gnome_vfs_file_info_new();
res = gnome_vfs_get_file_info(uri, file_info,
GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
if (res == GNOME_VFS_OK) {
if ((file_info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE)!=0){
const gchar *type = gnome_vfs_mime_get_description(file_info->mime_type);
add_row(table, row_p, _("Type:"),
type ? type : file_info->mime_type, FALSE);
}
if ((file_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) != 0) {
gchar *size;
size = gnome_vfs_format_file_size_for_display(file_info->size);
add_row(table, row_p, _("Size:"), size, FALSE);
g_free(size);
}
}
gnome_vfs_file_info_unref(file_info);
if (FT_IS_SFNT(face)) {
gint i, len;
gchar *version = NULL, *copyright = NULL, *description = NULL;
len = FT_Get_Sfnt_Name_Count(face);
for (i = 0; i < len; i++) {
FT_SfntName sname;
if (FT_Get_Sfnt_Name(face, i, &sname) != 0)
continue;
/* only handle the unicode names for US langid */
if (!(sname.platform_id == TT_PLATFORM_MICROSOFT &&
sname.encoding_id == TT_MS_ID_UNICODE_CS &&
sname.language_id == TT_MS_LANGID_ENGLISH_UNITED_STATES))
continue;
switch (sname.name_id) {
case TT_NAME_ID_COPYRIGHT:
g_free(copyright);
copyright = g_convert(sname.string, sname.string_len,
"UTF-8", "UTF-16BE", NULL, NULL, NULL);
break;
case TT_NAME_ID_VERSION_STRING:
g_free(version);
version = g_convert(sname.string, sname.string_len,
"UTF-8", "UTF-16BE", NULL, NULL, NULL);
break;
case TT_NAME_ID_DESCRIPTION:
g_free(description);
description = g_convert(sname.string, sname.string_len,
"UTF-8", "UTF-16BE", NULL, NULL, NULL);
break;
default:
break;
}
}
if (version) {
add_row(table, row_p, _("Version:"), version, FALSE);
g_free(version);
}
if (copyright) {
add_row(table, row_p, _("Copyright:"), copyright, TRUE);
g_free(copyright);
}
if (description) {
add_row(table, row_p, _("Description:"), description, TRUE);
g_free(description);
}
} else if (FT_Get_PS_Font_Info(face, &ps_info) == 0) {
if (ps_info.version && g_utf8_validate(ps_info.version, -1, NULL))
add_row(table, row_p, _("Version:"), ps_info.version, FALSE);
if (ps_info.notice && g_utf8_validate(ps_info.notice, -1, NULL))
add_row(table, row_p, _("Copyright:"), ps_info.notice, TRUE);
}
}
static gboolean
expose_event(GtkWidget *widget, GdkEventExpose *event, GdkPixmap *pixmap)
{
gdk_draw_drawable(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
static void
set_icon(GtkWindow *window, const gchar *uri)
{
GdkScreen *screen;
GtkIconTheme *icon_theme;
gchar *icon_name = NULL;
screen = gtk_widget_get_screen (GTK_WIDGET (window));
icon_theme = gtk_icon_theme_get_for_screen (screen);
icon_name = gnome_icon_lookup_sync(icon_theme, NULL, uri, NULL,
GNOME_ICON_LOOKUP_FLAGS_NONE, NULL);
if (!icon_name) goto end;
gtk_window_set_icon_name (window, icon_name);
end:
g_free(icon_name);
}
int
main(int argc, char **argv)
{
FT_Error error;
FT_Library library;
FT_Face face;
gchar *font_file, *title;
gint row;
GtkWidget *window, *vbox, *table, *swin, *drawing_area;
GdkPixmap *pixmap;
GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);
gtk_init(&argc, &argv);
if (argc != 2) {
g_printerr(_("usage: %s fontfile\n"), argv[0]);
return 1;
}
if (!gnome_vfs_init()) {
g_printerr("could not initialise gnome-vfs\n");
return 1;
}
if (!XftInitFtLibrary()) {
g_printerr("could not initialise freetype library\n");
return 1;
}
error = FT_Init_FreeType(&library);
if (error) {
g_printerr("could not initialise freetype\n");
return 1;
}
font_file = gnome_vfs_make_uri_from_shell_arg (argv[1]);
if (!font_file) {
g_printerr("could not parse argument into a URI\n");
return 1;
}
error = FT_New_Face_From_URI(library, font_file, 0, &face);
if (error) {
g_printerr("could not load face '%s'\n", font_file);
return 1;
}
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
title = g_strconcat(face->family_name,
face->style_name ? ", " : "",
face->style_name, NULL);
gtk_window_set_title(GTK_WINDOW(window), title);
set_icon(GTK_WINDOW(window), font_file);
g_free(title);
gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
table = gtk_table_new(1, 2, FALSE);
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, TRUE, 0);
row = 0;
add_face_info(table, &row, font_file, face);
gtk_table_set_col_spacings(GTK_TABLE(table), 8);
gtk_table_set_row_spacings(GTK_TABLE(table), 2);
swin = gtk_scrolled_window_new(NULL, NULL);
gtk_widget_set_size_request(swin, 500, 200);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
drawing_area = gtk_drawing_area_new();
gtk_widget_modify_bg(drawing_area, GTK_STATE_NORMAL, &white);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin),
drawing_area);
pixmap = create_text_pixmap(drawing_area, face);
g_signal_connect(drawing_area, "expose_event",
G_CALLBACK(expose_event), pixmap);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}

View file

@ -0,0 +1,109 @@
<?xml version="1.0"?>
<gconfschemafile>
<schemalist>
<schema>
<key>/schemas/desktop/gnome/thumbnailers/application@x-font-ttf/command</key>
<applyto>/desktop/gnome/thumbnailers/application@x-font-ttf/command</applyto>
<type>string</type>
<default>gnome-thumbnail-font %u %o</default>
<locale name="C">
<short>Thumbnail command for TrueType fonts</short>
<long>
Set this key to the command used to create thumbnails for
TrueType fonts.
</long>
</locale>
</schema>
<schema>
<key>/schemas/desktop/gnome/thumbnailers/application@x-font-ttf/enable</key>
<applyto>/desktop/gnome/thumbnailers/application@x-font-ttf/enable</applyto>
<type>bool</type>
<default>true</default>
<locale name="C">
<short>Whether to thumbnail TrueType fonts</short>
<long>
If set to true, then TrueType fonts will be thumbnailed.
</long>
</locale>
</schema>
<schema>
<key>/schemas/desktop/gnome/thumbnailers/application@x-font-type1/command</key>
<applyto>/desktop/gnome/thumbnailers/application@x-font-type1/command</applyto>
<type>string</type>
<default>gnome-thumbnail-font %u %o</default>
<locale name="C">
<short>Thumbnail command for Type1 fonts</short>
<long>
Set this key to the command used to create thumbnails for
Type1 fonts.
</long>
</locale>
</schema>
<schema>
<key>/schemas/desktop/gnome/thumbnailers/application@x-font-type1/enable</key>
<applyto>/desktop/gnome/thumbnailers/application@x-font-type1/enable</applyto>
<type>bool</type>
<default>true</default>
<locale name="C">
<short>Whether to thumbnail Type1 fonts</short>
<long>
If set to true, then Type1 fonts will be thumbnailed.
</long>
</locale>
</schema>
<schema>
<key>/schemas/desktop/gnome/thumbnailers/application@x-font-pcf/command</key>
<applyto>/desktop/gnome/thumbnailers/application@x-font-pcf/command</applyto>
<type>string</type>
<default>gnome-thumbnail-font %u %o</default>
<locale name="C">
<short>Thumbnail command for PCF fonts</short>
<long>
Set this key to the command used to create thumbnails for
PCF fonts.
</long>
</locale>
</schema>
<schema>
<key>/schemas/desktop/gnome/thumbnailers/application@x-font-pcf/enable</key>
<applyto>/desktop/gnome/thumbnailers/application@x-font-pcf/enable</applyto>
<type>bool</type>
<default>true</default>
<locale name="C">
<short>Whether to thumbnail PCF fonts</short>
<long>
If set to true, then PCF fonts will be thumbnailed.
</long>
</locale>
</schema>
<schema>
<key>/schemas/desktop/gnome/thumbnailers/application@x-font-otf/command</key>
<applyto>/desktop/gnome/thumbnailers/application@x-font-otf/command</applyto>
<type>string</type>
<default>gnome-thumbnail-font %u %o</default>
<locale name="C">
<short>Thumbnail command for OpenType fonts</short>
<long>
Set this key to the command used to create thumbnails for
OpenType fonts.
</long>
</locale>
</schema>
<schema>
<key>/schemas/desktop/gnome/thumbnailers/application@x-font-otf/enable</key>
<applyto>/desktop/gnome/thumbnailers/application@x-font-otf/enable</applyto>
<type>bool</type>
<default>true</default>
<locale name="C">
<short>Whether to thumbnail OpenType fonts</short>
<long>
If set to true, then OpenType fonts will be thumbnailed.
</long>
</locale>
</schema>
</schemalist>
</gconfschemafile>

143
font-viewer/ftstream-vfs.c Normal file
View file

@ -0,0 +1,143 @@
/* -*- mode: C; c-basic-offset: 4 -*-
* fontilus - a collection of font utilities for GNOME
* Copyright (C) 2002-2003 James Henstridge <james@daa.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include <libgnomevfs/gnome-vfs.h>
static unsigned long
vfs_stream_read(FT_Stream stream,
unsigned long offset,
unsigned char *buffer,
unsigned long count)
{
GnomeVFSHandle *handle = (GnomeVFSHandle *)stream->descriptor.pointer;
GnomeVFSFileSize bytes_read = 0;
if (gnome_vfs_seek(handle, GNOME_VFS_SEEK_START, offset) != GNOME_VFS_OK)
return 0;
if (count > 0) {
if (gnome_vfs_read(handle, buffer, count, &bytes_read) != GNOME_VFS_OK)
return 0;
}
return bytes_read;
}
static void
vfs_stream_close(FT_Stream stream)
{
GnomeVFSHandle *handle = (GnomeVFSHandle *)stream->descriptor.pointer;
if (!handle)
return;
gnome_vfs_close(handle);
stream->descriptor.pointer = NULL;
stream->size = 0;
stream->base = NULL;
}
static FT_Error
vfs_stream_open(FT_Stream stream,
const char *uri)
{
GnomeVFSHandle *handle;
GnomeVFSFileInfo *finfo;
if (!stream)
return FT_Err_Invalid_Stream_Handle;
if (gnome_vfs_open(&handle, uri,
GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM) != GNOME_VFS_OK) {
g_message("could not open URI");
return FT_Err_Cannot_Open_Resource;
}
finfo = gnome_vfs_file_info_new();
if (gnome_vfs_get_file_info_from_handle(handle, finfo,0) != GNOME_VFS_OK) {
g_warning("could not get file info");
gnome_vfs_file_info_unref(finfo);
gnome_vfs_close(handle);
return FT_Err_Cannot_Open_Resource;
}
if ((finfo->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) == 0) {
g_warning("file info did not include file size");
gnome_vfs_file_info_unref(finfo);
gnome_vfs_close(handle);
return FT_Err_Cannot_Open_Resource;
}
stream->size = finfo->size;
gnome_vfs_file_info_unref(finfo);
stream->descriptor.pointer = handle;
stream->pathname.pointer = NULL;
stream->pos = 0;
stream->read = vfs_stream_read;
stream->close = vfs_stream_close;
return FT_Err_Ok;
}
/* load a typeface from a URI */
FT_Error
FT_New_Face_From_URI(FT_Library library,
const gchar* uri,
FT_Long face_index,
FT_Face *aface)
{
FT_Open_Args args;
FT_Stream stream;
FT_Error error;
if ((stream = calloc(1, sizeof(*stream))) == NULL)
return FT_Err_Out_Of_Memory;
error = vfs_stream_open(stream, uri);
if (error != FT_Err_Ok) {
free(stream);
return error;
}
/* freetype-2.1.3 accidentally broke compatibility. */
#if defined(FT_OPEN_STREAM) && !defined(ft_open_stream)
# define ft_open_stream FT_OPEN_STREAM
#endif
args.flags = ft_open_stream;
args.stream = stream;
error = FT_Open_Face(library, &args, face_index, aface);
if (error != FT_Err_Ok) {
if (stream->close) stream->close(stream);
free(stream);
return error;
}
/* so that freetype will free the stream */
(*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
return error;
}

View file

@ -0,0 +1,14 @@
[Desktop Entry]
_Name=Font Viewer
_Comment=Preview fonts
Icon=gnome-settings-font
Exec=gnome-font-viewer %u
Terminal=false
Type=Application
StartupNotify=true
NoDisplay=true
MimeType=application/x-font-ttf;application/x-font-pcf;application/x-font-type1;application/x-font-otf;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-control-center
X-GNOME-Bugzilla-Component=font properties
X-GNOME-Bugzilla-Version=@VERSION@

View file

@ -1 +0,0 @@
SUBDIRS = $(FONTILUS)