Drop font-viewer
Will be moved to another module
This commit is contained in:
parent
f925a6a538
commit
ec8aed3b20
12 changed files with 12 additions and 1543 deletions
|
@ -1,8 +1,8 @@
|
||||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||||
|
|
||||||
SUBDIRS = po libgnome-control-center shell panels \
|
SUBDIRS = po libgnome-control-center shell panels \
|
||||||
font-viewer help docs
|
help docs
|
||||||
DIST_SUBDIRS = po font-viewer help shell typing-break docs examples panels libgnome-control-center
|
DIST_SUBDIRS = po help shell typing-break docs examples panels libgnome-control-center
|
||||||
|
|
||||||
if HAVE_TYPING_BREAK
|
if HAVE_TYPING_BREAK
|
||||||
SUBDIRS += typing-break
|
SUBDIRS += typing-break
|
||||||
|
|
|
@ -151,7 +151,6 @@ if $PKG_CONFIG --exists xft ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PKG_CHECK_MODULES(FONT_CAPPLET, $COMMON_MODULES $xft_modules)
|
PKG_CHECK_MODULES(FONT_CAPPLET, $COMMON_MODULES $xft_modules)
|
||||||
PKG_CHECK_MODULES(FONT_VIEWER, $COMMON_MODULES $xft_modules)
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES(AT_CAPPLET, $COMMON_MODULES)
|
PKG_CHECK_MODULES(AT_CAPPLET, $COMMON_MODULES)
|
||||||
|
|
||||||
|
@ -344,8 +343,6 @@ docs/reference/libgnome-control-center/Makefile
|
||||||
docs/reference/libgnome-control-center/version.xml
|
docs/reference/libgnome-control-center/version.xml
|
||||||
examples/Makefile
|
examples/Makefile
|
||||||
examples/gnome-example-panel.desktop.in
|
examples/gnome-example-panel.desktop.in
|
||||||
font-viewer/Makefile
|
|
||||||
font-viewer/gnome-font-viewer.desktop.in
|
|
||||||
help/Makefile
|
help/Makefile
|
||||||
libgnome-control-center/Makefile
|
libgnome-control-center/Makefile
|
||||||
libgnome-control-center/libgnome-control-center.pc
|
libgnome-control-center/libgnome-control-center.pc
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
|
|
||||||
INCLUDES = $(FONT_VIEWER_CFLAGS) $(GNOMECC_CAPPLETS_CFLAGS) -DDIRECTORY_DIR=\"$(directorydir)\" \
|
|
||||||
-DGNOMELOCALEDIR=\"$(datadir)/locale\"
|
|
||||||
|
|
||||||
bin_PROGRAMS = gnome-thumbnail-font gnome-font-viewer
|
|
||||||
|
|
||||||
gnome_thumbnail_font_LDADD = $(GNOMECC_CAPPLETS_LIBS) $(FONT_VIEWER_LIBS)
|
|
||||||
gnome_thumbnail_font_SOURCES = ftstream-vfs.c ftstream-vfs.h font-thumbnailer.c totem-resources.c totem-resources.h
|
|
||||||
|
|
||||||
gnome_font_viewer_LDADD = $(GNOMECC_CAPPLETS_LIBS) $(FONT_VIEWER_LIBS)
|
|
||||||
gnome_font_viewer_SOURCES = ftstream-vfs.c ftstream-vfs.h 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
|
|
||||||
|
|
||||||
-include $(top_srcdir)/git.mk
|
|
|
@ -1,399 +0,0 @@
|
||||||
/* -*- 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 <gdk-pixbuf/gdk-pixbuf.h>
|
|
||||||
|
|
||||||
#include <gio/gio.h>
|
|
||||||
#include <glib/gi18n.h>
|
|
||||||
|
|
||||||
#include "totem-resources.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);
|
|
||||||
g_object_unref(subpixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
FT_Error error;
|
|
||||||
FT_Library library;
|
|
||||||
FT_Face face;
|
|
||||||
FT_UInt glyph_index1, glyph_index2;
|
|
||||||
GFile *file;
|
|
||||||
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, "");
|
|
||||||
|
|
||||||
g_type_init ();
|
|
||||||
g_thread_init (NULL);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
error = FT_Init_FreeType(&library);
|
|
||||||
if (error) {
|
|
||||||
g_printerr("could not initialise freetype: %s\n", get_ft_error(error));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
totem_resources_monitor_start (arguments[0], 30 * G_USEC_PER_SEC);
|
|
||||||
|
|
||||||
file = g_file_new_for_commandline_arg (arguments[0]);
|
|
||||||
uri = g_file_get_uri (file);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
totem_resources_monitor_stop ();
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
|
@ -1,609 +0,0 @@
|
||||||
/* -*- 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 <gio/gio.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include <gdk/gdkx.h>
|
|
||||||
#include <glib/gi18n.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, (guchar *)text, len, &extents);
|
|
||||||
XftDrawStringUtf8(draw, colour, font, 4, *pos_y + extents.y, (guchar *)text, len);
|
|
||||||
*pos_y += extents.height + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
check_font_contain_text (FT_Face face, const 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 gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, GdkPixmap *pixmap);
|
|
||||||
|
|
||||||
static GdkPixmap *
|
|
||||||
create_text_pixmap(GtkWidget *drawing_area, FT_Face face)
|
|
||||||
{
|
|
||||||
gint i, pixmap_width, pixmap_height, pos_y, textlen;
|
|
||||||
GdkPixmap *pixmap = NULL;
|
|
||||||
const 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;
|
|
||||||
cairo_t *cr;
|
|
||||||
GdkWindow *window = gtk_widget_get_window (drawing_area);
|
|
||||||
|
|
||||||
text = pango_language_get_sample_string(NULL);
|
|
||||||
if (! check_font_contain_text (face, text))
|
|
||||||
{
|
|
||||||
pango_language_get_sample_string (pango_language_from_string ("en_US"));
|
|
||||||
}
|
|
||||||
|
|
||||||
textlen = strlen(text);
|
|
||||||
|
|
||||||
/* create the XftDraw */
|
|
||||||
xdisplay = GDK_PIXMAP_XDISPLAY(window);
|
|
||||||
xvisual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(window));
|
|
||||||
xcolormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(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,
|
|
||||||
(guchar *)lowercase_text, strlen(lowercase_text), &extents);
|
|
||||||
pixmap_height += extents.height + 4;
|
|
||||||
pixmap_width = MAX(pixmap_width, 8 + extents.width);
|
|
||||||
XftTextExtentsUtf8(xdisplay, font,
|
|
||||||
(guchar *)uppercase_text, strlen(uppercase_text), &extents);
|
|
||||||
pixmap_height += extents.height + 4;
|
|
||||||
pixmap_width = MAX(pixmap_width, 8 + extents.width);
|
|
||||||
XftTextExtentsUtf8(xdisplay, font,
|
|
||||||
(guchar *)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, (guchar *)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(window,
|
|
||||||
pixmap_width, pixmap_height, -1);
|
|
||||||
if (!pixmap)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
cr = gdk_cairo_create (pixmap);
|
|
||||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
|
||||||
cairo_paint (cr);
|
|
||||||
cairo_destroy (cr);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_signal_connect(drawing_area, "expose-event", G_CALLBACK(expose_event),
|
|
||||||
pixmap);
|
|
||||||
|
|
||||||
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,
|
|
||||||
gboolean expand)
|
|
||||||
{
|
|
||||||
gchar *bold_name;
|
|
||||||
GtkWidget *name_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), 0.0, 0.0);
|
|
||||||
gtk_label_set_use_markup(GTK_LABEL(name_w), TRUE);
|
|
||||||
|
|
||||||
gtk_table_attach(GTK_TABLE(table), name_w, 0, 1, *row_p, *row_p + 1,
|
|
||||||
GTK_FILL, GTK_FILL, 0, 0);
|
|
||||||
|
|
||||||
if (multiline) {
|
|
||||||
GtkWidget *label, *viewport;
|
|
||||||
GtkScrolledWindow *swin;
|
|
||||||
guint flags;
|
|
||||||
|
|
||||||
label = gtk_label_new (value);
|
|
||||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
|
||||||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
|
||||||
gtk_widget_set_size_request (label, 200, -1);
|
|
||||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
|
|
||||||
|
|
||||||
|
|
||||||
swin = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
|
|
||||||
gtk_scrolled_window_set_policy(swin,
|
|
||||||
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
|
||||||
|
|
||||||
viewport = gtk_viewport_new (gtk_scrolled_window_get_hadjustment (swin),
|
|
||||||
gtk_scrolled_window_get_vadjustment (swin));
|
|
||||||
gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
|
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER(swin), viewport);
|
|
||||||
(*row_p)++;
|
|
||||||
if (expand)
|
|
||||||
flags = GTK_FILL|GTK_EXPAND;
|
|
||||||
else
|
|
||||||
flags = GTK_FILL;
|
|
||||||
gtk_table_attach(GTK_TABLE(table), GTK_WIDGET(swin), 0, 2, *row_p, *row_p + 1,
|
|
||||||
GTK_FILL|GTK_EXPAND, flags, 0, 0);
|
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (viewport), label);
|
|
||||||
} else {
|
|
||||||
GtkWidget *label = gtk_label_new(value);
|
|
||||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
|
|
||||||
gtk_label_set_selectable(GTK_LABEL(label), TRUE);
|
|
||||||
gtk_table_attach(GTK_TABLE(table), label, 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)
|
|
||||||
{
|
|
||||||
gchar *s;
|
|
||||||
GFile *file;
|
|
||||||
GFileInfo *info;
|
|
||||||
PS_FontInfoRec ps_info;
|
|
||||||
|
|
||||||
add_row(table, row_p, _("Name:"), face->family_name, FALSE, FALSE);
|
|
||||||
|
|
||||||
if (face->style_name)
|
|
||||||
add_row(table, row_p, _("Style:"), face->style_name, FALSE, FALSE);
|
|
||||||
|
|
||||||
file = g_file_new_for_uri (uri);
|
|
||||||
|
|
||||||
info = g_file_query_info (file,
|
|
||||||
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
|
|
||||||
G_FILE_ATTRIBUTE_STANDARD_SIZE,
|
|
||||||
G_FILE_QUERY_INFO_NONE,
|
|
||||||
NULL, NULL);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
if (info) {
|
|
||||||
s = g_content_type_get_description (g_file_info_get_content_type (info));
|
|
||||||
add_row (table, row_p, _("Type:"), s, FALSE, FALSE);
|
|
||||||
g_free (s);
|
|
||||||
|
|
||||||
s = g_format_size_for_display (g_file_info_get_size (info));
|
|
||||||
add_row (table, row_p, _("Size:"), s, FALSE, FALSE);
|
|
||||||
g_free (s);
|
|
||||||
|
|
||||||
g_object_unref (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((gchar *)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((gchar *)sname.string, sname.string_len,
|
|
||||||
"UTF-8", "UTF-16BE", NULL, NULL, NULL);
|
|
||||||
break;
|
|
||||||
case TT_NAME_ID_DESCRIPTION:
|
|
||||||
g_free(description);
|
|
||||||
description = g_convert((gchar *)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, FALSE);
|
|
||||||
g_free(version);
|
|
||||||
}
|
|
||||||
if (copyright) {
|
|
||||||
add_row(table, row_p, _("Copyright:"), copyright, TRUE, TRUE);
|
|
||||||
g_free(copyright);
|
|
||||||
}
|
|
||||||
if (description) {
|
|
||||||
add_row(table, row_p, _("Description:"), description, TRUE, 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, FALSE);
|
|
||||||
if (ps_info.notice && g_utf8_validate(ps_info.notice, -1, NULL))
|
|
||||||
add_row(table, row_p, _("Copyright:"), ps_info.notice, TRUE, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
expose_event(GtkWidget *widget, GdkEventExpose *event, GdkPixmap *pixmap)
|
|
||||||
{
|
|
||||||
cairo_t *cr;
|
|
||||||
|
|
||||||
cr = gdk_cairo_create (gtk_widget_get_window (widget));
|
|
||||||
|
|
||||||
gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0);
|
|
||||||
gdk_cairo_region (cr, event->region);
|
|
||||||
cairo_fill (cr);
|
|
||||||
|
|
||||||
cairo_destroy (cr);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_icon(GtkWindow *window, const gchar *uri)
|
|
||||||
{
|
|
||||||
GFile *file;
|
|
||||||
GIcon *icon;
|
|
||||||
GFileInfo *info;
|
|
||||||
GdkScreen *screen;
|
|
||||||
GtkIconTheme *icon_theme;
|
|
||||||
const gchar *icon_name = NULL, *content_type;
|
|
||||||
|
|
||||||
screen = gtk_widget_get_screen (GTK_WIDGET (window));
|
|
||||||
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
|
||||||
|
|
||||||
file = g_file_new_for_uri (uri);
|
|
||||||
|
|
||||||
info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
|
|
||||||
G_FILE_QUERY_INFO_NONE, NULL, NULL);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
if (! info)
|
|
||||||
return;
|
|
||||||
|
|
||||||
content_type = g_file_info_get_content_type (info);
|
|
||||||
icon = g_content_type_get_icon (content_type);
|
|
||||||
|
|
||||||
if (G_IS_THEMED_ICON (icon)) {
|
|
||||||
const gchar * const *names = NULL;
|
|
||||||
|
|
||||||
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
|
|
||||||
if (names) {
|
|
||||||
gint i;
|
|
||||||
for (i = 0; names[i]; i++) {
|
|
||||||
if (gtk_icon_theme_has_icon (icon_theme, names[i])) {
|
|
||||||
icon_name = names[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icon_name) {
|
|
||||||
gtk_window_set_icon_name (window, icon_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
font_install_finished_cb (GObject *source_object,
|
|
||||||
GAsyncResult *res,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GError *err = NULL;
|
|
||||||
|
|
||||||
g_file_copy_finish (G_FILE (source_object), res, &err);
|
|
||||||
|
|
||||||
if (!err) {
|
|
||||||
gtk_button_set_label (GTK_BUTTON (data), _("Installed"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gtk_button_set_label (GTK_BUTTON (data), _("Install Failed"));
|
|
||||||
g_debug ("Install failed: %s", err->message);
|
|
||||||
g_error_free (err);
|
|
||||||
}
|
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (data), FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
install_button_clicked_cb (GtkButton *button,
|
|
||||||
const gchar *font_file)
|
|
||||||
{
|
|
||||||
GFile *src, *dest;
|
|
||||||
gchar *dest_path, *dest_filename;
|
|
||||||
|
|
||||||
GError *err = NULL;
|
|
||||||
|
|
||||||
/* first check if ~/.fonts exists */
|
|
||||||
dest_path = g_build_filename (g_get_home_dir (), ".fonts", NULL);
|
|
||||||
if (!g_file_test (dest_path, G_FILE_TEST_EXISTS)) {
|
|
||||||
GFile *f = g_file_new_for_path (dest_path);
|
|
||||||
g_file_make_directory_with_parents (f, NULL, &err);
|
|
||||||
g_object_unref (f);
|
|
||||||
if (err) {
|
|
||||||
/* TODO: show error dialog */
|
|
||||||
g_warning ("Could not create fonts directory: %s", err->message);
|
|
||||||
g_error_free (err);
|
|
||||||
g_free (dest_path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_free (dest_path);
|
|
||||||
|
|
||||||
/* create destination filename */
|
|
||||||
src = g_file_new_for_uri (font_file);
|
|
||||||
|
|
||||||
dest_filename = g_file_get_basename (src);
|
|
||||||
dest_path = g_build_filename (g_get_home_dir (), ".fonts", dest_filename, NULL);
|
|
||||||
g_free (dest_filename);
|
|
||||||
|
|
||||||
dest = g_file_new_for_path (dest_path);
|
|
||||||
|
|
||||||
/* TODO: show error dialog if file exists */
|
|
||||||
g_file_copy_async (src, dest, G_FILE_COPY_NONE, 0, NULL, NULL, NULL,
|
|
||||||
font_install_finished_cb, button);
|
|
||||||
|
|
||||||
g_object_unref (src);
|
|
||||||
g_object_unref (dest);
|
|
||||||
g_free (dest_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
FT_Error error;
|
|
||||||
FT_Library library;
|
|
||||||
FT_Face face;
|
|
||||||
GFile *file;
|
|
||||||
gchar *font_file, *title;
|
|
||||||
gint row;
|
|
||||||
GtkWidget *window, *hbox, *table, *swin, *drawing_area;
|
|
||||||
GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
|
|
||||||
GtkWidget *button, *align;
|
|
||||||
|
|
||||||
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 (!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;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = g_file_new_for_commandline_arg (argv[1]);
|
|
||||||
font_file = g_file_get_uri (file);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
hbox = gtk_hbox_new(FALSE, 0);
|
|
||||||
gtk_container_add(GTK_CONTAINER(window), hbox);
|
|
||||||
|
|
||||||
swin = gtk_scrolled_window_new(NULL, NULL);
|
|
||||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
|
|
||||||
GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
|
|
||||||
gtk_box_pack_start(GTK_BOX(hbox), 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);
|
|
||||||
g_signal_connect (drawing_area, "realize", G_CALLBACK (create_text_pixmap), face);
|
|
||||||
|
|
||||||
/* set the minimum size on the scrolled window to prevent
|
|
||||||
* unnecessary scrolling */
|
|
||||||
gtk_widget_set_size_request(swin, 500, -1);
|
|
||||||
|
|
||||||
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
|
||||||
|
|
||||||
table = gtk_table_new(1, 2, FALSE);
|
|
||||||
gtk_container_set_border_width(GTK_CONTAINER(table), 5);
|
|
||||||
gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, TRUE, 0);
|
|
||||||
|
|
||||||
row = 0;
|
|
||||||
add_face_info(table, &row, font_file, face);
|
|
||||||
|
|
||||||
/* add install button */
|
|
||||||
align = gtk_alignment_new (1.0, 0.5, 0.0, 0.0);
|
|
||||||
gtk_table_attach (GTK_TABLE (table), align, 0, 2, row, row + 1,
|
|
||||||
GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_mnemonic (_("I_nstall Font"));
|
|
||||||
g_signal_connect (button, "clicked",
|
|
||||||
G_CALLBACK (install_button_clicked_cb), font_file);
|
|
||||||
gtk_container_add (GTK_CONTAINER (align), button);
|
|
||||||
|
|
||||||
|
|
||||||
gtk_table_set_col_spacings(GTK_TABLE(table), 8);
|
|
||||||
gtk_table_set_row_spacings(GTK_TABLE(table), 2);
|
|
||||||
gtk_widget_show_all(window);
|
|
||||||
|
|
||||||
gtk_main();
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
<?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>
|
|
|
@ -1,156 +0,0 @@
|
||||||
/* -*- 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 <gio/gio.h>
|
|
||||||
|
|
||||||
#include "ftstream-vfs.h"
|
|
||||||
|
|
||||||
static unsigned long
|
|
||||||
vfs_stream_read(FT_Stream stream,
|
|
||||||
unsigned long offset,
|
|
||||||
unsigned char *buffer,
|
|
||||||
unsigned long count)
|
|
||||||
{
|
|
||||||
GFileInputStream *handle = (GFileInputStream *)stream->descriptor.pointer;
|
|
||||||
gssize bytes_read = 0;
|
|
||||||
|
|
||||||
if (! g_seekable_seek (G_SEEKABLE (handle), offset, G_SEEK_SET, NULL, NULL))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (count > 0) {
|
|
||||||
bytes_read = g_input_stream_read (G_INPUT_STREAM (handle), buffer, count, NULL, NULL);
|
|
||||||
|
|
||||||
if (bytes_read == -1)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytes_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vfs_stream_close(FT_Stream stream)
|
|
||||||
{
|
|
||||||
GFileInputStream *handle = (GFileInputStream *)stream->descriptor.pointer;
|
|
||||||
|
|
||||||
if (! handle)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_object_unref (handle);
|
|
||||||
|
|
||||||
stream->descriptor.pointer = NULL;
|
|
||||||
stream->size = 0;
|
|
||||||
stream->base = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FT_Error
|
|
||||||
vfs_stream_open(FT_Stream stream,
|
|
||||||
const char *uri)
|
|
||||||
{
|
|
||||||
GFile *file;
|
|
||||||
GError *error = NULL;
|
|
||||||
GFileInfo *info;
|
|
||||||
GFileInputStream *handle;
|
|
||||||
|
|
||||||
if (!stream)
|
|
||||||
return FT_Err_Invalid_Stream_Handle;
|
|
||||||
|
|
||||||
file = g_file_new_for_uri (uri);
|
|
||||||
|
|
||||||
handle = g_file_read (file, NULL, &error);
|
|
||||||
if (! handle) {
|
|
||||||
g_message ("%s", error->message);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
g_error_free (error);
|
|
||||||
return FT_Err_Cannot_Open_Resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
|
|
||||||
G_FILE_QUERY_INFO_NONE, NULL, &error);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
if (! info) {
|
|
||||||
g_warning ("%s", error->message);
|
|
||||||
|
|
||||||
g_error_free (error);
|
|
||||||
return FT_Err_Cannot_Open_Resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->size = g_file_info_get_size (info);
|
|
||||||
|
|
||||||
g_object_unref (info);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/* -*- 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ft2build.h>
|
|
||||||
#include FT_FREETYPE_H
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
[Desktop Entry]
|
|
||||||
_Name=Font Viewer
|
|
||||||
_Comment=Preview fonts
|
|
||||||
Icon=preferences-desktop-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@
|
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* The Totem project hereby grant permission for non-gpl compatible GStreamer
|
|
||||||
* plugins to be used and distributed together with GStreamer and Totem. This
|
|
||||||
* permission are above and beyond the permissions granted by the GPL license
|
|
||||||
* Totem is covered by.
|
|
||||||
*
|
|
||||||
* Monday 7th February 2005: Christian Schaller: Add exception clause.
|
|
||||||
* See license_change file for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
#include <glib/gstdio.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
|
|
||||||
#include "totem-resources.h"
|
|
||||||
|
|
||||||
#define MAX_HELPER_MEMORY (256 * 1024 * 1024) /* 256 MB */
|
|
||||||
#define MAX_HELPER_SECONDS (15) /* 15 seconds */
|
|
||||||
#define DEFAULT_SLEEP_TIME (30 * G_USEC_PER_SEC) /* 30 seconds */
|
|
||||||
|
|
||||||
static guint sleep_time = DEFAULT_SLEEP_TIME;
|
|
||||||
static gboolean finished = TRUE;
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_resource_limits (const char *input)
|
|
||||||
{
|
|
||||||
struct rlimit limit;
|
|
||||||
struct stat buf;
|
|
||||||
rlim_t max;
|
|
||||||
|
|
||||||
max = MAX_HELPER_MEMORY;
|
|
||||||
|
|
||||||
/* Set the maximum virtual size depending on the size
|
|
||||||
* of the file to process, as we wouldn't be able to
|
|
||||||
* mmap it otherwise */
|
|
||||||
if (input == NULL) {
|
|
||||||
max = MAX_HELPER_MEMORY;
|
|
||||||
} else if (g_stat (input, &buf) == 0) {
|
|
||||||
max = MAX_HELPER_MEMORY + buf.st_size;
|
|
||||||
} else if (g_str_has_prefix (input, "file://") != FALSE) {
|
|
||||||
char *file;
|
|
||||||
file = g_filename_from_uri (input, NULL, NULL);
|
|
||||||
if (file != NULL && g_stat (file, &buf) == 0)
|
|
||||||
max = MAX_HELPER_MEMORY + buf.st_size;
|
|
||||||
g_free (file);
|
|
||||||
}
|
|
||||||
|
|
||||||
limit.rlim_cur = max;
|
|
||||||
limit.rlim_max = max;
|
|
||||||
|
|
||||||
setrlimit (RLIMIT_DATA, &limit);
|
|
||||||
|
|
||||||
limit.rlim_cur = MAX_HELPER_SECONDS;
|
|
||||||
limit.rlim_max = MAX_HELPER_SECONDS;
|
|
||||||
setrlimit (RLIMIT_CPU, &limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_GNUC_NORETURN static gpointer
|
|
||||||
time_monitor (gpointer data)
|
|
||||||
{
|
|
||||||
const char *app_name;
|
|
||||||
|
|
||||||
g_usleep (sleep_time);
|
|
||||||
|
|
||||||
if (finished != FALSE)
|
|
||||||
g_thread_exit (NULL);
|
|
||||||
|
|
||||||
app_name = g_get_application_name ();
|
|
||||||
if (app_name == NULL)
|
|
||||||
app_name = g_get_prgname ();
|
|
||||||
g_print ("%s couldn't process file: '%s'\n"
|
|
||||||
"Reason: Took too much time to process.\n",
|
|
||||||
app_name,
|
|
||||||
(const char *) data);
|
|
||||||
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
totem_resources_monitor_start (const char *input, gint wall_clock_time)
|
|
||||||
{
|
|
||||||
set_resource_limits (input);
|
|
||||||
|
|
||||||
if (wall_clock_time < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (wall_clock_time > 0)
|
|
||||||
sleep_time = wall_clock_time;
|
|
||||||
|
|
||||||
finished = FALSE;
|
|
||||||
g_thread_create (time_monitor, (gpointer) input, FALSE, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
totem_resources_monitor_stop (void)
|
|
||||||
{
|
|
||||||
finished = TRUE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2007 Bastien Nocera <hadess@hadess.net>
|
|
||||||
*
|
|
||||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* The Totem project hereby grant permission for non-gpl compatible GStreamer
|
|
||||||
* plugins to be used and distributed together with GStreamer and Totem. This
|
|
||||||
* permission are above and beyond the permissions granted by the GPL license
|
|
||||||
* Totem is covered by.
|
|
||||||
*
|
|
||||||
* Monday 7th February 2005: Christian Schaller: Add exception clause.
|
|
||||||
* See license_change file for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
void totem_resources_monitor_start (const char *input,
|
|
||||||
gint wall_clock_time);
|
|
||||||
void totem_resources_monitor_stop (void);
|
|
||||||
|
|
|
@ -73,8 +73,8 @@ static gboolean postpone_sensitize_cb (DrwBreakWindow *window)
|
||||||
static gboolean clock_timeout_cb (DrwBreakWindow *window);
|
static gboolean clock_timeout_cb (DrwBreakWindow *window);
|
||||||
static void postpone_clicked_cb (GtkWidget *button,
|
static void postpone_clicked_cb (GtkWidget *button,
|
||||||
GtkWidget *window);
|
GtkWidget *window);
|
||||||
static gboolean label_expose_event_cb (GtkLabel *label,
|
static gboolean label_draw_event_cb (GtkLabel *label,
|
||||||
GdkEventExpose *event,
|
cairo_t *cr,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
static void label_size_request_cb (GtkLabel *label,
|
static void label_size_request_cb (GtkLabel *label,
|
||||||
GtkRequisition *requisition,
|
GtkRequisition *requisition,
|
||||||
|
@ -237,8 +237,8 @@ drw_break_window_init (DrwBreakWindow *window)
|
||||||
gtk_widget_show (priv->break_label);
|
gtk_widget_show (priv->break_label);
|
||||||
|
|
||||||
g_signal_connect (priv->break_label,
|
g_signal_connect (priv->break_label,
|
||||||
"expose_event",
|
"draw",
|
||||||
G_CALLBACK (label_expose_event_cb),
|
G_CALLBACK (label_draw_event_cb),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_signal_connect_after (priv->break_label,
|
g_signal_connect_after (priv->break_label,
|
||||||
|
@ -260,8 +260,8 @@ drw_break_window_init (DrwBreakWindow *window)
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), priv->clock_label, TRUE, TRUE, 8);
|
gtk_box_pack_start (GTK_BOX (vbox), priv->clock_label, TRUE, TRUE, 8);
|
||||||
|
|
||||||
g_signal_connect (priv->clock_label,
|
g_signal_connect (priv->clock_label,
|
||||||
"expose_event",
|
"draw",
|
||||||
G_CALLBACK (label_expose_event_cb),
|
G_CALLBACK (label_draw_event_cb),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_signal_connect_after (priv->clock_label,
|
g_signal_connect_after (priv->clock_label,
|
||||||
|
@ -543,25 +543,19 @@ postpone_clicked_cb (GtkWidget *button,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
label_expose_event_cb (GtkLabel *label,
|
label_draw_event_cb (GtkLabel *label,
|
||||||
GdkEventExpose *event,
|
cairo_t *cr,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
gint x, y;
|
gint x, y;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
GdkWindow *window;
|
GdkWindow *window;
|
||||||
cairo_t *cr;
|
|
||||||
|
|
||||||
gtk_label_get_layout_offsets (label, &x, &y);
|
gtk_label_get_layout_offsets (label, &x, &y);
|
||||||
|
|
||||||
widget = GTK_WIDGET (label);
|
widget = GTK_WIDGET (label);
|
||||||
window = gtk_widget_get_window (widget);
|
window = gtk_widget_get_window (widget);
|
||||||
|
|
||||||
cr = gdk_cairo_create (window);
|
|
||||||
|
|
||||||
gdk_cairo_rectangle (cr, &event->area);
|
|
||||||
cairo_clip (cr);
|
|
||||||
|
|
||||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||||
|
|
||||||
/* Can't use pango_cairo_show_layout() here as we need to override
|
/* Can't use pango_cairo_show_layout() here as we need to override
|
||||||
|
@ -571,13 +565,10 @@ label_expose_event_cb (GtkLabel *label,
|
||||||
pango_cairo_layout_path (cr, gtk_label_get_layout (label));
|
pango_cairo_layout_path (cr, gtk_label_get_layout (label));
|
||||||
cairo_fill (cr);
|
cairo_fill (cr);
|
||||||
|
|
||||||
cairo_destroy (cr);
|
|
||||||
|
|
||||||
gtk_paint_layout (gtk_widget_get_style (widget),
|
gtk_paint_layout (gtk_widget_get_style (widget),
|
||||||
window,
|
cr,
|
||||||
gtk_widget_get_state (widget),
|
gtk_widget_get_state (widget),
|
||||||
FALSE,
|
FALSE,
|
||||||
&event->area,
|
|
||||||
widget,
|
widget,
|
||||||
"label",
|
"label",
|
||||||
x, y,
|
x, y,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue