[gnome-print] PATCH: Make libgnomeprint use fontconfig if it's available.



It's a diff against cvs HEAD of libgnomeprint.

If fontconfig is detected by configure, it is used, otherwise it falls
back to old behavior (gnome-print's own fontmap files).

It isn't tested much, and for some reason, freetype can't get unicode
charmap for some (few, namely webdings, windings) fonts.

It's quite hacky, since I didn't want to make big changes. It should be
possible (and right way to do it) to get all information about fonts
from fontconfig and we could remove direct freetype/type1 access from
gnome-print...


Another thing, I think there is no reason to keep GnomeFontDialog in
libgnomeprint, it's already in libgnomeui (and Gtk) (correct me if I'm
wrong).

As a result, we have unified font backend with pango plus we can (soon)
remove gnome-font-installer and gnome-font-dialog code to make
gnome-print's codebase much smaller.

-- 
Tambet Ingo <tambet@ximian.com>
? autom4te-2.53.cache
? diff
? stamp-h1
Index: acconfig.h
===================================================================
RCS file: /cvs/gnome/libgnomeprint/acconfig.h,v
retrieving revision 1.11
diff -u -r1.11 acconfig.h
--- acconfig.h	29 Aug 2002 17:12:46 -0000	1.11
+++ acconfig.h	2 Oct 2002 17:56:52 -0000
@@ -13,3 +13,5 @@
 #undef GNOME_PRINT_MODULES_DIR
 #undef FONTMAPDIR_STATIC
 #undef FONTMAPDIR_DYNAMIC
+#undef HAVE_FONTCONFIG
+
Index: configure.in
===================================================================
RCS file: /cvs/gnome/libgnomeprint/configure.in,v
retrieving revision 1.199
diff -u -r1.199 configure.in
--- configure.in	1 Sep 2002 16:20:55 -0000	1.199
+++ configure.in	2 Oct 2002 17:56:52 -0000
@@ -89,6 +89,22 @@
 
 AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
 
+dnl
+dnl Check for Fontconfig and use it
+dnl when we have it.
+dnl
+have_fontconfig=false
+fontconfig_modules=""
+if $PKG_CONFIG --exists fontconfig ; then
+  have_fontconfig=true
+  fontconfig_modules="fontconfig"
+fi
+
+AC_DEFINE(HAVE_FONTCONFIG)
+
+PKG_CHECK_MODULES(GP, [ $glib_modules $libart_modules $pango_modules $libxml2_modules $libbonobo_modules $fontconfig_modules ])
+
+
 dnl =================================
 dnl Checking for freetype2
 dnl =================================
Index: libgnomeprint/gnome-fontmap.c
===================================================================
RCS file: /cvs/gnome/libgnomeprint/libgnomeprint/gnome-fontmap.c,v
retrieving revision 1.23
diff -u -r1.23 gnome-fontmap.c
--- libgnomeprint/gnome-fontmap.c	29 Aug 2002 17:12:47 -0000	1.23
+++ libgnomeprint/gnome-fontmap.c	2 Oct 2002 17:56:53 -0000
@@ -36,6 +36,10 @@
 #include <libxml/xmlmemory.h>
 #include "gnome-fontmap.h"
 
+#ifdef HAVE_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
+
 /*
  * We parse following locations for fontmaps:
  *
@@ -168,6 +172,8 @@
 	}
 }
 
+#ifndef HAVE_FONTCONFIG
+
 static GPFontMap *
 gp_fontmap_load (void)
 {
@@ -318,6 +324,7 @@
 
 	return map;
 }
+#endif
 
 static gint
 gp_fontmap_compare_names (gconstpointer a, gconstpointer b)
@@ -761,6 +768,7 @@
 		GPFontEntryT1 *t1;
 		GPFontEntryT1Alias *t1a;
 		GPFontEntrySpecial *s;
+		GPFontEntryTT *tt;
 
 		g_return_if_fail (entry->face == NULL);
 
@@ -782,6 +790,10 @@
 			break;
 		case GP_FONT_ENTRY_ALIAS:
 			break;
+		case GP_FONT_ENTRY_TRUETYPE:
+			tt = (GPFontEntryTT *) entry;
+			if (tt->ttf.name) g_free (tt->ttf.name);
+			break;
 		case GP_FONT_ENTRY_SPECIAL:
 			s = (GPFontEntrySpecial *) entry;
 			if (s->file.name) g_free (s->file.name);
@@ -1020,3 +1032,195 @@
 
 	return FALSE;
 }
+
+
+#ifdef HAVE_FONTCONFIG
+
+static GPFontEntry *
+fcpattern_to_gp_font_entry (FcPattern *font)
+{
+	GPFontEntry *e;
+	GPFontEntryTT *tt;
+	FcResult result;
+	FcChar8 *str;
+	int i;
+
+	tt = g_new0 (GPFontEntryTT, 1);
+	e = (GPFontEntry *)tt;
+
+	e->type = GP_FONT_ENTRY_TRUETYPE;
+	e->refcount = 1;
+	e->face = NULL;
+
+	/* gp_font_entry_2_0_load_data: */
+	result = FcPatternGetString (font, FC_FAMILY, 0, &str);
+	if (result == FcResultMatch)
+		e->familyname = g_strdup (str);
+
+	result = FcPatternGetString (font, FC_STYLE, 0, &str);
+	if (result == FcResultMatch) {
+		e->speciesname = g_strdup (str);
+		e->weight = g_strdup (str);
+	}
+
+	result = FcPatternGetInteger (font, FC_WEIGHT, 0, &i);
+	if (result == FcResultMatch)
+		e->Weight = i;
+
+	e->version = g_strdup ("1.0");
+
+	e->name = g_strdup_printf ("%s %s", e->familyname, e->weight);
+	e->psname = g_strdup_printf ("%s-%s", e->familyname, e->weight);
+
+	result = FcPatternGetInteger (font, FC_SLANT, 0, &i);
+	if (result == FcResultMatch)
+		e->ItalicAngle = i;
+
+	/* gp_font_entry_2_0_truetype_load_files */
+	result = FcPatternGetString (font, FC_FILE, 0, &str);
+	if (result == FcResultMatch)
+		tt->ttf.name = g_strdup (str);
+
+
+	return e;
+}
+
+static void
+gp_fontmap_load_fontconfig (GPFontMap *map)
+{
+	FcFontSet *fontset;
+	FcPattern *font;
+	GPFontEntry *e;
+	int i;
+
+	fontset = FcConfigGetFonts (NULL, FcSetSystem);
+	if (fontset == NULL) {
+		return;
+	}
+
+	for (i = 0; i < fontset->nfont; i++) {
+		font = fontset->fonts[i];
+
+		e = fcpattern_to_gp_font_entry (font);
+		if (e) {
+			g_hash_table_insert (map->fontdict, e->name, e);
+			map->num_fonts++;
+			map->fonts = g_slist_prepend (map->fonts, e);
+		}
+	}
+}
+
+static GPFontMap *
+gp_fontmap_load (void)
+{
+	GPFontMap *map;
+	GSList * l;
+
+	map = g_new (GPFontMap, 1);
+	/* We always hold private ref to fontmap, this is released if directories change */
+	map->refcount = 1;
+	map->num_fonts = 0;
+	/* Clear timestamps */
+	map->mtime_static = 0;
+	map->mtime_dynamic = 0;
+	map->mtime_user = 0;
+	map->fontdict = g_hash_table_new (g_str_hash, g_str_equal);
+	map->familydict = g_hash_table_new (g_str_hash, g_str_equal);
+	map->fonts = NULL;
+	map->families = NULL;
+	map->fontlist = NULL;
+	map->familylist = NULL;
+	map->defaults = NULL;
+	map->defaultsdict = g_hash_table_new (g_str_hash, g_str_equal);
+
+
+	gp_fontmap_load_fontconfig (map);
+
+	/* Sort fonts alphabetically */
+	map->fonts = g_slist_sort (map->fonts, gp_fe_sortname);
+
+	/* Sort fonts into familia */
+	for (l = map->fonts; l != NULL; l = l->next) {
+		GPFontEntry * e;
+		GPFamilyEntry * f;
+		e = (GPFontEntry *) l->data;
+		f = g_hash_table_lookup (map->familydict, e->familyname);
+		if (!f) {
+			f = g_new0 (GPFamilyEntry, 1);
+			gp_family_entry_ref (f);
+			f->name = g_strdup (e->familyname);
+			f->fonts = g_slist_prepend (f->fonts, e);
+			g_hash_table_insert (map->familydict, f->name, f);
+			map->families = g_slist_prepend (map->families, f);
+		} else {
+			f->fonts = g_slist_prepend (f->fonts, e);
+		}
+	}
+
+	/* Sort familia alphabetically */
+	map->families = g_slist_sort (map->families, gp_familyentry_sortname);
+
+	/* Sort fonts inside familia */
+	for (l = map->families; l != NULL; l = l->next) {
+		GPFamilyEntry * f;
+		f = (GPFamilyEntry *) l->data;
+		f->fonts = g_slist_sort (f->fonts, gp_fe_sortspecies);
+	}
+
+	/* Compose defaultsdict */
+	map->defaults = g_slist_reverse (map->defaults);
+	while (map->defaults) {
+		GSList *l;
+		guchar *locales, *fontname;
+		GPFontEntry *entry;
+		l = map->defaults->data;
+		map->defaults = g_slist_remove (map->defaults, l);
+		locales = l->data;
+		fontname = l->next->data;
+		g_slist_free (l);
+		entry = g_hash_table_lookup (map->fontdict, fontname);
+		if (!entry) {
+			GPFamilyEntry *fe;
+			/* Try family */
+			fe = g_hash_table_lookup (map->familydict, fontname);
+			if (fe && fe->fonts) {
+				entry = (GPFontEntry *) fe->fonts->data;
+				l = fe->fonts;
+				while (l) {
+					GPFontEntry *e;
+					e = (GPFontEntry *) l->data;
+					if (!strcasecmp (e->speciesname, "regular") ||
+					    !strcasecmp (e->speciesname, "roman") ||
+					    !strcasecmp (e->speciesname, "normal")) {
+						entry = e;
+						break;
+					}
+					l = l->next;
+				}
+			}
+		}
+		if (entry) {
+			guchar *l;
+			l = locales;
+			while (l) {
+				guchar *e;
+				e = strchr (l, ',');
+				if (e) {
+					*e = '\0';
+					e += 1;
+				}
+				if (!g_hash_table_lookup (map->defaultsdict, l)) {
+					GQuark q;
+					q = g_quark_from_string (l);
+					g_hash_table_insert (map->defaultsdict, (gpointer) g_quark_to_string (q), entry);
+				}
+				l = e;
+			}
+		}
+		g_free (locales);
+		g_free (fontname);
+	}
+
+	return map;
+}
+#endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]