Re: PangoXft and PangoFT2 patch from hell
- From: Alex Larsson <alexl redhat com>
- To: Owen Taylor <otaylor redhat com>
- Cc: <gtk-devel-list gnome org>
- Subject: Re: PangoXft and PangoFT2 patch from hell
- Date: Sat, 17 Nov 2001 20:49:32 -0500 (EST)
On 16 Nov 2001, Owen Taylor wrote:
> I've read through the patch now, except for the PangoFT2 parts.
> I assume that part is just doing the same thing as the PangoXft
> part, and I'm less familiar with the code to begin with.
Ok. Here is the next revision.
> * We shouldn't require LEX and YACC, for tarballs. So, we need to
> check the results of AM_PROG_LEX, AC_PROG_YACC and define
> some sort of @REBUILD_MINI_XFT@ based on this. (See handling
> of @REBUILD@ in GTK+)
I didn't do this yet. I'll do so, but maybe we should get the API in as
soon as possible.
/ Alex
Index: configure.in
===================================================================
RCS file: /cvs/gnome/pango/configure.in,v
retrieving revision 1.82
diff -u -p -r1.82 configure.in
--- configure.in 2001/10/28 22:54:09 1.82
+++ configure.in 2001/11/18 01:40:27
@@ -15,7 +15,9 @@ AM_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
-
+AM_PROG_LEX
+AC_PROG_YACC
+
AC_MSG_CHECKING([for some Win32 platform])
case "$host" in
*-*-mingw*|*-*-cygwin*)
@@ -553,6 +555,7 @@ AC_OUTPUT([
Makefile
pango/Makefile
pango/mini-fribidi/Makefile
+pango/mini-xft/Makefile
pango/opentype/Makefile
pango/makefile.mingw
pango/pango.rc
Index: modules/basic/basic-ft2.c
===================================================================
RCS file: /cvs/gnome/pango/modules/basic/basic-ft2.c,v
retrieving revision 1.11
diff -u -p -r1.11 basic-ft2.c
--- modules/basic/basic-ft2.c 2001/06/14 20:38:20 1.11
+++ modules/basic/basic-ft2.c 2001/11/18 01:40:30
@@ -119,21 +119,13 @@ static PangoGlyph
find_char (PangoFont *font,
gunichar wc)
{
- int i;
- int n_subfonts;
-
- n_subfonts = pango_ft2_n_subfonts (font);
+ FT_Face face;
+ FT_UInt index;
- for (i = 0; i < n_subfonts; i++)
- {
- FT_Face face;
- FT_UInt index;
-
- face = pango_ft2_get_face (font, i+1);
- index = FT_Get_Char_Index (face, wc);
- if (index && index <= face->num_glyphs)
- return PANGO_FT2_MAKE_GLYPH (i+1, index);
- }
+ face = pango_ft2_font_get_face (font);
+ index = FT_Get_Char_Index (face, wc);
+ if (index && index <= face->num_glyphs)
+ return index;
return 0;
}
@@ -285,19 +277,7 @@ static PangoCoverage *
basic_engine_get_coverage (PangoFont *font,
PangoLanguage *lang)
{
- PangoCoverage *result;
-#if 0
- gunichar wc;
-
- result = pango_coverage_new ();
-
- for (wc = 0; wc < 65536; wc++)
- if (find_char (font, wc))
- pango_coverage_set (result, wc, PANGO_COVERAGE_EXACT);
-#else
- result = pango_ft2_get_coverage (font, lang);
-#endif
- return result;
+ return pango_ft2_font_get_coverage (font, lang);
}
static PangoEngine *
@@ -346,3 +326,4 @@ void
MODULE_ENTRY(script_engine_unload) (PangoEngine *engine)
{
}
+
Index: pango/Makefile.am
===================================================================
RCS file: /cvs/gnome/pango/pango/Makefile.am,v
retrieving revision 1.59
diff -u -p -r1.59 Makefile.am
--- pango/Makefile.am 2001/10/28 22:54:14 1.59
+++ pango/Makefile.am 2001/11/18 01:40:30
@@ -6,6 +6,9 @@ GPATH = $(srcdir)
if HAVE_FREETYPE
OPENTYPE_SUBDIR=opentype
+XFT_SUBDIR = mini-xft
+else
+XFT_SUBDIR =
endif
if HAVE_FRIBIDI
@@ -13,9 +16,9 @@ else
FRIBIDI_SUBDIR = mini-fribidi
endif
-SUBDIRS = $(OPENTYPE_SUBDIR) $(FRIBIDI_SUBDIR)
+SUBDIRS = $(OPENTYPE_SUBDIR) $(FRIBIDI_SUBDIR) $(XFT_SUBDIR)
-DIST_SUBDIRS = mini-fribidi opentype
+DIST_SUBDIRS = mini-fribidi mini-xft opentype
INCLUDES = \
-DPANGO_ENABLE_BACKEND \
@@ -183,11 +186,10 @@ libpangoft2_la_SOURCES = \
pangoft2.h \
pangoft2.c \
pangoft2-private.h \
- pangoft2-fontcache.c \
pangoft2-fontmap.c \
module-defs-ft2.c
-libpangoft2_la_LIBADD = $(INCLUDED_FT2_MODULES) $(FREETYPE_LIBS) libpango.la
+libpangoft2_la_LIBADD = $(INCLUDED_FT2_MODULES) $(FREETYPE_LIBS) mini-xft/libmini-xft.la libpango.la
libpangoft2_la_LDFLAGS = -release $(VERSION) $(GLIB_LIBS) $(no_undefined) $(pangoft2_export_symbols)
libpangoft2_la_DEPENDENCIES = $(INCLUDED_FT2_MODULES) libpango.la
Index: pango/fonts.c
===================================================================
RCS file: /cvs/gnome/pango/pango/fonts.c,v
retrieving revision 1.40
diff -u -p -r1.40 fonts.c
--- pango/fonts.c 2001/11/11 23:36:26 1.40
+++ pango/fonts.c 2001/11/18 01:40:31
@@ -1405,3 +1405,352 @@ pango_font_face_get_face_name (PangoFont
return PANGO_FONT_FACE_GET_CLASS (face)->get_face_name (face);
}
+
+/*
+ * PangoFontset
+ */
+
+static void pango_fontset_class_init (PangoFontsetClass *class);
+static PangoFontMetrics *pango_fontset_real_get_metrics (PangoFontset *fontset,
+ PangoLanguage *language);
+
+GType
+pango_fontset_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (PangoFontsetClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) pango_fontset_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PangoFontset),
+ 0, /* n_preallocs */
+ NULL /* init */
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "PangoFontset",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+static void
+pango_fontset_class_init (PangoFontsetClass *class)
+{
+ class->get_metrics = pango_fontset_real_get_metrics;
+}
+
+/**
+ * pango_fontset_get_font:
+ * @fontset: a #PangoFontset
+ * @wc: a unicode character
+ * @language: language tag used to determine which script to get the font
+ * for, or %NULL to indicate to get the the entire font.
+ *
+ * Returns the font in the fontset that contains the best glyph for the
+ * unicode character wc.
+ *
+ * Returns: a #PangoFont. The caller must call g_object_unref when finished
+ * with the font.
+ **/
+PangoFont *
+pango_fontset_get_font (PangoFontset *fontset,
+ guint wc,
+ PangoLanguage *language)
+{
+ g_return_val_if_fail (fontset != NULL, NULL);
+
+ return PANGO_FONTSET_GET_CLASS (fontset)->get_font (fontset, wc, language);
+}
+
+/**
+ * pango_fontset_get_metrics:
+ * @fontset: a #PangoFontset
+ * @desc: a #PangoFontDescription structure
+ * @language: language tag used to determine which script to get the metrics
+ * for, or %NULL to indicate to get the metrics for the entire
+ * font.
+ *
+ * Get overall metric information for the fonts in the fontset.
+ * Since the metrics may be substantially different for
+ * different scripts, a language tag can be provided to indicate that
+ * the metrics should be retrieved that correspond to the script(s)
+ * used by that language.
+ *
+ * Returns: a #PangoMetrics object. The caller must call pango_font_metrics_unref()
+ * when finished using the object.
+ **/
+PangoFontMetrics *
+pango_fontset_get_metrics (PangoFontset *fontset,
+ PangoLanguage *language)
+{
+ g_return_val_if_fail (fontset != NULL, NULL);
+
+ return PANGO_FONTSET_GET_CLASS (fontset)->get_metrics (fontset, language);
+}
+
+
+static PangoFontMetrics *
+pango_fontset_real_get_metrics (PangoFontset *fontset,
+ PangoLanguage *language)
+{
+ PangoFontMetrics *metrics, *raw_metrics;
+ const char *sample_str;
+ const char *p;
+ int count;
+ GHashTable *fonts_seen;
+ PangoFont *font;
+
+ sample_str = pango_language_get_sample_string (language);
+
+ count = 0;
+ metrics = pango_font_metrics_new ();
+ fonts_seen = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
+
+ p = sample_str;
+ while (*p)
+ {
+ gunichar wc = g_utf8_get_char (p);
+ font = pango_fontset_get_font (fontset, wc, language);
+ if (font)
+ {
+ if (g_hash_table_lookup (fonts_seen, font) == NULL)
+ {
+ raw_metrics = pango_font_get_metrics (font, language);
+ g_hash_table_insert (fonts_seen, font, font);
+
+ if (count == 0)
+ {
+ *metrics = *raw_metrics;
+ metrics->approximate_char_width = raw_metrics->approximate_char_width;
+ metrics->approximate_digit_width = raw_metrics->approximate_digit_width;
+ }
+ else
+ {
+ metrics->ascent = MAX (metrics->ascent, raw_metrics->ascent);
+ metrics->descent = MAX (metrics->descent, raw_metrics->descent);
+ metrics->approximate_char_width += raw_metrics->approximate_char_width;
+ metrics->approximate_digit_width += raw_metrics->approximate_digit_width;
+ }
+ count++;
+ }
+ else
+ g_object_unref (font);
+ }
+
+ p = g_utf8_next_char (p);
+ }
+
+ g_hash_table_destroy (fonts_seen);
+
+ metrics->approximate_char_width /= count;
+ metrics->approximate_digit_width /= count;
+
+ return metrics;
+}
+
+
+/*
+ * PangoFontsetSimple
+ */
+
+#define PANGO_FONTSET_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONTSET_SIMPLE, PangoFontsetSimpleClass))
+#define PANGO_IS_FONTSET_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FONTSET_SIMPLE))
+#define PANGO_FONTSET_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONTSET_SIMPLE, PangoFontsetSimpleClass))
+
+static void pango_fontset_simple_class_init (PangoFontsetSimpleClass *class);
+static void pango_fontset_simple_finalize (GObject *object);
+static void pango_fontset_simple_init (PangoFontsetSimple *fontset);
+static PangoFontMetrics *pango_fontset_simple_get_metrics (PangoFontset *fontset,
+ PangoLanguage *language);
+static PangoFont * pango_fontset_simple_get_font (PangoFontset *fontset,
+ guint wc,
+ PangoLanguage *language);
+
+
+
+struct _PangoFontsetSimple
+{
+ PangoFontset parent_instance;
+
+ GPtrArray *fonts;
+ GPtrArray *coverages;
+ PangoLanguage *language;
+};
+
+struct _PangoFontsetSimpleClass
+{
+ PangoFontsetClass parent_class;
+};
+
+static PangoFontsetClass *simple_parent_class; /* Parent class structure for PangoFontsetSimple */
+
+PangoFontsetSimple *
+pango_fontset_simple_new (void)
+{
+ return g_object_new (PANGO_TYPE_FONTSET_SIMPLE, NULL);
+}
+
+GType
+pango_fontset_simple_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (PangoFontsetSimpleClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) pango_fontset_simple_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PangoFontsetSimple),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pango_fontset_simple_init,
+ };
+
+ object_type = g_type_register_static (PANGO_TYPE_FONTSET,
+ "PangoFontsetSimple",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+static void
+pango_fontset_simple_class_init (PangoFontsetSimpleClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontsetClass *fontset_class = PANGO_FONTSET_CLASS (class);
+
+ simple_parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = pango_fontset_simple_finalize;
+ fontset_class->get_font = pango_fontset_simple_get_font;
+ fontset_class->get_metrics = pango_fontset_simple_get_metrics;
+}
+
+static void
+pango_fontset_simple_init (PangoFontsetSimple *fontset)
+{
+ fontset->fonts = g_ptr_array_new ();
+ fontset->coverages = g_ptr_array_new ();
+ fontset->language = NULL;
+}
+
+static void
+pango_fontset_simple_finalize (GObject *object)
+{
+ PangoFontsetSimple *fontset = PANGO_FONTSET_SIMPLE (object);
+ PangoCoverage *coverage;
+ int i;
+
+ for (i = 0; i < fontset->fonts->len; i++)
+ g_object_unref (g_ptr_array_index(fontset->fonts, i));
+
+ g_ptr_array_free (fontset->fonts, TRUE);
+
+ for (i = 0; i < fontset->coverages->len; i++)
+ {
+ coverage = g_ptr_array_index (fontset->coverages, i);
+ if (coverage)
+ pango_coverage_unref (coverage);
+ }
+
+ g_ptr_array_free (fontset->coverages, TRUE);
+
+ G_OBJECT_CLASS (simple_parent_class)->finalize (object);
+}
+
+void
+pango_fontset_simple_append (PangoFontsetSimple *fontset,
+ PangoFont *font)
+{
+ g_ptr_array_add (fontset->fonts, font);
+ g_ptr_array_add (fontset->coverages, NULL);
+}
+
+int
+pango_fontset_simple_size (PangoFontsetSimple *fontset)
+{
+ return fontset->fonts->len;
+}
+
+static PangoFontMetrics *
+pango_fontset_simple_get_metrics (PangoFontset *fontset,
+ PangoLanguage *language)
+{
+ PangoFontsetSimple *simple = PANGO_FONTSET_SIMPLE (fontset);
+
+ if (simple->fonts->len == 1)
+ return pango_font_get_metrics (PANGO_FONT (g_ptr_array_index(simple->fonts, 0)),
+ language);
+
+ return PANGO_FONTSET_CLASS (simple_parent_class)->get_metrics (fontset, language);
+}
+
+static PangoFont *
+pango_fontset_simple_get_font (PangoFontset *fontset,
+ guint wc,
+ PangoLanguage *language)
+{
+ PangoFontsetSimple *simple = PANGO_FONTSET_SIMPLE (fontset);
+ PangoCoverageLevel best_level = PANGO_COVERAGE_NONE;
+ PangoCoverageLevel level;
+ PangoFont *font;
+ PangoCoverage *coverage;
+ int result = -1;
+ int i;
+
+ /* Only cache coverages from one language, this assumes
+ * that apps normally only use one language at a time. */
+ if (simple->language != language)
+ {
+ for (i = 0; i < simple->coverages->len; i++)
+ {
+ coverage = g_ptr_array_index (simple->coverages, i);
+
+ if (coverage)
+ pango_coverage_unref (coverage);
+
+ g_ptr_array_index (simple->coverages, i) = NULL;
+ }
+ simple->language = language;
+ }
+
+ for (i = 0; i < simple->fonts->len; i++)
+ {
+ coverage = g_ptr_array_index (simple->coverages, i);
+
+ if (coverage == NULL)
+ {
+ font = g_ptr_array_index (simple->fonts, i);
+
+ coverage = pango_font_get_coverage (font, language);
+ g_ptr_array_index (simple->coverages, i) = coverage;
+ }
+
+ level = pango_coverage_get (coverage, wc);
+
+ if (result == -1 || level > best_level)
+ {
+ result = i;
+ best_level = level;
+ if (level == PANGO_COVERAGE_EXACT)
+ break;
+ }
+ }
+
+ font = g_ptr_array_index(simple->fonts, result);
+ return g_object_ref (font);
+}
Index: pango/pango-context.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-context.c,v
retrieving revision 1.42
diff -u -p -r1.42 pango-context.c
--- pango/pango-context.c 2001/09/19 23:44:50 1.42
+++ pango/pango-context.c 2001/11/18 01:40:32
@@ -35,7 +35,7 @@ struct _PangoContext
PangoDirection base_dir;
PangoFontDescription *font_desc;
- GSList *font_maps;
+ PangoFontMap *font_map;
};
struct _PangoContextClass
@@ -92,7 +92,7 @@ pango_context_init (PangoContext *contex
{
context->base_dir = PANGO_DIRECTION_LTR;
context->language = NULL;
- context->font_maps = NULL;
+ context->font_map = NULL;
context->font_desc = pango_font_description_new ();
pango_font_description_set_family (context->font_desc, "serif");
@@ -120,8 +120,8 @@ pango_context_finalize (GObject *object)
context = PANGO_CONTEXT (object);
- g_slist_foreach (context->font_maps, (GFunc)g_object_unref, NULL);
- g_slist_free (context->font_maps);
+ if (context->font_map)
+ g_object_unref (G_OBJECT(context->font_map));
pango_font_description_free (context->font_desc);
@@ -147,39 +147,24 @@ pango_context_new (void)
}
/**
- * pango_context_add_font_map:
+ * pango_context_set_font_map:
* @context: a #PangoContext
- * @font_map: the #PangoFontMap to add.
+ * @font_map: the #PangoFontMap to set.
*
- * Add a font map to the list of font maps that are searched for fonts
- * when fonts are looked-up in this context.
+ * Sets the font map to be searched when fonts are looked-up in this context.
**/
void
-pango_context_add_font_map (PangoContext *context,
+pango_context_set_font_map (PangoContext *context,
PangoFontMap *font_map)
{
g_return_if_fail (context != NULL);
g_return_if_fail (font_map != NULL);
-
- g_object_ref (G_OBJECT (font_map));
- context->font_maps = g_slist_append (context->font_maps, font_map);
-}
-typedef struct
-{
- int n_found;
- PangoFontFamily **families;
-} ListFamiliesInfo;
+ if (context->font_map)
+ g_object_unref (G_OBJECT (context->font_map));
-static void
-list_families_foreach (gpointer key, gpointer value, gpointer user_data)
-{
- ListFamiliesInfo *info = user_data;
-
- if (info->families)
- info->families[info->n_found++] = value;
-
- g_free (value);
+ g_object_ref (G_OBJECT (font_map));
+ context->font_map = font_map;
}
/**
@@ -196,17 +181,13 @@ pango_context_list_families (PangoContex
PangoFontFamily ***families,
int *n_families)
{
- int n_maps;
-
g_return_if_fail (context != NULL);
g_return_if_fail (families == NULL || n_families != NULL);
if (n_families == NULL)
return;
-
- n_maps = g_slist_length (context->font_maps);
- if (n_maps == 0)
+ if (context->font_map == NULL)
{
*n_families = 0;
if (families)
@@ -214,57 +195,8 @@ pango_context_list_families (PangoContex
return;
}
- else if (n_maps == 1)
-
- pango_font_map_list_families (context->font_maps->data, families, n_families);
- else
- {
- GHashTable *family_hash;
- GSList *tmp_list;
- ListFamiliesInfo info;
-
- *n_families = 0;
-
- family_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- tmp_list = context->font_maps;
- while (tmp_list)
- {
- PangoFontFamily **tmp_families;
- int tmp_n_families;
- int i;
-
- pango_font_map_list_families (tmp_list->data, &tmp_families, &tmp_n_families);
-
- for (i=0; i<*n_families; i++)
- {
- const char *family = pango_font_family_get_name (tmp_families[i]);
-
- if (!g_hash_table_lookup (family_hash, tmp_families[i]))
- {
- g_hash_table_insert (family_hash, (char *)family, tmp_families[i]);
- (*n_families)++;
- }
- }
-
- g_free (tmp_families);
-
- tmp_list = tmp_list->next;
- }
-
- info.n_found = 0;
-
- if (families)
- {
- *families = g_new (PangoFontFamily *, *n_families);
- info.families = *families;
- }
- else
- info.families = NULL;
-
- g_hash_table_foreach (family_hash, list_families_foreach, &info);
- g_hash_table_destroy (family_hash);
- }
+ else
+ pango_font_map_list_families (context->font_map, families, n_families);
}
/**
@@ -281,23 +213,9 @@ PangoFont *
pango_context_load_font (PangoContext *context,
const PangoFontDescription *desc)
{
- GSList *tmp_list;
-
g_return_val_if_fail (context != NULL, NULL);
-
- tmp_list = context->font_maps;
- while (tmp_list)
- {
- PangoFont *font;
-
- font = pango_font_map_load_font (tmp_list->data, desc);
- if (font)
- return font;
-
- tmp_list = tmp_list->next;
- }
- return NULL;
+ return pango_font_map_load_font (context->font_map, desc);
}
/**
@@ -610,152 +528,6 @@ static PangoEngineShape fallback_shaper
fallback_engine_get_coverage
};
-/* FIXME: Remove this artificial limit */
-#define MAX_FAMILIES 16
-
-typedef struct _FontSet FontSet;
-
-struct _FontSet
-{
- int n_families;
- PangoFont *fonts[MAX_FAMILIES];
- PangoCoverage *coverages[MAX_FAMILIES];
-};
-
-#define FONT_SET_INITIALIZER { 0, }
-
-static gint
-font_set_get_font (FontSet *font_set,
- gunichar wc)
-{
- PangoCoverageLevel best_level = PANGO_COVERAGE_NONE;
-
- int result = -1;
- int i;
-
- for (i=0; i < font_set->n_families; i++)
- {
- if (font_set->fonts[i])
- {
- PangoCoverageLevel level = pango_coverage_get (font_set->coverages[i], wc);
-
- if (result == -1 || level > best_level)
- {
- result = i;
- best_level = level;
- }
- }
- }
-
- return result;
-}
-
-static void
-font_set_free (FontSet *font_set)
-{
- int j;
-
- for (j=0; j < font_set->n_families; j++)
- {
- if (font_set->fonts[j])
- {
- g_object_unref (font_set->fonts[j]);
- pango_coverage_unref (font_set->coverages[j]);
- }
- }
-
- font_set->n_families = 0;
-}
-
-static void
-font_set_load (FontSet *font_set,
- PangoContext *context,
- PangoLanguage *language,
- const PangoFontDescription *desc)
-{
- PangoFontDescription *tmp_desc = pango_font_description_copy_static (desc);
- char **families;
- int j;
-
- font_set_free (font_set);
-
- families = g_strsplit (pango_font_description_get_family (desc), ",", -1);
-
- font_set->n_families = 0;
- for (j=0; families[j] && font_set->n_families < MAX_FAMILIES; j++)
- {
- pango_font_description_set_family_static (tmp_desc, families[j]);
- font_set->fonts[font_set->n_families] = pango_context_load_font (context, tmp_desc);
-
- if (font_set->fonts[font_set->n_families])
- {
- font_set->coverages[font_set->n_families] = pango_font_get_coverage (font_set->fonts[font_set->n_families], language);
- (font_set->n_families)++;
- }
- }
-
- g_strfreev (families);
- pango_font_description_set_family_static (tmp_desc, pango_font_description_get_family (desc));
-
- /* The font description was completely unloadable, try with
- * family == "Sans"
- */
- if (font_set->n_families == 0)
- {
- char *ctmp1, *ctmp2;
-
- ctmp1 = pango_font_description_to_string (desc);
- pango_font_description_set_family_static (tmp_desc, "Sans");
- ctmp2 = pango_font_description_to_string (tmp_desc);
-
- g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2);
- g_free (ctmp1);
- g_free (ctmp2);
-
- font_set->fonts[0] = pango_context_load_font (context, tmp_desc);
- if (font_set->fonts[0])
- {
- font_set->coverages[0] = pango_font_get_coverage (font_set->fonts[0], language);
- font_set->n_families = 1;
- }
- }
-
- /* We couldn't try with Sans and the specified style. Try Sans Normal
- */
- if (font_set->n_families == 0)
- {
- char *ctmp1, *ctmp2;
-
- ctmp1 = pango_font_description_to_string (tmp_desc);
- pango_font_description_set_style (tmp_desc, PANGO_STYLE_NORMAL);
- pango_font_description_set_weight (tmp_desc, PANGO_WEIGHT_NORMAL);
- pango_font_description_set_variant (tmp_desc, PANGO_VARIANT_NORMAL);
- pango_font_description_set_stretch (tmp_desc, PANGO_STRETCH_NORMAL);
- ctmp2 = pango_font_description_to_string (tmp_desc);
-
- g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2);
- g_free (ctmp1);
- g_free (ctmp2);
-
- font_set->fonts[0] = pango_context_load_font (context, tmp_desc);
- if (font_set->fonts[0])
- {
- font_set->coverages[0] = pango_font_get_coverage (font_set->fonts[0], language);
- font_set->n_families = 1;
- }
- }
-
- /* Everything failed, we are screwed, there is no way to continue
- */
- if (font_set->n_families == 0)
- {
- g_warning ("All font failbacks failed!!!!");
- exit (1);
- }
-
- pango_font_description_free (tmp_desc);
-}
-
static gboolean
advance_iterator_to (PangoAttrIterator *iterator,
int start_index)
@@ -794,12 +566,11 @@ add_engines (PangoContext *context,
GSList *extra_attrs = NULL;
PangoMap *lang_map = NULL;
PangoFontDescription *current_desc = NULL;
- FontSet current_fonts = FONT_SET_INITIALIZER;
+ PangoFontset *current_fonts = NULL;
PangoAttrIterator *iterator;
gboolean first_iteration = TRUE;
gunichar wc;
int i = 0;
- int font_index;
if (cached_iter)
iterator = cached_iter;
@@ -858,7 +629,11 @@ add_engines (PangoContext *context,
pango_font_description_free (current_desc);
current_desc = next_desc;
- font_set_load (¤t_fonts, context, language, current_desc);
+ if (current_fonts)
+ g_object_unref (current_fonts);
+
+ current_fonts = pango_font_map_load_fontset (context->font_map,
+ current_desc);
}
else
pango_font_description_free (next_desc);
@@ -868,14 +643,7 @@ add_engines (PangoContext *context,
pos = g_utf8_next_char (pos);
analysis->lang_engine = (PangoEngineLang *)pango_map_get_engine (lang_map, wc);
- font_index = font_set_get_font (¤t_fonts, wc);
- if (font_index != -1)
- {
- analysis->font = current_fonts.fonts[font_index];
- g_object_ref (analysis->font);
- }
- else
- analysis->font = NULL;
+ analysis->font = pango_fontset_get_font (current_fonts, wc, language);
analysis->language = language;
/* FIXME: handle reference counting properly on the shapers */
@@ -894,7 +662,8 @@ add_engines (PangoContext *context,
if (current_desc)
pango_font_description_free (current_desc);
- font_set_free (¤t_fonts);
+ if (current_fonts)
+ g_object_unref (current_fonts);
if (iterator != cached_iter)
pango_attr_iterator_destroy (iterator);
@@ -929,62 +698,17 @@ pango_context_get_metrics (PangoContext
const PangoFontDescription *desc,
PangoLanguage *language)
{
- FontSet current_fonts = FONT_SET_INITIALIZER;
- PangoFontMetrics *raw_metrics[MAX_FAMILIES];
+ PangoFontset *current_fonts = NULL;
PangoFontMetrics *metrics;
- const char *sample_str;
- const char *p;
- int i;
g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
g_return_val_if_fail (desc != NULL, NULL);
- sample_str = pango_language_get_sample_string (language);
+ current_fonts = pango_font_map_load_fontset (context->font_map, desc);
- font_set_load (¤t_fonts, context, language, desc);
-
- if (current_fonts.n_families == 1)
- metrics = pango_font_get_metrics (current_fonts.fonts[0], language);
- else
- {
- int count = 0;
-
- metrics = pango_font_metrics_new ();
-
- for (i=0; i < MAX_FAMILIES; i++)
- raw_metrics[i] = NULL;
+ metrics = pango_fontset_get_metrics (current_fonts, language);
- p = sample_str;
- while (*p)
- {
- gunichar wc = g_utf8_get_char (p);
- int index = font_set_get_font (¤t_fonts, wc);
- if (!raw_metrics[index])
- raw_metrics[index] = pango_font_get_metrics (current_fonts.fonts[index], language);
-
- if (count == 0)
- *metrics = *raw_metrics[index];
- else
- {
- metrics->ascent = MAX (metrics->ascent, raw_metrics[index]->ascent);
- metrics->descent = MAX (metrics->descent, raw_metrics[index]->descent);
- metrics->approximate_char_width += raw_metrics[index]->approximate_char_width;
- metrics->approximate_digit_width += raw_metrics[index]->approximate_digit_width;
- }
-
- p = g_utf8_next_char (p);
- count++;
- }
-
- for (i=0; i < MAX_FAMILIES; i++)
- if (raw_metrics[i])
- pango_font_metrics_unref (raw_metrics[i]);
-
- metrics->approximate_char_width /= count;
- metrics->approximate_digit_width /= count;
- }
-
- font_set_free (¤t_fonts);
+ g_object_unref (current_fonts);
return metrics;
}
Index: pango/pango-context.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-context.h,v
retrieving revision 1.14
diff -u -p -r1.14 pango-context.h
--- pango/pango-context.h 2001/09/18 20:05:17 1.14
+++ pango/pango-context.h 2001/11/18 01:40:32
@@ -50,7 +50,7 @@ GType pango_context_get_type
#ifdef PANGO_ENABLE_BACKEND
PangoContext *pango_context_new (void);
-void pango_context_add_font_map (PangoContext *context,
+void pango_context_set_font_map (PangoContext *context,
PangoFontMap *font_map);
#endif /* PANGO_ENABLE_BACKEND */
Index: pango/pango-font.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-font.h,v
retrieving revision 1.24
diff -u -p -r1.24 pango-font.h
--- pango/pango-font.h 2001/09/20 12:01:52 1.24
+++ pango/pango-font.h 2001/11/18 01:40:33
@@ -309,6 +309,70 @@ struct _PangoFontClass
PangoLanguage *language);
};
+
+#endif /* PANGO_ENABLE_BACKEND */
+
+/*
+ * PangoFontset
+ */
+
+#define PANGO_TYPE_FONTSET (pango_fontset_get_type ())
+#define PANGO_FONTSET(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONTSET, PangoFontset))
+#define PANGO_IS_FONTSET(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONTSET))
+
+GType pango_fontset_get_type (void) G_GNUC_CONST;
+
+typedef struct _PangoFontset PangoFontset;
+
+PangoFont * pango_fontset_get_font (PangoFontset *fontset,
+ guint wc,
+ PangoLanguage *language);
+PangoFontMetrics *pango_fontset_get_metrics (PangoFontset *fontset,
+ PangoLanguage *language);
+
+#ifdef PANGO_ENABLE_BACKEND
+
+typedef struct _PangoFontsetClass PangoFontsetClass;
+
+#define PANGO_FONTSET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONTSET, PangoFontsetClass))
+#define PANGO_IS_FONTSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FONTSET))
+#define PANGO_FONTSET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONTSET, PangoFontsetClass))
+
+struct _PangoFontset
+{
+ GObject parent_instance;
+};
+
+struct _PangoFontsetClass
+{
+ GObjectClass parent_class;
+
+ PangoFont * (*get_font) (PangoFontset *fontset,
+ guint wc,
+ PangoLanguage *language);
+
+ PangoFontMetrics *(*get_metrics) (PangoFontset *fontset,
+ PangoLanguage *language);
+};
+
+/*
+ * PangoFontsetSimple
+ */
+
+#define PANGO_TYPE_FONTSET_SIMPLE (pango_fontset_simple_get_type ())
+#define PANGO_FONTSET_SIMPLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONTSET_SIMPLE, PangoFontsetSimple))
+#define PANGO_IS_FONTSET_SIMPLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONTSET_SIMPLE))
+
+typedef struct _PangoFontsetSimple PangoFontsetSimple;
+typedef struct _PangoFontsetSimpleClass PangoFontsetSimpleClass;
+
+GType pango_fontset_simple_get_type (void) G_GNUC_CONST;
+
+PangoFontsetSimple * pango_fontset_simple_new (void);
+void pango_fontset_simple_append (PangoFontsetSimple *fontset,
+ PangoFont *font);
+int pango_fontset_simple_size (PangoFontsetSimple *fontset);
+
#endif /* PANGO_ENABLE_BACKEND */
G_END_DECLS
Index: pango/pango-fontmap.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-fontmap.c,v
retrieving revision 1.7
diff -u -p -r1.7 pango-fontmap.c
--- pango/pango-fontmap.c 2001/10/27 20:34:17 1.7
+++ pango/pango-fontmap.c 2001/11/18 01:40:33
@@ -20,7 +20,14 @@
*/
#include "pango-fontmap.h"
+#include "pango-utils.h"
+#include <stdlib.h>
+static void pango_font_map_class_init (PangoFontMapClass *class);
+static PangoFontset *pango_font_map_real_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+
+
GType
pango_font_map_get_type (void)
{
@@ -33,7 +40,7 @@ pango_font_map_get_type (void)
sizeof (PangoFontMapClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
- NULL, /* class_init */
+ (GClassInitFunc) pango_font_map_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (PangoFontMap),
@@ -49,6 +56,13 @@ pango_font_map_get_type (void)
return object_type;
}
+
+static void
+pango_font_map_class_init (PangoFontMapClass *class)
+{
+ class->load_fontset = pango_font_map_real_load_fontset;
+}
+
/**
* pango_font_map_load_font:
* @fontmap: a #PangoFontMap
@@ -84,4 +98,136 @@ pango_font_map_list_families (PangoFontM
g_return_if_fail (fontmap != NULL);
PANGO_FONT_MAP_GET_CLASS (fontmap)->list_families (fontmap, families, n_families);
+}
+
+/**
+ * pango_font_map_load_fontset:
+ * @fontmap: a #PangoFontMap
+ * @desc: a #PangoFontDescription describing the font to load
+ *
+ * Load a set of fonts in the fontmap that can be used to render
+ * a font matching @desc.
+ *
+ * Returns the fontset, or %NULL if no font matched.
+ **/
+PangoFontset *
+pango_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc)
+{
+ g_return_val_if_fail (fontmap != NULL, 0);
+
+ return PANGO_FONT_MAP_GET_CLASS (fontmap)->load_fontset (fontmap, desc);
+}
+
+static void
+pango_font_map_fontset_add_fonts (PangoFontMap *fontmap,
+ PangoFontsetSimple *fonts,
+ PangoFontDescription *desc,
+ char *family)
+{
+ char **aliases;
+ int n_aliases;
+ int j;
+ PangoFont *font;
+
+ pango_lookup_aliases (family,
+ &aliases,
+ &n_aliases);
+
+ if (n_aliases)
+ {
+ for (j = 0; j < n_aliases; j++)
+ {
+ pango_font_description_set_family_static (desc, aliases[j]);
+ font = pango_font_map_load_font (fontmap, desc);
+ if (font)
+ pango_fontset_simple_append (fonts, font);
+ }
+ }
+ else
+ {
+ pango_font_description_set_family_static (desc, family);
+ font = pango_font_map_load_font (fontmap, desc);
+ if (font)
+ pango_fontset_simple_append (fonts, font);
+ }
+}
+
+static PangoFontset *
+pango_font_map_real_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc)
+{
+ PangoFontDescription *tmp_desc = pango_font_description_copy_static (desc);
+ char **families;
+ int i;
+ PangoFontsetSimple *fonts;
+
+ families = g_strsplit (pango_font_description_get_family (desc), ",", -1);
+
+ fonts = pango_fontset_simple_new ();
+
+ for (i = 0; families[i]; i++)
+ pango_font_map_fontset_add_fonts (fontmap,
+ fonts,
+ tmp_desc,
+ families[i]);
+
+ g_strfreev (families);
+ pango_font_description_set_family_static (tmp_desc,
+ pango_font_description_get_family (desc));
+
+ /* The font description was completely unloadable, try with
+ * family == "Sans"
+ */
+ if (pango_fontset_simple_size (fonts) == 0)
+ {
+ char *ctmp1, *ctmp2;
+
+ ctmp1 = pango_font_description_to_string (desc);
+ pango_font_description_set_family_static (tmp_desc, "Sans");
+ ctmp2 = pango_font_description_to_string (tmp_desc);
+
+ g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2);
+ g_free (ctmp1);
+ g_free (ctmp2);
+
+ pango_font_map_fontset_add_fonts (fontmap,
+ fonts,
+ tmp_desc,
+ "Sans");
+ }
+
+ /* We couldn't try with Sans and the specified style. Try Sans Normal
+ */
+ if (pango_fontset_simple_size (fonts) == 0)
+ {
+ char *ctmp1, *ctmp2;
+
+ pango_font_description_set_family_static (tmp_desc, "Sans");
+ ctmp1 = pango_font_description_to_string (tmp_desc);
+ pango_font_description_set_style (tmp_desc, PANGO_STYLE_NORMAL);
+ pango_font_description_set_weight (tmp_desc, PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_variant (tmp_desc, PANGO_VARIANT_NORMAL);
+ pango_font_description_set_stretch (tmp_desc, PANGO_STRETCH_NORMAL);
+ ctmp2 = pango_font_description_to_string (tmp_desc);
+
+ g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2);
+ g_free (ctmp1);
+ g_free (ctmp2);
+
+ pango_font_map_fontset_add_fonts (fontmap,
+ fonts,
+ tmp_desc,
+ "Sans");
+ }
+
+ /* Everything failed, we are screwed, there is no way to continue
+ */
+ if (pango_fontset_simple_size (fonts) == 0)
+ {
+ g_warning ("All font failbacks failed!!!!");
+ exit (1);
+ }
+
+ return PANGO_FONTSET (fonts);
}
Index: pango/pango-fontmap.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-fontmap.h,v
retrieving revision 1.5
diff -u -p -r1.5 pango-fontmap.h
--- pango/pango-fontmap.h 2001/09/18 20:05:17 1.5
+++ pango/pango-fontmap.h 2001/11/18 01:40:33
@@ -32,13 +32,16 @@ G_BEGIN_DECLS
typedef struct _PangoFontMap PangoFontMap;
-GType pango_font_map_get_type (void) G_GNUC_CONST;
-PangoFont *pango_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *desc);
-void pango_font_map_list_families (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
+GType pango_font_map_get_type (void) G_GNUC_CONST;
+PangoFont * pango_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+PangoFontset *pango_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+void pango_font_map_list_families (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families);
+
#ifdef PANGO_ENABLE_BACKEND
#define PANGO_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_MAP, PangoFontMapClass))
@@ -56,11 +59,13 @@ struct _PangoFontMapClass
{
GObjectClass parent_class;
- PangoFont *(*load_font) (PangoFontMap *fontmap,
- const PangoFontDescription *desc);
- void (*list_families) (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
+ PangoFont * (*load_font) (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+ void (*list_families) (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families);
+ PangoFontset *(*load_fontset) (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
};
#endif /* PANGO_ENABLE_BACKEND */
Index: pango/pango-utils.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-utils.c,v
retrieving revision 1.29
diff -u -p -r1.29 pango-utils.c
--- pango/pango-utils.c 2001/11/11 23:36:26 1.29
+++ pango/pango-utils.c 2001/11/18 01:40:34
@@ -48,6 +48,16 @@
#endif
+struct PangoAlias
+{
+ char *alias;
+ int n_families;
+ char **families;
+ gboolean visible; /* Do we want/need this? */
+};
+
+GHashTable *pango_aliases_ht = NULL;
+
/**
* pango_trim_string:
* @str: a string
@@ -557,7 +567,7 @@ read_config_file (const char *filename,
}
if (ferror (file))
- errstring = g_strdup ("g_strerror(errno)");
+ errstring = g_strdup (g_strerror(errno));
error:
@@ -1250,3 +1260,235 @@ pango_get_mirror_char (gunichar c
}
#endif /* HAVE_FRIBIDI */
+
+
+guint
+alias_hash (struct PangoAlias *alias)
+{
+ return g_str_hash (alias->alias);
+}
+
+gboolean
+alias_equal (struct PangoAlias *alias1,
+ struct PangoAlias *alias2)
+{
+ return g_str_equal (alias1->alias,
+ alias2->alias);
+}
+
+
+void
+alias_free (struct PangoAlias *alias)
+{
+ int i;
+ g_free (alias->alias);
+
+ for (i = 0; i < alias->n_families; i++)
+ g_free (alias->families[i]);
+
+ g_free (alias->families);
+
+ g_free (alias);
+}
+
+static void
+read_alias_file (const char *filename)
+{
+ FILE *file;
+
+ GString *line_buffer;
+ GString *tmp_buffer1;
+ GString *tmp_buffer2;
+ char *errstring = NULL;
+ const char *pos;
+ int line = 0;
+ struct PangoAlias alias_key;
+ struct PangoAlias *alias;
+ char **new_families;
+ int n_new;
+ int i;
+
+ file = fopen (filename, "r");
+ if (!file)
+ return;
+
+ line_buffer = g_string_new (NULL);
+ tmp_buffer1 = g_string_new (NULL);
+ tmp_buffer2 = g_string_new (NULL);
+
+ while (pango_read_line (file, line_buffer))
+ {
+ gboolean empty = FALSE;
+ gboolean append = FALSE;
+ line++;
+
+ pos = line_buffer->str;
+ if (!pango_skip_space (&pos))
+ continue;
+
+ if (!pango_scan_word (&pos, tmp_buffer1) ||
+ !pango_skip_space (&pos))
+ {
+ errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
+ goto error;
+ }
+
+ if (*pos == '+')
+ {
+ append = TRUE;
+ pos++;
+ }
+
+ if (*(pos++) != '=')
+ {
+ errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
+ goto error;
+ }
+
+ if (!pango_skip_space (&pos))
+ {
+ empty = TRUE;
+ }
+ else
+ {
+ if (!pango_scan_string (&pos, tmp_buffer2))
+ {
+ errstring = g_strdup ("Error parsing value string");
+ goto error;
+ }
+ if (pango_skip_space (&pos))
+ {
+ errstring = g_strdup ("Junk after value string");
+ goto error;
+ }
+ }
+
+ alias_key.alias = g_ascii_strdown (tmp_buffer1->str, -1);
+
+ /* Remove any existing values */
+ alias = g_hash_table_lookup (pango_aliases_ht, &alias_key);
+
+ if (!alias)
+ {
+ alias = g_new0 (struct PangoAlias, 1);
+ alias->alias = alias_key.alias;
+
+ g_hash_table_insert (pango_aliases_ht,
+ alias, alias);
+ }
+ else
+ g_free (alias_key.alias);
+
+ new_families = g_strsplit (tmp_buffer2->str, ",", -1);
+
+ n_new = 0;
+ while (new_families[n_new])
+ n_new++;
+
+ if (alias->families && append)
+ {
+ alias->families = g_realloc (alias->families,
+ sizeof (char *) *(n_new + alias->n_families));
+ for (i = 0; i < n_new; i++)
+ alias->families[alias->n_families + i] = new_families[i];
+ g_free (new_families);
+ alias->n_families += n_new;
+ }
+ else
+ {
+ for (i = 0; i < alias->n_families; i++)
+ g_free (alias->families[i]);
+ g_free (alias->families);
+
+ alias->families = new_families;
+ alias->n_families = n_new;
+ }
+ }
+
+ if (ferror (file))
+ errstring = g_strdup (g_strerror(errno));
+
+ error:
+
+ if (errstring)
+ {
+ fprintf (stderr, "Pango:%s:%d: %s\n", filename, line, errstring);
+ g_free (errstring);
+ }
+
+ g_string_free (line_buffer, TRUE);
+ g_string_free (tmp_buffer1, TRUE);
+ g_string_free (tmp_buffer2, TRUE);
+
+ fclose (file);
+}
+
+void
+pango_load_aliases (void)
+{
+ char *filename;
+ const char *home;
+
+ pango_aliases_ht = g_hash_table_new_full ((GHashFunc)alias_hash,
+ (GEqualFunc)alias_equal,
+ (GDestroyNotify)alias_free,
+ NULL);
+
+
+ filename = g_strconcat (pango_get_sysconf_subdirectory (),
+ G_DIR_SEPARATOR_S "pango.aliases",
+ NULL);
+ read_alias_file (filename);
+ g_free (filename);
+
+ home = g_get_home_dir ();
+ if (home && *home)
+ {
+ filename = g_strconcat (home,
+ G_DIR_SEPARATOR_S ".pango.aliases",
+ NULL);
+ read_alias_file (filename);
+ g_free (filename);
+ }
+}
+
+
+/**
+ * pango_lookup_aliases:
+ * @fontname: an ascii string
+ * @families: will be set to an array of font family names.
+ * this array is owned by pango and should not be freed.
+ *
+ * Look up all user defined aliases for the alias #fontname.
+ * The resulting font family names will be stored in #families,
+ * and the number of families will be returned.
+ *
+ * Return value: the number of font famillies stored in the #families argument.
+ * This value is owned by Pango and must not be freed.
+ **/
+void
+pango_lookup_aliases (const char *fontname,
+ char ***families,
+ int *n_families)
+{
+ struct PangoAlias alias_key;
+ struct PangoAlias *alias;
+
+ if (pango_aliases_ht == NULL)
+ pango_load_aliases ();
+
+ alias_key.alias = g_ascii_strdown (fontname, -1);
+ alias = g_hash_table_lookup (pango_aliases_ht, &alias_key);
+ g_free (alias_key.alias);
+
+ if (alias)
+ {
+ *families = alias->families;
+ *n_families = alias->n_families;
+ }
+ else
+ {
+ *families = NULL;
+ *n_families = 0;
+ }
+}
Index: pango/pango-utils.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-utils.h,v
retrieving revision 1.14
diff -u -p -r1.14 pango-utils.h
--- pango/pango-utils.h 2001/10/18 19:50:08 1.14
+++ pango/pango-utils.h 2001/11/18 01:40:34
@@ -38,6 +38,9 @@ gboolean pango_scan_int (const cha
#ifdef PANGO_ENABLE_BACKEND
char * pango_config_key_get (const char *key);
+void pango_lookup_aliases (const char *fontname,
+ char ***families,
+ int *n_families);
#endif /* PANGO_ENABLE_BACKEND */
/* Functions for parsing textual representations
Index: pango/pangoft2-fontcache.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoft2-fontcache.c,v
retrieving revision 1.8
diff -u -p -r1.8 pangoft2-fontcache.c
--- pango/pangoft2-fontcache.c 2000/12/21 09:54:01 1.8
+++ pango/pangoft2-fontcache.c 2001/11/18 01:40:35
@@ -66,7 +66,7 @@ free_cache_entry (PangoFT2OA *oa,
error = FT_Done_Face (entry->face);
if (error != FT_Err_Ok)
g_warning ("Error from FT_Done_Face: %s",
- pango_ft2_ft_strerror (error));
+ _pango_ft2_ft_strerror (error));
g_free (entry);
}
@@ -215,7 +215,7 @@ pango_ft2_font_cache_load (PangoFT2FontC
if (error != FT_Err_Ok)
{
g_warning ("Error from FT_Open_Face: %s",
- pango_ft2_ft_strerror (error));
+ _pango_ft2_ft_strerror (error));
return NULL;
}
Index: pango/pangoft2-fontmap.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoft2-fontmap.c,v
retrieving revision 1.23
diff -u -p -r1.23 pangoft2-fontmap.c
--- pango/pangoft2-fontmap.c 2001/11/02 14:21:19 1.23
+++ pango/pangoft2-fontmap.c 2001/11/18 01:40:36
@@ -36,6 +36,8 @@
#include "pango-utils.h"
#include "pangoft2-private.h"
+#include "mini-xft/MiniXftFreetype.h"
+
#ifdef G_OS_WIN32
#define STRICT
#include <windows.h>
@@ -45,41 +47,46 @@
#define PANGO_FT2_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FT2_FONT_MAP, PangoFT2FontMap))
#define PANGO_FT2_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FT2_FONT_MAP))
-typedef struct _PangoFT2Family PangoFT2Family;
typedef struct _PangoFT2FontMap PangoFT2FontMap;
typedef struct _PangoFT2SizeInfo PangoFT2SizeInfo;
+typedef struct _PangoFT2PatternSet PangoFT2PatternSet;
/* Number of freed fonts */
#define MAX_FREED_FONTS 16
+struct _PangoFT2Family
+{
+ PangoFontFamily parent_instance;
+
+ PangoFT2FontMap *fontmap;
+ char *family_name;
+
+ PangoFT2Face **faces;
+ int n_faces; /* -1 == uninitialized */
+};
+
+
struct _PangoFT2FontMap
{
PangoFontMap parent_instance;
FT_Library library;
-
- PangoFT2FontCache *font_cache;
- GQueue *freed_fonts;
-
- /* Maps Pango family names to PangoFT2FamilyEntry structs */
- GHashTable *families;
- /* Maps the family and style of a face to a PangoFT2OA struct */
- GHashTable *faces;
+ GHashTable *fontset_hash; /* Maps PangoFontDescription -> PangoXftFontSet */
+ GHashTable *coverage_hash; /* Maps font file name -> PangoCoverage */
- int n_fonts;
+ GHashTable *fonts; /* Maps XftPattern -> PangoFT2Font */
+ GQueue *freed_fonts; /* Fonts in fonts that has been freed */
- double resolution; /* (points / pixel) * PANGO_SCALE */
+ /* List of all families availible */
+ PangoFT2Family **families;
+ int n_families; /* -1 == uninitialized */
};
-struct _PangoFT2Family
+struct _PangoFT2PatternSet
{
- PangoFontFamily parent_instance;
-
- char *family_name;
-
- /* List of PangoFT2FontEntry structs */
- GSList *font_entries;
+ int n_patterns;
+ MiniXftPattern **patterns;
};
#define PANGO_FT2_TYPE_FAMILY (pango_ft2_family_get_type ())
@@ -93,33 +100,27 @@ struct _PangoFT2Family
static GType pango_ft2_font_map_get_type (void);
GType pango_ft2_family_get_type (void);
GType pango_ft2_face_get_type (void);
-
-static void pango_ft2_font_map_init (PangoFT2FontMap *fontmap);
-static void pango_ft2_font_map_class_init (PangoFontMapClass *class);
+static void pango_ft2_font_map_init (PangoFT2FontMap *fontmap);
+static void pango_ft2_font_map_class_init (PangoFontMapClass *class);
+static void pango_ft2_font_map_finalize (GObject *object);
+static PangoFont * pango_ft2_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description);
+static PangoFontset *pango_ft2_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+static void pango_ft2_font_set_free (PangoFT2PatternSet *font_set);
+static void pango_ft2_font_map_list_families (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families);
+static void pango_ft2_font_map_cache_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+static void pango_ft2_font_map_cache_clear (PangoFT2FontMap *ft2fontmap);
-static void pango_ft2_font_map_finalize (GObject *object);
-static PangoFont *pango_ft2_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description);
-static void pango_ft2_font_map_list_families (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
-
-static void pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap);
-
-static void pango_ft2_font_map_read_aliases (PangoFT2FontMap *ft2fontmap);
-
-static void pango_ft2_insert_face (PangoFT2FontMap *fontmap,
- FT_Face face,
- const char *path,
- int face_index);
-
static PangoFontClass *parent_class; /* Parent class structure for PangoFT2FontMap */
static PangoFT2FontMap *pango_ft2_global_fontmap = NULL;
-static char **pango_ft2_font_directories = NULL;
static GType
pango_ft2_font_map_get_type (void)
@@ -149,131 +150,135 @@ pango_ft2_font_map_get_type (void)
return object_type;
}
-static void
-pango_ft2_font_map_init (PangoFT2FontMap *ft2fontmap)
-{
- ft2fontmap->families = g_hash_table_new (g_str_hash, g_str_equal);
- ft2fontmap->faces = g_hash_table_new ((GHashFunc)pango_font_description_hash,
- (GEqualFunc)pango_font_description_equal);
- ft2fontmap->n_fonts = 0;
-}
-
static void
-pango_ft2_font_map_class_init (PangoFontMapClass *class)
+pango_ft2_font_set_free (PangoFT2PatternSet *font_set)
{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- char *font_path;
-
- parent_class = g_type_class_peek_parent (class);
+ int i;
- object_class->finalize = pango_ft2_font_map_finalize;
- class->load_font = pango_ft2_font_map_load_font;
- class->list_families = pango_ft2_font_map_list_families;
+ for (i = 0; i < font_set->n_patterns; i++)
+ MiniXftPatternDestroy (font_set->patterns[i]);
- font_path = pango_config_key_get ("PangoFT2/FontPath");
+ g_free (font_set);
+}
- if (!font_path)
- {
- font_path = g_build_filename (pango_get_lib_subdirectory (),
- "ft2fonts",
- NULL);
+static guint
+pango_ft2_pattern_hash (MiniXftPattern *pattern)
+{
+ char *str;
+ int i;
+ double d;
+ guint hash = 0;
+
+ MiniXftPatternGetString (pattern, XFT_FILE, 0, &str);
+ if (str)
+ hash = g_str_hash (str);
-#ifdef G_OS_WIN32
- {
- char win_dir[100];
- char *tmp_str;
+ if (MiniXftPatternGetInteger (pattern, XFT_INDEX, 0, &i) == MiniXftResultMatch)
+ hash ^= i;
- GetWindowsDirectory (win_dir, sizeof (win_dir));
- tmp_str = g_build_filename (font_path,
- win_dir,
- "fonts",
- NULL);
- g_free (font_path);
- font_path = tmp_str;
- }
-#endif
- }
+ if (MiniXftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &d) == MiniXftResultMatch)
+ hash ^= (guint) (d*1000.0);
- pango_ft2_font_directories = pango_split_file_list (font_path);
- g_free (font_path);
+ return hash;
}
static gboolean
-pango_ft2_is_font_file (const char *name)
+pango_ft2_pattern_equal (MiniXftPattern *pattern1,
+ MiniXftPattern *pattern2)
{
- int len;
+ char *file1, *file2;
+ int index1, index2;
+ double size1, size2;
+ MiniXftResult res1, res2;
+ int int1, int2;
+ Bool bool1, bool2;
+
+ MiniXftPatternGetString (pattern1, XFT_FILE, 0, &file1);
+ MiniXftPatternGetString (pattern2, XFT_FILE, 0, &file2);
- len = strlen (name);
- if (len > 4 &&
- (g_ascii_strncasecmp (&name[len-4], ".pfa", 4) == 0 ||
- g_ascii_strncasecmp (&name[len-4], ".pfb", 4) == 0 ||
- g_ascii_strncasecmp (&name[len-4], ".ttf", 4) == 0 ||
- g_ascii_strncasecmp (&name[len-4], ".ttc", 4) == 0))
- return TRUE;
+ g_assert (file1 != NULL && file2 != NULL);
- return FALSE;
+ if (strcmp (file1, file2) != 0)
+ return FALSE;
+
+ if (MiniXftPatternGetInteger (pattern1, XFT_INDEX, 0, &index1) != MiniXftResultMatch)
+ return FALSE;
+
+ if (MiniXftPatternGetInteger (pattern2, XFT_INDEX, 0, &index2) != MiniXftResultMatch)
+ return FALSE;
+
+ if (index1 != index2)
+ return FALSE;
+
+ if (MiniXftPatternGetDouble (pattern1, XFT_PIXEL_SIZE, 0, &size1) != MiniXftResultMatch)
+ return FALSE;
+
+ if (MiniXftPatternGetDouble (pattern2, XFT_PIXEL_SIZE, 0, &size2) != MiniXftResultMatch)
+ return FALSE;
+
+ if (size1 != size2)
+ return FALSE;
+
+ res1 = MiniXftPatternGetInteger (pattern1, XFT_RGBA, 0, &int1);
+ res2 = MiniXftPatternGetInteger (pattern2, XFT_RGBA, 0, &int2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2))
+ return FALSE;
+
+ res1 = MiniXftPatternGetBool (pattern1, XFT_ANTIALIAS, 0, &bool1);
+ res2 = MiniXftPatternGetBool (pattern2, XFT_ANTIALIAS, 0, &bool2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && bool1 != bool2))
+ return FALSE;
+
+ res1 = MiniXftPatternGetBool (pattern1, XFT_MINSPACE, 0, &bool1);
+ res2 = MiniXftPatternGetBool (pattern2, XFT_MINSPACE, 0, &bool2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && bool1 != bool2))
+ return FALSE;
+
+ res1 = MiniXftPatternGetInteger (pattern1, XFT_SPACING, 0, &int1);
+ res2 = MiniXftPatternGetInteger (pattern2, XFT_SPACING, 0, &int2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2))
+ return FALSE;
+
+ res1 = MiniXftPatternGetInteger (pattern1, XFT_CHAR_WIDTH, 0, &int1);
+ res2 = MiniXftPatternGetInteger (pattern2, XFT_CHAR_WIDTH, 0, &int2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2))
+ return FALSE;
+
+ return TRUE;
}
-static gboolean
-pango_ft2_scan_directory (const char *path,
- PangoFT2FontMap *ft2fontmap)
+
+static void
+pango_ft2_font_map_init (PangoFT2FontMap *ft2fontmap)
{
- DIR *dir;
- struct dirent *entry;
- char *fullname;
- FT_Face face;
- FT_Error error;
- int i;
- gboolean found_font = FALSE;
- dir = opendir (path);
- if (!dir)
- /* Don't warn; it's OK to have nonexistent entries in the font path */
- return FALSE;
+ ft2fontmap->fonts =
+ g_hash_table_new ((GHashFunc)pango_ft2_pattern_hash,
+ (GEqualFunc)pango_ft2_pattern_equal);
+ ft2fontmap->fontset_hash =
+ g_hash_table_new_full ((GHashFunc)pango_font_description_hash,
+ (GEqualFunc)pango_font_description_equal,
+ (GDestroyNotify)pango_font_description_free,
+ (GDestroyNotify)pango_ft2_font_set_free);
+
+ ft2fontmap->coverage_hash =
+ g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)pango_coverage_unref);
+ ft2fontmap->freed_fonts = g_queue_new ();
+}
- while ((entry = readdir (dir)) != NULL)
- {
- fullname = g_build_filename (path, entry->d_name, NULL);
- if (pango_ft2_is_font_file (fullname))
- {
- error = FT_New_Face (ft2fontmap->library, fullname, 0, &face);
- if (error != FT_Err_Ok)
- g_warning ("Error loading font from '%s': %s",
- fullname, pango_ft2_ft_strerror (error));
- else
- {
- if (face->face_flags & FT_FACE_FLAG_SCALABLE)
- {
- pango_ft2_insert_face (ft2fontmap, face, fullname, 0);
- found_font = TRUE;
- }
-
- for (i = 1; i < face->num_faces; i++)
- {
- error = FT_Done_Face (face);
- if (error != FT_Err_Ok)
- g_warning ("Error from FT_Done_Face: %s",
- pango_ft2_ft_strerror (error));
- error = FT_New_Face (ft2fontmap->library, fullname, i, &face);
- if (error != FT_Err_Ok)
- g_warning ("Error loading font %d from '%s': %s",
- i, fullname, pango_ft2_ft_strerror (error));
- else if (face->face_flags & FT_FACE_FLAG_SCALABLE)
- {
- pango_ft2_insert_face (ft2fontmap, face, fullname, i);
- found_font = TRUE;
- }
- }
- error = FT_Done_Face (face);
- if (error != FT_Err_Ok)
- g_warning ("Error from FT_Done_Face: %s",
- pango_ft2_ft_strerror (error));
- }
- }
- g_free (fullname);
- }
- closedir (dir);
- return found_font;
+static void
+pango_ft2_font_map_class_init (PangoFontMapClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = pango_ft2_font_map_finalize;
+ class->load_font = pango_ft2_font_map_load_font;
+ class->load_fontset = pango_ft2_font_map_load_fontset;
+ class->list_families = pango_ft2_font_map_list_families;
}
/**
@@ -288,9 +293,7 @@ pango_ft2_scan_directory (const char
PangoFontMap *
pango_ft2_font_map_for_display (void)
{
- char **tmp_list;
FT_Error error;
- gboolean read_font;
/* Make sure that the type system is initialized */
g_type_init ();
@@ -304,27 +307,10 @@ pango_ft2_font_map_for_display (void)
if (error != FT_Err_Ok)
{
g_warning ("Error from FT_Init_FreeType: %s",
- pango_ft2_ft_strerror (error));
+ _pango_ft2_ft_strerror (error));
return NULL;
}
- pango_ft2_global_fontmap->font_cache = pango_ft2_font_cache_new (pango_ft2_global_fontmap->library);
- pango_ft2_global_fontmap->freed_fonts = g_queue_new ();
-
- tmp_list = pango_ft2_font_directories;
-
- read_font = FALSE;
- while (*tmp_list)
- {
- read_font |= pango_ft2_scan_directory ((const char *) *tmp_list, pango_ft2_global_fontmap);
- tmp_list++;
- }
-
- if (!read_font)
- g_warning ("No fonts found by pangoft2. Things will probably not work");
-
- pango_ft2_font_map_read_aliases (pango_ft2_global_fontmap);
-
return PANGO_FONT_MAP (pango_ft2_global_fontmap);
}
@@ -336,560 +322,288 @@ pango_ft2_font_map_for_display (void)
void
pango_ft2_shutdown_display (void)
{
- pango_ft2_fontmap_cache_clear (pango_ft2_global_fontmap);
+ pango_ft2_font_map_cache_clear (pango_ft2_global_fontmap);
g_object_unref (G_OBJECT (pango_ft2_global_fontmap));
pango_ft2_global_fontmap = NULL;
}
+
static void
pango_ft2_font_map_finalize (GObject *object)
{
PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (object);
- g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);
g_queue_free (ft2fontmap->freed_fonts);
+ g_hash_table_destroy (ft2fontmap->fontset_hash);
+ g_hash_table_destroy (ft2fontmap->coverage_hash);
- pango_ft2_font_cache_free (ft2fontmap->font_cache);
-
FT_Done_FreeType (ft2fontmap->library);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-static void
-list_families_foreach (gpointer key, gpointer value, gpointer user_data)
+/* Add a mapping from xfont->font_pattern to xfont */
+void
+_pango_ft2_font_map_add (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font)
{
- GSList **list = user_data;
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *) fontmap;
- *list = g_slist_prepend (*list, value);
+ g_hash_table_insert (ft2fontmap->fonts,
+ ft2font->font_pattern,
+ ft2font);
}
+/* Remove mapping from xfont->font_pattern to xfont */
+void
+_pango_ft2_font_map_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font)
+{
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *) fontmap;
+
+ g_hash_table_remove (ft2fontmap->fonts,
+ ft2font->font_pattern);
+}
+
static void
pango_ft2_font_map_list_families (PangoFontMap *fontmap,
PangoFontFamily ***families,
int *n_families)
{
- GSList *family_list = NULL;
- GSList *tmp_list;
PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
-
- if (!n_families)
- return;
-
- g_hash_table_foreach (ft2fontmap->families, list_families_foreach, &family_list);
-
- *n_families = g_slist_length (family_list);
+ MiniXftFontSet *fontset;
+ int i;
- if (families)
+ if (ft2fontmap->n_families < 0)
{
- int i = 0;
-
- *families = g_new (PangoFontFamily *, *n_families);
+ fontset = MiniXftListFonts ((Display *)1, 0,
+ XFT_CORE, MiniXftTypeBool, False,
+ XFT_ENCODING, MiniXftTypeString, "iso10646-1",
+ NULL,
+ XFT_FAMILY,
+ NULL);
+
+ ft2fontmap->n_families = fontset->nfont;
+ ft2fontmap->families = g_new (PangoFT2Family *, ft2fontmap->n_families);
- tmp_list = family_list;
- while (tmp_list)
+ for (i = 0; i < fontset->nfont; i++)
{
- (*families)[i] = tmp_list->data;
- i++;
- tmp_list = tmp_list->next;
+ char *s;
+ MiniXftResult res;
+
+ res = MiniXftPatternGetString (fontset->fonts[i], XFT_FAMILY, 0, &s);
+ g_assert (res == MiniXftResultMatch);
+
+ ft2fontmap->families[i] = g_object_new (PANGO_FT2_TYPE_FAMILY, NULL);
+ ft2fontmap->families[i]->family_name = g_strdup (s);
+ ft2fontmap->families[i]->fontmap = ft2fontmap;
}
+
+ MiniXftFontSetDestroy (fontset);
}
+
+ if (n_families)
+ *n_families = ft2fontmap->n_families;
- g_slist_free (family_list);
+ if (families)
+ *families = g_memdup (ft2fontmap->families, ft2fontmap->n_families * sizeof (PangoFontFamily *));
}
-static PangoFT2Family *
-pango_ft2_get_family (PangoFT2FontMap *ft2fontmap,
- const char *family_name)
+static int
+pango_ft2_convert_weight (PangoWeight pango_weight)
{
- PangoFT2Family *ft2family = g_hash_table_lookup (ft2fontmap->families, family_name);
- if (!ft2family)
- {
- ft2family = g_object_new (PANGO_FT2_TYPE_FAMILY, NULL);
- ft2family->family_name = g_strdup (family_name);
- ft2family->font_entries = NULL;
-
- g_hash_table_insert (ft2fontmap->families, ft2family->family_name, ft2family);
- }
-
- return ft2family;
+ int weight;
+
+ if (pango_weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2)
+ weight = XFT_WEIGHT_LIGHT;
+ else if (pango_weight < (PANGO_WEIGHT_NORMAL + 600) / 2)
+ weight = XFT_WEIGHT_MEDIUM;
+ else if (pango_weight < (600 + PANGO_WEIGHT_BOLD) / 2)
+ weight = XFT_WEIGHT_DEMIBOLD;
+ else if (pango_weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2)
+ weight = XFT_WEIGHT_BOLD;
+ else
+ weight = XFT_WEIGHT_BLACK;
+
+ return weight;
}
-static PangoFont *
-pango_ft2_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description)
+static int
+pango_ft2_convert_slant (PangoStyle pango_style)
{
- PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
- PangoFT2Family *family_entry;
- PangoFont *result = NULL;
- GSList *tmp_list;
- gchar *name;
-
- g_return_val_if_fail (description != NULL, NULL);
+ int slant;
- name = g_ascii_strdown (pango_font_description_get_family (description), -1);
-
- family_entry = g_hash_table_lookup (ft2fontmap->families, name);
- g_free (name);
+ if (pango_style == PANGO_STYLE_ITALIC)
+ slant = XFT_SLANT_ITALIC;
+ else if (pango_style == PANGO_STYLE_OBLIQUE)
+ slant = XFT_SLANT_OBLIQUE;
+ else
+ slant = XFT_SLANT_ROMAN;
- if (family_entry)
- {
- PangoFT2Face *best_match = NULL;
-
- tmp_list = family_entry->font_entries;
- while (tmp_list)
- {
- PangoFT2Face *face = tmp_list->data;
-
- if (pango_font_description_better_match (description,
- best_match ? best_match->description : NULL,
- face->description))
- best_match = face;
-
- tmp_list = tmp_list->next;
- }
-
- if (best_match)
- {
- GSList *tmp_list = best_match->cached_fonts;
-
- gint size = pango_font_description_get_size (description);
-
- while (tmp_list)
- {
- PangoFT2Font *ft2font = tmp_list->data;
-
- if (ft2font->size == size)
- {
- result = (PangoFont *)ft2font;
-
- g_object_ref (G_OBJECT (result));
- if (ft2font->in_cache)
- pango_ft2_fontmap_cache_remove (fontmap, ft2font);
- break;
- }
- tmp_list = tmp_list->next;
- }
-
- if (!result)
- {
- PangoFT2Font *ft2font =
- (PangoFT2Font *) pango_ft2_load_font (fontmap,
- best_match->open_args,
- best_match->face_indices,
- best_match->n_fonts,
- size);
-
- ft2font->fontmap = fontmap;
- ft2font->entry = best_match;
- best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, ft2font);
-
- result = (PangoFont *)ft2font;
- }
- }
- }
-
- return result;
+ return slant;
}
-static gboolean
-pango_ft2_font_map_read_alias_file (PangoFT2FontMap *ft2fontmap,
- const char *filename)
-{
- FILE *infile;
- int lineno = 0;
- int nfaces;
- int i;
- PangoFT2Face *face = NULL;
- gchar **faces;
- gboolean ret_val = FALSE;
-
- infile = fopen (filename, "r");
- if (infile)
- {
- GString *line_buf = g_string_new (NULL);
- GString *tmp_buf = g_string_new (NULL);
-
- while (pango_read_line (infile, line_buf))
- {
- PangoFT2Family *family_entry;
- PangoStyle style;
- PangoVariant variant;
- PangoWeight weight;
- PangoStretch stretch;
-
- const char *p = line_buf->str;
-
- lineno++;
-
- if (!pango_skip_space (&p))
- continue;
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- face = g_object_new (PANGO_FT2_TYPE_FACE, NULL);
- face->n_fonts = 0;
- face->open_args = NULL;
- face->face_indices = NULL;
-
- face->description = pango_font_description_new ();
-
- g_string_ascii_down (tmp_buf);
- pango_font_description_set_family (face->description, tmp_buf->str);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- if (!pango_parse_style (tmp_buf->str, &style, TRUE))
- goto error;
- pango_font_description_set_style (face->description, style);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- if (!pango_parse_variant (tmp_buf->str, &variant, TRUE))
- goto error;
- pango_font_description_set_variant (face->description, variant);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- if (!pango_parse_weight (tmp_buf->str, &weight, TRUE))
- goto error;
- pango_font_description_set_weight (face->description, weight);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- if (!pango_parse_stretch (tmp_buf->str, &stretch, TRUE))
- goto error;
- pango_font_description_set_stretch (face->description, stretch);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- /* Remove excess whitespace and check for complete fields */
-
- faces = g_strsplit (tmp_buf->str, ",", -1);
- nfaces = 0;
- for (i = 0; faces[i]; i++)
- {
- char *trimmed = pango_trim_string (faces[i]);
- g_free (faces[i]);
- faces[i] = trimmed;
- nfaces++;
- }
-
- face->open_args = g_new (FT_Open_Args *, nfaces);
- face->face_indices = g_new (FT_Long, nfaces);
-
- for (i = 0; i < nfaces; i++)
- {
- PangoFontDescription *desc = pango_font_description_copy_static (face->description);
- PangoFT2OA *oa;
-
- pango_font_description_set_family_static (desc, faces[i]);
- oa = g_hash_table_lookup (ft2fontmap->faces, desc);
- if (!oa)
- g_warning ("Face '%s' on line %d of '%s' not found", faces[i], lineno, filename);
- else
- {
- face->open_args[face->n_fonts] = oa->open_args;
- face->face_indices[face->n_fonts] = oa->face_index;
- face->n_fonts++;
- }
-
- pango_font_description_free (desc);
- }
-
- g_strfreev (faces);
-
- /* Insert the font entry into our structures */
- family_entry = pango_ft2_get_family (ft2fontmap, pango_font_description_get_family (face->description));
- family_entry->font_entries = g_slist_prepend (family_entry->font_entries, face);
- ft2fontmap->n_fonts++;
-
- /* Save space by consolidating duplicated string */
- pango_font_description_set_family_static (face->description, family_entry->family_name);
- face->cached_fonts = NULL;
- face->coverage = NULL;
- }
-
- if (ferror (infile))
- g_warning ("Error reading file '%s': %s", filename, g_strerror(errno));
-
- ret_val = TRUE;
- goto out;
-
- error:
- if (face)
- {
- if (face->open_args)
- g_free (face->open_args);
- if (face->face_indices)
- g_free (face->face_indices);
- if (face->description)
- pango_font_description_free (face->description);
- g_free (face);
- }
-
- g_warning ("Error parsing line %d of alias file '%s'", lineno, filename);
-
- out:
- g_string_free (tmp_buf, TRUE);
- g_string_free (line_buf, TRUE);
+static MiniXftPattern *
+pango_ft2_make_pattern (const PangoFontDescription *description)
+{
+ MiniXftPattern *pattern;
+ PangoStyle pango_style;
+ int slant;
+ int weight;
+
+ pango_style = pango_font_description_get_style (description);
- fclose (infile);
- }
+ slant = pango_ft2_convert_slant (pango_style);
+ weight = pango_ft2_convert_weight (pango_font_description_get_weight (description));
+
+ /* To fool Xft into not munging glyph indices, we open it as glyphs-fontspecific
+ * then set the encoding ourself
+ */
+ pattern = MiniXftPatternBuild (0,
+ XFT_ENCODING, MiniXftTypeString, "glyphs-fontspecific",
+ XFT_CORE, MiniXftTypeBool, False,
+ XFT_FAMILY, MiniXftTypeString, pango_font_description_get_family (description),
+ XFT_WEIGHT, MiniXftTypeInteger, weight,
+ XFT_SLANT, MiniXftTypeInteger, slant,
+ XFT_SIZE, MiniXftTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE,
+ NULL);
- return ret_val;
+ return pattern;
}
-static void
-pango_ft2_font_map_read_aliases (PangoFT2FontMap *ft2fontmap)
+static PangoFont *
+pango_ft2_font_map_new_font (PangoFontMap *fontmap,
+ MiniXftPattern *match)
{
- char **files;
- char *files_str = pango_config_key_get ("PangoFT2/AliasFiles");
- int n;
- gboolean read_aliasfile;
-
- if (!files_str)
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
+ PangoFT2Font *font;
+
+ /* Look up cache */
+ font = g_hash_table_lookup (ft2fontmap->fonts, match);
+
+ if (font)
{
- const char *home = g_get_home_dir ();
- char *file1 = NULL;
- char *file2;
-
- if (home && *home)
- file1 = g_build_filename (home, ".pangoft2_aliases", NULL);
+ /* Revive fonts from cache */
+ if (font->in_cache)
+ pango_ft2_font_map_cache_remove (fontmap, font);
- file2 = g_build_filename (pango_get_sysconf_subdirectory (),
- "pangoft2.aliases",
- NULL);
-
- files_str = g_build_path (G_SEARCHPATH_SEPARATOR_S,
- file1 ? file1 : file2,
- file1 ? file2 : NULL,
- NULL);
-
- g_free (file1);
- g_free (file2);
+ return (PangoFont *)g_object_ref (G_OBJECT(font));
}
-
- files = pango_split_file_list (files_str);
-
- n = 0;
- while (files[n])
- n++;
-
-
- read_aliasfile = FALSE;
- while (n-- > 0)
- read_aliasfile |= pango_ft2_font_map_read_alias_file (ft2fontmap, files[n]);
-
- if (!read_aliasfile)
- g_warning ("Didn't read any pango ft2 fontalias file. Things will probably not work.");
-
- g_strfreev (files);
- g_free (files_str);
+ return (PangoFont *)_pango_ft2_font_new (fontmap, MiniXftPatternDuplicate (match));
}
-#if DEBUGGING
-static void
-pango_print_desc (PangoFontDescription *desc)
+static PangoFont *
+pango_ft2_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description)
{
- PangoStyle style = pango_font_description_get_style (desc);
- PangoVariant variant = pango_font_description_get_variant (desc);
- PangoWeight weight = pango_font_description_get_weight (desc);
- PangoStretch stretch = pango_font_description_get_stretch (desc);
-
- g_print ("%s%s%s%s%s",
- pango_font_description_get_family (desc),
- (style == PANGO_STYLE_NORMAL ? "" :
- (style == PANGO_STYLE_OBLIQUE ? " OBLIQUE" :
- (style == PANGO_STYLE_ITALIC ? " ITALIC" : " ???"))),
- (variant == PANGO_VARIANT_NORMAL ? "" :
- (variant == PANGO_VARIANT_SMALL_CAPS ? " SMALL CAPS" : "???")),
- (weight >= (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2 &&
- weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2 ? "" :
- (weight < (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2 ? " ULTRALIGHT" :
- (weight >= (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2 &&
- weight < (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2 ? " LIGHT" :
- (weight >= (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2 &&
- weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2 ? " BOLD" :
- (weight >= (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2 &&
- weight < (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY) / 2 ? " ULTRABOLD" :
- " HEAVY"))))),
- (stretch == PANGO_STRETCH_ULTRA_CONDENSED ? " ULTRA CONDENSED" :
- (stretch == PANGO_STRETCH_EXTRA_CONDENSED ? " EXTRA CONDENSED" :
- (stretch == PANGO_STRETCH_CONDENSED ? " CONDENSED" :
- (stretch == PANGO_STRETCH_SEMI_CONDENSED ? " SEMI CONDENSED" :
- (stretch == PANGO_STRETCH_NORMAL ? "" :
- (stretch == PANGO_STRETCH_SEMI_EXPANDED ? " SEMI EXPANDED" :
- (stretch == PANGO_STRETCH_EXPANDED ? " EXPANDED" :
- (stretch == PANGO_STRETCH_EXTRA_EXPANDED ? " EXTRA EXPANDED" :
- (stretch == PANGO_STRETCH_ULTRA_EXPANDED ? " ULTRA EXPANDED" : " ???"))))))))));
-}
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
+ MiniXftPattern *pattern, *match;
+ MiniXftResult res;
-static void
-pango_ft2_print_oa (PangoFT2OA *oa)
-{
- g_print ("%s:%ld", oa->open_args->pathname, oa->face_index);
-}
+ pattern = pango_ft2_make_pattern (description);
+
+ match = MiniXftFontMatch ((Display *)1, 0, pattern, &res);
+
+ MiniXftPatternDestroy (pattern);
+
+ if (match)
+ return pango_ft2_font_map_new_font (fontmap, match);
-#endif
+ return NULL;
+}
-static void
-pango_ft2_insert_face (PangoFT2FontMap *ft2fontmap,
- FT_Face face,
- const char *path,
- int face_index)
+static PangoFontset *
+pango_ft2_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc)
{
- PangoFontDescription *description;
- char *family_name;
- PangoStyle style;
- PangoVariant variant;
- PangoWeight weight;
- PangoStretch stretch;
- GSList *tmp_list;
- PangoFT2Family *family_entry;
- PangoFT2Face *face_entry;
- PangoFT2OA *oa;
- FT_Open_Args *open_args;
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
+ MiniXftPattern *pattern, *pattern_copy;
+ MiniXftPattern *match;
+ int i;
+ char *family, *family_res;
+ MiniXftResult res;
+ int id;
+ PangoFT2PatternSet *patterns;
+ int max_patterns;
+ PangoFontsetSimple *simple;
- family_name = g_ascii_strdown (face->family_name, -1);
+ patterns = g_hash_table_lookup (ft2fontmap->fontset_hash, desc);
- if (face->style_flags & FT_STYLE_FLAG_ITALIC)
- style = PANGO_STYLE_ITALIC;
- else
- style = PANGO_STYLE_NORMAL;
-
- variant = PANGO_VARIANT_NORMAL;
+ if (patterns == NULL)
+ {
+ pattern = pango_ft2_make_pattern (desc);
- if (face->style_flags & FT_STYLE_FLAG_BOLD)
- weight = PANGO_WEIGHT_BOLD;
- else
- weight = PANGO_WEIGHT_NORMAL;
+ MiniXftConfigSubstitute (pattern);
+ MiniXftDefaultSubstitute ((Display *)1, 0, pattern);
- stretch = PANGO_STRETCH_NORMAL;
+ pattern_copy = MiniXftPatternDuplicate (pattern);
- if (face->style_name)
- {
- gchar **styles = g_strsplit (face->style_name, " ", 0);
- gint i = 0;
+ patterns = g_new (PangoFT2PatternSet, 1);
+ patterns->n_patterns = 0;
+ max_patterns = 5;
+ patterns->patterns = g_new (MiniXftPattern *, max_patterns);
- while (styles[i])
+ MiniXftInit (0);
+ MiniXftInitFtLibrary ();
+
+ match = NULL;
+ id = 0;
+ while (MiniXftPatternGetString (pattern, XFT_FAMILY, id++, &family) == MiniXftResultMatch)
{
- (void) (pango_parse_style (styles[i], &style, FALSE) ||
- pango_parse_variant (styles[i], &variant, FALSE) ||
- pango_parse_weight (styles[i], &weight, FALSE) ||
- pango_parse_stretch (styles[i], &stretch, FALSE));
- i++;
- }
- g_strfreev (styles);
- }
-
-#if 0
- PING ((""));
- pango_print_desc (description);
-#endif
+ MiniXftPatternDel (pattern_copy, XFT_FAMILY);
+ MiniXftPatternAddString (pattern_copy, XFT_FAMILY, family);
- family_entry = pango_ft2_get_family (ft2fontmap, family_name);
- g_free (family_name);
-
- tmp_list = family_entry->font_entries;
- while (tmp_list)
- {
- face_entry = tmp_list->data;
+ match = MiniXftFontSetMatch (&_MiniXftFontSet, 1, pattern_copy, &res);
+
+ if (match &&
+ MiniXftPatternGetString (match, XFT_FAMILY, 0, &family_res) == MiniXftResultMatch &&
+ g_ascii_strcasecmp (family, family_res) == 0)
+ {
+ if (patterns->n_patterns == max_patterns)
+ {
+ max_patterns *= 2;
+ patterns->patterns = g_realloc (patterns->patterns,
+ sizeof(MiniXftPattern *) * max_patterns);
+ }
- if (pango_font_description_get_style (face_entry->description) == style &&
- pango_font_description_get_weight (face_entry->description) == weight &&
- pango_font_description_get_stretch (face_entry->description) == stretch &&
- pango_font_description_get_variant (face_entry->description) == variant)
+ patterns->patterns[patterns->n_patterns++] = match;
+ match = NULL;
+ }
+ if (match)
+ MiniXftPatternDestroy (match);
+ }
+
+ if (patterns->n_patterns == 0)
{
-#if 0
- PING ((" family and description matched (!)"));
-#endif
- return;
+ match = MiniXftFontSetMatch (&_MiniXftFontSet, 1, pattern, &res);
+ patterns->patterns[patterns->n_patterns++] = match;
}
-
- tmp_list = tmp_list->next;
- }
- description = pango_font_description_new ();
- pango_font_description_set_family_static (description, family_entry->family_name);
- pango_font_description_set_style (description, style);
- pango_font_description_set_weight (description, weight);
- pango_font_description_set_stretch (description, stretch);
- pango_font_description_set_variant (description, variant);
+ MiniXftPatternDestroy (pattern);
+ MiniXftPatternDestroy (pattern_copy);
- oa = g_hash_table_lookup (ft2fontmap->faces, description);
- if (!oa)
- {
- oa = g_new (PangoFT2OA, 1);
- open_args = g_new (FT_Open_Args, 1);
- open_args->flags = ft_open_pathname;
- open_args->pathname = g_strdup (path);
- open_args->driver = NULL;
- open_args->num_params = 0;
- oa->open_args = open_args;
- oa->face_index = face_index;
-#if 0
- PING (("adding mapping: "));
- pango_ft2_print_oa (oa);
-#endif
- g_hash_table_insert (ft2fontmap->faces, description, oa);
+ g_hash_table_insert (ft2fontmap->fontset_hash,
+ pango_font_description_copy (desc),
+ patterns);
}
-#if 0
- g_print ("\n");
-#endif
-
- face_entry = g_object_new (PANGO_FT2_TYPE_FACE, NULL);
- face_entry->description = description;
- face_entry->cached_fonts = NULL;
- face_entry->coverage = NULL;
- face_entry->open_args = g_new (FT_Open_Args *, 1);
- face_entry->open_args[0] = oa->open_args;
- face_entry->face_indices = g_new (FT_Long, 1);
- face_entry->face_indices[0] = oa->face_index;
- face_entry->n_fonts = 1;
- family_entry->font_entries = g_slist_append (family_entry->font_entries, face_entry);
- ft2fontmap->n_fonts++;
-}
-static void
-free_coverages_foreach (gpointer key,
- gpointer value,
- gpointer data)
-{
- pango_coverage_unref (value);
-}
-
-/**
- * pango_ft2_font_map_get_font_cache:
- * @font_map: a #PangoFT2FontMap.
- *
- * Obtains the font cache associated with the given font map.
- *
- * Returns: the #PangoFT2FontCache of @font_map.
- **/
-PangoFT2FontCache *
-pango_ft2_font_map_get_font_cache (PangoFontMap *font_map)
-{
- g_return_val_if_fail (font_map != NULL, NULL);
- g_return_val_if_fail (PANGO_FT2_IS_FONT_MAP (font_map), NULL);
+ simple = pango_fontset_simple_new ();
- return PANGO_FT2_FONT_MAP (font_map)->font_cache;
+ for (i = 0; i < patterns->n_patterns; i++)
+ pango_fontset_simple_append (simple,
+ pango_ft2_font_map_new_font (fontmap, patterns->patterns[i]));
+
+ return PANGO_FONTSET (simple);
}
void
-pango_ft2_fontmap_cache_add (PangoFontMap *fontmap,
- PangoFT2Font *ft2font)
+_pango_ft2_font_map_cache_add (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font)
{
PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap);
@@ -904,9 +618,9 @@ pango_ft2_fontmap_cache_add (PangoFontMa
ft2font->in_cache = TRUE;
}
-void
-pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap,
- PangoFT2Font *ft2font)
+static void
+pango_ft2_font_map_cache_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font)
{
PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap);
@@ -926,7 +640,7 @@ pango_ft2_fontmap_cache_remove (PangoFon
}
static void
-pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap)
+pango_ft2_font_map_cache_clear (PangoFT2FontMap *ft2fontmap)
{
g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);
g_list_free (ft2fontmap->freed_fonts->head);
@@ -935,98 +649,95 @@ pango_ft2_fontmap_cache_clear (PangoFT2F
ft2fontmap->freed_fonts->length = 0;
}
-static void
-pango_ft2_face_dump (int indent,
- PangoFT2Face *face)
+/*
+ * PangoFT2Face
+ */
+
+PangoFontDescription *
+_pango_ft2_font_desc_from_pattern (MiniXftPattern *pattern)
{
+ PangoFontDescription *desc;
+ PangoStyle style;
+ PangoWeight weight;
+
+ char *s;
int i;
- printf ("%*sPangoFT2Face %p:\n"
- "%*s lfp:\n",
- indent, "", face,
- indent, "");
-
- for (i = 0; i < face->n_fonts; i++)
- printf ("%*s PangoFT2OpenArgs:%s:%ld\n",
- indent, "", face->open_args[i]->pathname, face->face_indices[i]);
-
- printf ("%*s description:\n"
- "%*s family_name: %s\n"
- "%*s style: %d\n"
- "%*s variant: %d\n"
- "%*s weight: %d\n"
- "%*s stretch: %d\n"
- "%*s coverage: %p\n",
- indent, "",
- indent, "", pango_font_description_get_family (face->description),
- indent, "", pango_font_description_get_style (face->description),
- indent, "", pango_font_description_get_variant (face->description),
- indent, "", pango_font_description_get_weight (face->description),
- indent, "", pango_font_description_get_stretch (face->description),
- indent, "", face->coverage);
-}
+ desc = pango_font_description_new ();
-static void
-pango_ft2_family_entry_dump (int indent,
- PangoFT2Family *entry)
-{
- GSList *tmp_list = entry->font_entries;
-
- printf ("%*sPangoFT2Family %p:\n"
- "%*s family_name: %s\n"
- "%*s font_entries:\n",
- indent, "", entry,
- indent, "", entry->family_name,
- indent, "");
+ g_assert (MiniXftPatternGetString (pattern, XFT_FAMILY, 0, &s) == MiniXftResultMatch);
- while (tmp_list)
+ pango_font_description_set_family (desc, s);
+
+ if (MiniXftPatternGetInteger (pattern, XFT_SLANT, 0, &i) == MiniXftResultMatch)
{
- PangoFT2Face *face = tmp_list->data;
-
- pango_ft2_face_dump (indent + 2, face);
- tmp_list = tmp_list->next;
+ if (i == XFT_SLANT_ROMAN)
+ style = PANGO_STYLE_NORMAL;
+ else if (i == XFT_SLANT_OBLIQUE)
+ style = PANGO_STYLE_OBLIQUE;
+ else
+ style = PANGO_STYLE_ITALIC;
}
-}
+ else
+ style = PANGO_STYLE_NORMAL;
-static void
-dump_family (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- PangoFT2Family *entry = value;
- int indent = (int) user_data;
+ pango_font_description_set_style (desc, style);
- pango_ft2_family_entry_dump (indent, entry);
-}
+ if (MiniXftPatternGetInteger (pattern, XFT_WEIGHT, 0, &i) == MiniXftResultMatch)
+ {
+ if (i < XFT_WEIGHT_LIGHT)
+ weight = PANGO_WEIGHT_ULTRALIGHT;
+ else if (i < (XFT_WEIGHT_LIGHT + XFT_WEIGHT_MEDIUM) / 2)
+ weight = PANGO_WEIGHT_LIGHT;
+ else if (i < (XFT_WEIGHT_MEDIUM + XFT_WEIGHT_DEMIBOLD) / 2)
+ weight = PANGO_WEIGHT_NORMAL;
+ else if (i < (XFT_WEIGHT_DEMIBOLD + XFT_WEIGHT_BOLD) / 2)
+ weight = 600;
+ else if (i < (XFT_WEIGHT_BOLD + XFT_WEIGHT_BLACK) / 2)
+ weight = PANGO_WEIGHT_BOLD;
+ else
+ weight = PANGO_WEIGHT_ULTRABOLD;
+ }
+ else
+ weight = PANGO_WEIGHT_NORMAL;
-/**
- * pango_ft2_fontmap_dump:
- * @indent: the indent to use.
- * @fontmap: a #PangoFT2FontMap.
- *
- * Writes a description of the given font map to stdout.
- **/
-void
-pango_ft2_fontmap_dump (int indent,
- PangoFontMap *fontmap)
-{
- PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap);
+ pango_font_description_set_weight (desc, weight);
+
+ pango_font_description_set_variant (desc, PANGO_VARIANT_NORMAL);
+ pango_font_description_set_stretch (desc, PANGO_STRETCH_NORMAL);
- printf ("%*sPangoFT2FontMap %p:\n",
- indent, "", ft2fontmap);
- g_hash_table_foreach (ft2fontmap->families, dump_family, (gpointer) (indent + 2));
+ return desc;
}
-/*
- * PangoFT2Face
- */
static PangoFontDescription *
pango_ft2_face_describe (PangoFontFace *face)
{
- PangoFT2Face *ft2face = PANGO_FT2_FACE (face);
+ PangoFT2Face *ft2face = (PangoFT2Face *) face;
+ PangoFT2Family *ft2family = ft2face->family;
+ PangoFontDescription *desc = NULL;
+ MiniXftResult res;
+ MiniXftPattern *match_pattern;
+ MiniXftPattern *result_pattern;
+
+ match_pattern = MiniXftPatternBuild (NULL,
+ XFT_ENCODING, MiniXftTypeString, "iso10646-1",
+ XFT_FAMILY, MiniXftTypeString, ft2family->family_name,
+ XFT_CORE, MiniXftTypeBool, False,
+ XFT_STYLE, MiniXftTypeString, ft2face->style,
+ NULL);
+ g_assert (match_pattern);
+
+ result_pattern = MiniXftFontMatch ((Display *)1, 0, match_pattern, &res);
+ if (result_pattern)
+ {
+ desc = _pango_ft2_font_desc_from_pattern (result_pattern);
+ MiniXftPatternDestroy (result_pattern);
+ }
- return pango_font_description_copy (ft2face->description);
+ MiniXftPatternDestroy (match_pattern);
+
+ return desc;
}
static const char *
@@ -1034,18 +745,7 @@ pango_ft2_face_get_face_name (PangoFontF
{
PangoFT2Face *ft2face = PANGO_FT2_FACE (face);
- if (!ft2face->face_name)
- {
- PangoFontDescription *desc = pango_font_face_describe (face);
-
- pango_font_description_unset_fields (desc,
- PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE);
-
- ft2face->face_name = pango_font_description_to_string (desc);
- pango_font_description_free (desc);
- }
-
- return ft2face->face_name;
+ return ft2face->style;
}
static void
@@ -1082,113 +782,33 @@ pango_ft2_face_get_type (void)
return object_type;
}
-
-PangoCoverage *
-pango_ft2_face_get_coverage (PangoFT2Face *face,
- PangoFont *font,
- PangoLanguage *language)
-{
- guint32 ch;
- PangoMap *shape_map;
- PangoCoverage *coverage;
- PangoCoverage *result;
- PangoCoverageLevel font_level;
- PangoMapEntry *map_entry;
- GHashTable *coverage_hash;
- PangoFontDescription *description;
- FILE *cache_file;
- char *file_name;
- char *cache_file_name;
- char *font_as_filename;
- guchar *buf;
- size_t buflen;
-
- if (face)
- if (face->coverage)
- {
- pango_coverage_ref (face->coverage);
- return face->coverage;
- }
-
- description = pango_font_describe (font);
- font_as_filename = pango_font_description_to_filename (description);
- file_name = g_strconcat (font_as_filename, ".",
- language ? pango_language_to_string (language) : "",
- NULL);
- g_free (font_as_filename);
- cache_file_name = g_build_filename (pango_get_sysconf_subdirectory (),
- "cache.ft2", file_name, NULL);
- g_free (file_name);
- pango_font_description_free (description);
-
- PING (("trying to load %s", cache_file_name));
- result = NULL;
- if (g_file_get_contents (cache_file_name, (char **)&buf, &buflen, NULL))
- {
- result = pango_coverage_from_bytes (buf, buflen);
- g_free (buf);
- }
- if (!result)
- {
- result = pango_coverage_new ();
-
- coverage_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- shape_map = pango_ft2_get_shaper_map (language);
-
- for (ch = 0; ch < 65536; ch++)
- {
- map_entry = pango_map_get_entry (shape_map, ch);
- if (map_entry->info)
- {
- coverage = g_hash_table_lookup (coverage_hash, map_entry->info->id);
- if (!coverage)
- {
- PangoEngineShape *engine = (PangoEngineShape *)pango_map_get_engine (shape_map, ch);
- coverage = engine->get_coverage (font, language);
- g_hash_table_insert (coverage_hash, map_entry->info->id, coverage);
- }
-
- font_level = pango_coverage_get (coverage, ch);
- if (font_level == PANGO_COVERAGE_EXACT && !map_entry->is_exact)
- font_level = PANGO_COVERAGE_APPROXIMATE;
-
- if (font_level != PANGO_COVERAGE_NONE)
- pango_coverage_set (result, ch, font_level);
- }
- }
-
- g_hash_table_foreach (coverage_hash, free_coverages_foreach, NULL);
- g_hash_table_destroy (coverage_hash);
-
- cache_file = fopen (cache_file_name, "wb");
- if (cache_file)
- {
- pango_coverage_to_bytes (result, &buf, &buflen);
- PING (("saving %d bytes to %s", buflen, cache_file_name));
- fwrite (buf, buflen, 1, cache_file);
- fclose (cache_file);
- g_free (buf);
- }
- }
+void
+_pango_ft2_font_map_set_coverage (PangoFontMap *fontmap,
+ const char *name,
+ PangoCoverage *coverage)
+{
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
- if (face)
- {
- face->coverage = result;
- pango_coverage_ref (result);
- }
+ g_hash_table_insert (ft2fontmap->coverage_hash, g_strdup (name),
+ pango_coverage_ref (coverage));
+}
- g_free (cache_file_name);
+PangoCoverage *
+_pango_ft2_font_map_get_coverage (PangoFontMap *fontmap,
+ const char *name)
+{
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
- return result;
+ return g_hash_table_lookup (ft2fontmap->coverage_hash, name);
}
-void
-pango_ft2_face_remove (PangoFT2Face *face,
- PangoFont *font)
+FT_Library
+_pango_ft2_font_map_get_library (PangoFontMap *fontmap)
{
- face->cached_fonts = g_slist_remove (face->cached_fonts, font);
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
+
+ return ft2fontmap->library;
}
/*
@@ -1197,26 +817,48 @@ pango_ft2_face_remove (PangoFT2Face *fac
static void
pango_ft2_family_list_faces (PangoFontFamily *family,
- PangoFontFace ***faces,
- int *n_faces)
+ PangoFontFace ***faces,
+ int *n_faces)
{
PangoFT2Family *ft2family = PANGO_FT2_FAMILY (family);
- *n_faces = g_slist_length (ft2family->font_entries);
- if (faces)
+ if (ft2family->n_faces < 0)
{
- GSList *tmp_list;
- int i = 0;
+ MiniXftFontSet *fontset;
+ int i;
+
+ fontset = MiniXftListFonts ((Display *)1, 0,
+ XFT_ENCODING, MiniXftTypeString, "iso10646-1",
+ XFT_FAMILY, MiniXftTypeString, ft2family->family_name,
+ XFT_CORE, MiniXftTypeBool, False,
+ NULL,
+ XFT_STYLE,
+ NULL);
- *faces = g_new (PangoFontFace *, *n_faces);
+ ft2family->n_faces = fontset->nfont;
+ ft2family->faces = g_new (PangoFT2Face *, ft2family->n_faces);
- tmp_list = ft2family->font_entries;
- while (tmp_list)
+ for (i = 0; i < fontset->nfont; i++)
{
- (*faces)[i++] = tmp_list->data;
- tmp_list = tmp_list->next;
+ char *s;
+ MiniXftResult res;
+
+ res = MiniXftPatternGetString (fontset->fonts[i], XFT_STYLE, 0, &s);
+ g_assert (res == MiniXftResultMatch);
+
+ ft2family->faces[i] = g_object_new (PANGO_FT2_TYPE_FACE, NULL);
+ ft2family->faces[i]->style = g_strdup (s);
+ ft2family->faces[i]->family = ft2family;
}
+
+ MiniXftFontSetDestroy (fontset);
}
+
+ if (n_faces)
+ *n_faces = ft2family->n_faces;
+
+ if (faces)
+ *faces = g_memdup (ft2family->faces, ft2family->n_faces * sizeof (PangoFontFace *));
}
const char *
Index: pango/pangoft2-private.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoft2-private.h,v
retrieving revision 1.11
diff -u -p -r1.11 pangoft2-private.h
--- pango/pangoft2-private.h 2001/09/18 21:32:09 1.11
+++ pango/pangoft2-private.h 2001/11/18 01:40:36
@@ -25,6 +25,7 @@
#include "pango-modules.h"
#include "pangoft2.h"
+#include "mini-xft/MiniXft.h"
/* Debugging... */
/*#define DEBUGGING 1*/
@@ -52,43 +53,27 @@
((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6)
#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d))
-typedef struct _PangoFT2OA PangoFT2OA;
-typedef struct _PangoFT2Font PangoFT2Font;
+typedef struct _PangoFT2Font PangoFT2Font;
typedef struct _PangoFT2GlyphInfo PangoFT2GlyphInfo;
-typedef struct _PangoFT2Face PangoFT2Face;
-typedef struct _PangoFT2SubfontInfo PangoFT2SubfontInfo;
+typedef struct _PangoFT2Face PangoFT2Face;
+typedef struct _PangoFT2Family PangoFT2Family;
-struct _PangoFT2OA
-{
- FT_Open_Args *open_args;
- FT_Long face_index;
-};
struct _PangoFT2Font
{
PangoFont font;
- /* A PangoFT2Font consists of one or several FT2 fonts (faces) that
- * are assumed to blend visually well, and cover separate parts of
- * the Unicode characters. The FT2 faces are not kept unnecessarily
- * open, thus also we keep both the FT_Open_Args (and face index),
- * and FT_Face.
- */
- PangoFT2OA **oa;
- FT_Face *faces;
- int n_fonts;
+ MiniXftPattern *font_pattern;
+ FT_Face face;
int size;
- GSList *metrics_by_lang;
-
PangoFontMap *fontmap;
+ PangoFontDescription *description;
+
/* If TRUE, font is in cache of recently unused fonts and not otherwise
- * in use.
- */
+ * in use. */
gboolean in_cache;
-
- PangoFT2Face *entry;
GHashTable *glyph_info;
};
@@ -103,27 +88,30 @@ struct _PangoFT2Face
{
PangoFontFace parent_instance;
- FT_Open_Args **open_args;
- FT_Long *face_indices;
- int n_fonts;
- PangoFontDescription *description;
- PangoCoverage *coverage;
- char *face_name;
-
- GSList *cached_fonts;
+ PangoFT2Family *family;
+ char *style;
};
-PangoMap *pango_ft2_get_shaper_map (PangoLanguage *language);
-PangoCoverage *pango_ft2_face_get_coverage (PangoFT2Face *face,
- PangoFont *font,
- PangoLanguage *language);
-void pango_ft2_face_remove (PangoFT2Face *face,
- PangoFont *font);
-FT_Library *pango_ft2_fontmap_get_library (PangoFontMap *fontmap);
-void pango_ft2_fontmap_cache_add (PangoFontMap *fontmap,
- PangoFT2Font *ft2font);
-void pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap,
- PangoFT2Font *ft2font);
-const char *pango_ft2_ft_strerror (FT_Error error);
+PangoFT2Font * _pango_ft2_font_new (PangoFontMap *font,
+ MiniXftPattern *pattern);
+PangoMap *_pango_ft2_get_shaper_map (PangoLanguage *language);
+void _pango_ft2_font_map_set_coverage (PangoFontMap *fontmap,
+ const char *name,
+ PangoCoverage *coverage);
+PangoCoverage *_pango_ft2_font_map_get_coverage (PangoFontMap *fontmap,
+ const char *name);
+void _pango_ft2_face_remove (PangoFT2Face *face,
+ PangoFont *font);
+FT_Library _pango_ft2_font_map_get_library (PangoFontMap *fontmap);
+void _pango_ft2_font_map_cache_add (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+void _pango_ft2_font_map_cache_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+void _pango_ft2_font_map_add (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+void _pango_ft2_font_map_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+const char *_pango_ft2_ft_strerror (FT_Error error);
+PangoFontDescription *_pango_ft2_font_desc_from_pattern (MiniXftPattern *pattern);
#endif /* __PANGOFT2_PRIVATE_H__ */
Index: pango/pangoft2.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoft2.c,v
retrieving revision 1.26
diff -u -p -r1.26 pangoft2.c
--- pango/pangoft2.c 2001/10/26 21:41:02 1.26
+++ pango/pangoft2.c 2001/11/18 01:40:38
@@ -46,12 +46,6 @@ typedef struct _PangoFT2FontClass Pang
typedef struct _PangoFT2MetricsInfo PangoFT2MetricsInfo;
typedef struct _PangoFT2ContextInfo PangoFT2ContextInfo;
-struct _PangoFT2MetricsInfo
-{
- const char *sample_str;
- PangoFontMetrics *metrics;
-};
-
struct _PangoFT2FontClass
{
PangoFontClass parent_class;
@@ -66,9 +60,6 @@ static void pango_ft2_font_finalize (G
static PangoFontDescription *pango_ft2_font_describe (PangoFont *font);
-static PangoCoverage * pango_ft2_font_get_coverage (PangoFont *font,
- PangoLanguage *language);
-
static PangoEngineShape * pango_ft2_font_find_shaper (PangoFont *font,
PangoLanguage *language,
guint32 ch);
@@ -87,67 +78,88 @@ static void pango_ft2_g
gboolean *fg_set,
PangoAttrColor *bg_color,
gboolean *bg_set);
+
+static GType pango_ft2_font_get_type (void);
-static char *
-pango_ft2_open_args_describe (PangoFT2OA *oa)
+PangoFT2Font *
+_pango_ft2_font_new (PangoFontMap *fontmap,
+ MiniXftPattern *pattern)
{
- if (oa->open_args->flags & ft_open_memory)
- return g_strdup_printf ("memory at %p", oa->open_args->memory_base);
- else if (oa->open_args->flags == ft_open_pathname)
- return g_strdup_printf ("file '%s'", oa->open_args->pathname);
- else if (oa->open_args->flags & ft_open_stream)
- return g_strdup_printf ("FT_Stream at %p", oa->open_args->stream);
- else
- return g_strdup_printf ("open_args at %p, face_index %ld", oa->open_args, oa->face_index);
+ PangoFT2Font *ft2font;
+ double d;
+
+ g_return_val_if_fail (fontmap != NULL, NULL);
+ g_return_val_if_fail (pattern != NULL, NULL);
+
+ ft2font = (PangoFT2Font *)g_object_new (PANGO_TYPE_FT2_FONT, NULL);
+
+ ft2font->fontmap = fontmap;
+ ft2font->font_pattern = pattern;
+
+ g_object_ref (G_OBJECT (fontmap));
+ ft2font->description = _pango_ft2_font_desc_from_pattern (pattern);
+ ft2font->face = NULL;
+
+ if (MiniXftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &d) == MiniXftResultMatch)
+ ft2font->size = d*PANGO_SCALE;
+
+ _pango_ft2_font_map_add (ft2font->fontmap, ft2font);
+
+ return ft2font;
}
+
/**
- * pango_ft2_get_face:
+ * pango_ft2_font_get_face:
* @font: a #PangoFont
- * @subfont_index: the index of a subfont
*
- * Looks up a subfont in a #PangoFT2Font and returns a pointer to the
- * native FreeType2 FT_Face structure. This may be useful if you want
- * to use FreeType2 functions directly.
+ * Returns the native FreeType2 FT_Face structure used for this PangoFont.
+ * This may be useful if you want to use FreeType2 functions directly.
*
- * Return value: a pointer to a #FT_Face structure.
+ * Return value: a pointer to a #FT_Face structure, with the size set correctly
**/
FT_Face
-pango_ft2_get_face (PangoFont *font,
- PangoFT2Subfont subfont_index)
+pango_ft2_font_get_face (PangoFont *font)
{
PangoFT2Font *ft2font = (PangoFT2Font *)font;
- PangoFT2FontCache *cache;
FT_Face face;
FT_Error error;
+ MiniXftPattern *pattern;
+ char *filename;
+ int id;
+
+ pattern = ft2font->font_pattern;
- if (subfont_index < 1 || subfont_index > ft2font->n_fonts)
+ if (!ft2font->face)
{
- g_warning ("Invalid subfont %d", subfont_index);
- return NULL;
+ if (MiniXftPatternGetString (pattern, XFT_FILE, 0, &filename) != MiniXftResultMatch)
+ goto bail0;
+
+ if (MiniXftPatternGetInteger (pattern, XFT_INDEX, 0, &id) != MiniXftResultMatch)
+ goto bail0;
+
+ error = FT_New_Face (_pango_ft2_font_map_get_library (ft2font->fontmap),
+ filename, id, &ft2font->face);
+ ft2font->face->generic.data = 0;
}
+ bail0:
- if (!ft2font->faces[subfont_index-1])
+ if (!ft2font->face)
{
- cache = pango_ft2_font_map_get_font_cache (ft2font->fontmap);
-
- ft2font->faces[subfont_index-1] =
- pango_ft2_font_cache_load (cache,
- ft2font->oa[subfont_index-1]->open_args,
- ft2font->oa[subfont_index-1]->face_index);
-
- if (!ft2font->faces[subfont_index-1])
- g_warning ("Cannot load font for %s",
- pango_ft2_open_args_describe (ft2font->oa[subfont_index-1]));
+ g_warning ("Cannot load font\n");
+ return NULL;
}
- face = ft2font->faces[subfont_index-1];
+ face = ft2font->face;
if (ft2font->size != GPOINTER_TO_UINT (face->generic.data))
{
face->generic.data = GUINT_TO_POINTER (ft2font->size);
- error = FT_Set_Char_Size (face, 0, PANGO_PIXELS_26_6 (ft2font->size), 72, 72);
+ error = FT_Set_Char_Size (face,
+ PANGO_PIXELS_26_6 (ft2font->size),
+ PANGO_PIXELS_26_6 (ft2font->size),
+ 0, 0);
if (error)
g_warning ("Error in FT_Set_Char_Size: %d", error);
}
@@ -157,6 +169,7 @@ pango_ft2_get_face (PangoFont *font
/**
* pango_ft2_get_context:
+ * @dpi: the dpi of the target device
*
* Retrieves a #PangoContext appropriate for rendering with the PangoFT2
* backend.
@@ -164,7 +177,7 @@ pango_ft2_get_face (PangoFont *font
* Return value: the new #PangoContext
**/
PangoContext *
-pango_ft2_get_context (void)
+pango_ft2_get_context (double dpi)
{
PangoContext *result;
static gboolean registered_modules = FALSE;
@@ -177,9 +190,11 @@ pango_ft2_get_context (void)
for (i = 0; _pango_included_ft2_modules[i].list; i++)
pango_module_register (&_pango_included_ft2_modules[i]);
}
+
+ MiniXftSetDPI (dpi);
result = pango_context_new ();
- pango_context_add_font_map (result, pango_ft2_font_map_for_display ());
+ pango_context_set_font_map (result, pango_ft2_font_map_for_display ());
return result;
}
@@ -215,14 +230,10 @@ pango_ft2_font_get_type (void)
static void
pango_ft2_font_init (PangoFT2Font *ft2font)
{
- ft2font->oa = NULL;
- ft2font->faces = NULL;
-
- ft2font->n_fonts = 0;
+ ft2font->face = NULL;
- ft2font->metrics_by_lang = NULL;
+ ft2font->size = 0;
- ft2font->entry = NULL;
ft2font->glyph_info = g_hash_table_new (NULL, NULL);
}
@@ -245,54 +256,6 @@ pango_ft2_font_class_init (PangoFT2FontC
}
/**
- * pango_ft2_load_font:
- * @fontmap: a #PangoFontmap
- * @open_args: parameters that control loading
- * @face_indices:
- * @n_fonts:
- * @size:
- *
- * Loads a logical font based on XXX
- *
- * Return value: a new #PangoFont
- **/
-PangoFont *
-pango_ft2_load_font (PangoFontMap *fontmap,
- FT_Open_Args **open_args,
- FT_Long *face_indices,
- int n_fonts,
- int size)
-{
- PangoFT2Font *result;
- int i;
-
- g_return_val_if_fail (fontmap != NULL, NULL);
- g_return_val_if_fail (open_args != NULL, NULL);
- g_return_val_if_fail (face_indices != NULL, NULL);
- g_return_val_if_fail (n_fonts > 0, NULL);
-
- result = (PangoFT2Font *)g_object_new (PANGO_TYPE_FT2_FONT, NULL);
-
- result->fontmap = fontmap;
- g_object_ref (G_OBJECT (result->fontmap));
-
- result->oa = g_new (PangoFT2OA *, n_fonts);
- result->faces = g_new (FT_Face, n_fonts);
- result->n_fonts = n_fonts;
- result->size = size;
-
- for (i = 0; i < n_fonts; i++)
- {
- result->oa[i] = g_new (PangoFT2OA, 1);
- result->oa[i]->open_args = open_args[i];
- result->oa[i]->face_index = face_indices[i];
- result->faces[i] = NULL;
- }
-
- return &result->font;
-}
-
-/**
* pango_ft2_render:
* @bitmap: the FreeType2 bitmap onto which to draw the string
* @font: the font in which to draw the string
@@ -315,7 +278,6 @@ pango_ft2_render (FT_Bitmap *bitm
int i;
int x_position = 0;
int ix, iy, ixoff, iyoff, y_start, y_limit, x_start, x_limit;
- PangoFT2Subfont subfont_index;
PangoGlyphInfo *gi;
guchar *p, *q;
@@ -329,9 +291,8 @@ pango_ft2_render (FT_Bitmap *bitm
{
if (gi->glyph)
{
- glyph_index = PANGO_FT2_GLYPH_INDEX (gi->glyph);
- subfont_index = PANGO_FT2_GLYPH_SUBFONT (gi->glyph);
- face = pango_ft2_get_face (font, subfont_index);
+ glyph_index = gi->glyph;
+ face = pango_ft2_font_get_face (font);
if (face)
{
@@ -418,15 +379,9 @@ pango_ft2_render (FT_Bitmap *bitm
}
static FT_Glyph_Metrics *
-pango_ft2_get_per_char (PangoFont *font,
- PangoFT2Subfont subfont_index,
- guint32 glyph_index)
+pango_ft2_get_per_char (FT_Face face,
+ guint32 glyph_index)
{
- FT_Face face;
-
- if (!(face = pango_ft2_get_face (font, subfont_index)))
- return NULL;
-
FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT);
return &face->glyph->metrics;
}
@@ -439,22 +394,17 @@ pango_ft2_font_get_glyph_extents (PangoF
{
PangoFT2Font *ft2font = (PangoFT2Font *)font;
PangoFT2GlyphInfo *info;
- PangoFT2Subfont subfont_index;
- FT_UInt glyph_index;
FT_Glyph_Metrics *gm;
info = g_hash_table_lookup (ft2font->glyph_info, GUINT_TO_POINTER (glyph));
if (!info)
{
+ FT_Face face = pango_ft2_font_get_face (font);
info = g_new (PangoFT2GlyphInfo, 1);
- glyph_index = PANGO_FT2_GLYPH_INDEX (glyph);
- subfont_index = PANGO_FT2_GLYPH_SUBFONT (glyph);
- if (glyph && (gm = pango_ft2_get_per_char (font, subfont_index, glyph_index)))
+ if (glyph && (gm = pango_ft2_get_per_char (face, glyph)))
{
- FT_Face face = pango_ft2_get_face (font, subfont_index);
-
info->ink_rect.x = PANGO_UNITS_26_6 (gm->horiBearingX);
info->ink_rect.width = PANGO_UNITS_26_6 (gm->width);
info->ink_rect.y = -PANGO_UNITS_26_6 (gm->horiBearingY);
@@ -481,7 +431,7 @@ pango_ft2_font_get_glyph_extents (PangoF
g_hash_table_insert (ft2font->glyph_info, GUINT_TO_POINTER(glyph), info);
}
-
+
if (ink_rect)
*ink_rect = info->ink_rect;
if (logical_rect)
@@ -504,280 +454,67 @@ pango_ft2_font_get_kerning (PangoFont *f
PangoGlyph left,
PangoGlyph right)
{
- PangoFT2Subfont subfont_index;
FT_Face face;
- FT_UInt left_glyph_index, right_glyph_index;
FT_Error error;
FT_Vector kerning;
- subfont_index = PANGO_FT2_GLYPH_SUBFONT (left);
- if (PANGO_FT2_GLYPH_SUBFONT (right) != subfont_index)
- return 0;
-
- face = pango_ft2_get_face (font, subfont_index);
+ face = pango_ft2_font_get_face (font);
if (!face)
return 0;
if (!FT_HAS_KERNING (face))
return 0;
-
- left_glyph_index = PANGO_FT2_GLYPH_INDEX (left);
- right_glyph_index = PANGO_FT2_GLYPH_INDEX (right);
- if (!left_glyph_index || !right_glyph_index)
+ if (!left || !right)
return 0;
- error = FT_Get_Kerning (face, left_glyph_index, right_glyph_index,
+ error = FT_Get_Kerning (face, left, right,
ft_kerning_default, &kerning);
if (error != FT_Err_Ok)
g_warning ("FT_Get_Kerning returns error: %s",
- pango_ft2_ft_strerror (error));
+ _pango_ft2_ft_strerror (error));
return PANGO_UNITS_26_6 (kerning.x);
}
-/* Get composite font metrics for all subfonts in list
- */
-static void
-get_font_metrics_from_subfonts (PangoFont *font,
- GSList *subfonts,
- PangoFontMetrics *metrics)
-{
- GSList *tmp_list = subfonts;
- gboolean first = TRUE;
-
- metrics->ascent = 0;
- metrics->descent = 0;
-
- while (tmp_list)
- {
- FT_Face face = pango_ft2_get_face (font, GPOINTER_TO_UINT (tmp_list->data));
-
- g_assert (face != NULL);
-
- if (first)
- {
- metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender);
- metrics->descent = PANGO_UNITS_26_6 (-face->size->metrics.descender);
- metrics->approximate_digit_width = PANGO_UNITS_26_6 (face->size->metrics.max_advance);
- metrics->approximate_char_width = PANGO_UNITS_26_6 (face->size->metrics.max_advance);
- first = FALSE;
- }
- else
- {
- metrics->ascent = MAX (PANGO_UNITS_26_6 (face->size->metrics.ascender), metrics->ascent);
- metrics->descent = MAX (PANGO_UNITS_26_6 (-face->size->metrics.descender), metrics->descent);
- metrics->approximate_digit_width =
- MAX (PANGO_UNITS_26_6 (face->size->metrics.max_advance), metrics->approximate_digit_width);
- metrics->approximate_char_width =
- MAX (PANGO_UNITS_26_6 (face->size->metrics.max_advance), metrics->approximate_char_width);
- }
-
- tmp_list = tmp_list->next;
- }
-}
-
-/* Get composite font metrics for all subfonts resulting from shaping
- * string str with the given font
- *
- * This duplicates quite a bit of code from pango_itemize. This function
- * should die and we should simply add the ability to specify particular
- * fonts when itemizing.
- */
-static void
-get_font_metrics_from_string (PangoFont *font,
- PangoLanguage *language,
- const char *str,
- PangoFontMetrics *metrics)
-{
- const char *start, *p;
- PangoGlyphString *glyph_str = pango_glyph_string_new ();
- PangoEngineShape *shaper, *last_shaper;
- int last_level;
- gunichar *text_ucs4;
- long n_chars, i;
- guint8 *embedding_levels;
- PangoDirection base_dir = PANGO_DIRECTION_LTR;
- GSList *subfonts = NULL;
-
- text_ucs4 = g_utf8_to_ucs4_fast (str, -1, &n_chars);
- if (!text_ucs4)
- return;
-
- embedding_levels = g_new (guint8, n_chars);
- pango_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir,
- embedding_levels);
- g_free (text_ucs4);
-
- last_shaper = NULL;
- last_level = 0;
-
- i = 0;
- p = start = str;
- while (*p)
- {
- gunichar wc = g_utf8_get_char (p);
- p = g_utf8_next_char (p);
-
- shaper = pango_font_find_shaper (font, language, wc);
- if (p > start &&
- (shaper != last_shaper || last_level != embedding_levels[i]))
- {
- PangoAnalysis analysis;
- int j;
-
- analysis.shape_engine = shaper;
- analysis.lang_engine = NULL;
- analysis.font = font;
- analysis.level = last_level;
-
- pango_shape (start, p - start, &analysis, glyph_str);
-
- for (j = 0; j < glyph_str->num_glyphs; j++)
- {
- PangoFT2Subfont subfont_index = PANGO_FT2_GLYPH_SUBFONT (glyph_str->glyphs[j].glyph);
- if (!g_slist_find (subfonts, GUINT_TO_POINTER ((guint)subfont_index)))
- subfonts = g_slist_prepend (subfonts, GUINT_TO_POINTER ((guint)subfont_index));
- }
-
- start = p;
- }
-
- last_shaper = shaper;
- last_level = embedding_levels[i];
- i++;
- }
-
- get_font_metrics_from_subfonts (font, subfonts, metrics);
- g_slist_free (subfonts);
-
- pango_glyph_string_free (glyph_str);
- g_free (embedding_levels);
-
- return;
-}
-
static PangoFontMetrics *
pango_ft2_font_get_metrics (PangoFont *font,
PangoLanguage *language)
{
- PangoFT2MetricsInfo *info = NULL; /* Quiet GCC */
- PangoFT2Font *ft2font = (PangoFT2Font *)font;
- GSList *tmp_list;
-
- const char *sample_str = pango_language_get_sample_string (language);
+ PangoFontMetrics *metrics;
+ FT_Face face;
- tmp_list = ft2font->metrics_by_lang;
- while (tmp_list)
- {
- info = tmp_list->data;
-
- if (info->sample_str == sample_str) /* We _don't_ need strcmp */
- break;
+ face = pango_ft2_font_get_face (font);
- tmp_list = tmp_list->next;
- }
-
- if (!tmp_list)
- {
- info = g_new (PangoFT2MetricsInfo, 1);
- info->sample_str = sample_str;
- info->metrics = pango_font_metrics_new ();
- get_font_metrics_from_string (font, language, sample_str, info->metrics);
-
- ft2font->metrics_by_lang = g_slist_prepend (ft2font->metrics_by_lang, info);
- }
-
- return pango_font_metrics_ref (info->metrics);
-}
-
-/**
- * pango_ft2_n_subfonts:
- * @font: a #PangoFont
- *
- * Returns the number of subfonts in a #PangoFT2Font.
- *
- * Return value: the number of subfonts in @font
- **/
-int
-pango_ft2_n_subfonts (PangoFont *font)
-{
- PangoFT2Font *ft2font = (PangoFT2Font *)font;
-
- g_return_val_if_fail (font != NULL, 0);
+ metrics = pango_font_metrics_new ();
+
+ metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender);
+ metrics->descent = PANGO_UNITS_26_6 (-face->size->metrics.descender);
+ metrics->approximate_digit_width = PANGO_UNITS_26_6 (face->size->metrics.max_advance);
+ metrics->approximate_char_width = PANGO_UNITS_26_6 (face->size->metrics.max_advance);
- return ft2font->n_fonts;
+ return pango_font_metrics_ref (metrics);
}
-/**
- * pango_ft2_get_coverage:
- * @font: a #PangoFT2Font.
- * @language: the language to compute the coverage for.
- *
- * Computes the coverage of @language by @font.
- *
- * Returns: a newly-allocated #PangoCoverage.
- **/
-PangoCoverage *
-pango_ft2_get_coverage (PangoFont *font,
- PangoLanguage *language)
+static PangoCoverage *
+pango_ft2_calc_coverage (PangoFont *font,
+ PangoLanguage *language)
{
- PangoFT2Font *ft2font = (PangoFT2Font *)font;
- PangoCoverage *result = pango_coverage_new ();
- PangoCoverage *tmp;
- PangoGlyph glyph;
+ PangoCoverage *result;
FT_Face face;
gunichar wc;
- int i;
- for (i = 1; i <= ft2font->n_fonts; i++)
+ result = pango_coverage_new ();
+ face = pango_ft2_font_get_face (font);
+ for (wc = 0; wc < 65536; wc++)
{
- tmp = pango_coverage_new ();
- face = pango_ft2_get_face (font, i);
- for (wc = 0; wc < 65536; wc++)
- {
- glyph = PANGO_FT2_MAKE_GLYPH (i, wc);
- if (FT_Get_Char_Index (face, wc))
- pango_coverage_set (tmp, wc, PANGO_COVERAGE_EXACT);
- }
- pango_coverage_max (result, tmp);
- pango_coverage_unref (tmp);
+ if (FT_Get_Char_Index (face, wc))
+ pango_coverage_set (result, wc, PANGO_COVERAGE_EXACT);
}
return result;
}
-/**
- * pango_ft2_font_subfont_open_args:
- * @font: a #PangoFont which must be from the FT2 backend
- * @subfont_id: the id of a subfont within the @font
- * @open_args: pointer where to store the #FT_Open_Args for this subfont
- * @face_index: pointer where to store the face index for this subfont
- *
- * Determine the FT_Open_Args and face index for the specified subfont.
- **/
-void
-pango_ft2_font_subfont_open_args (PangoFont *font,
- PangoFT2Subfont subfont_id,
- FT_Open_Args **open_args,
- FT_Long *face_index)
-{
- PangoFT2Font *ft2font = (PangoFT2Font *)font;
- *open_args = NULL;
- *face_index = 0;
-
- g_return_if_fail (font != NULL);
- g_return_if_fail (PANGO_FT2_IS_FONT (font));
-
- if (subfont_id < 1 || subfont_id > ft2font->n_fonts)
- g_warning ("pango_ft2_font_subfont_open_args: Invalid subfont_id specified");
- else
- {
- *open_args = ft2font->oa[subfont_id-1]->open_args;
- *face_index = ft2font->oa[subfont_id-1]->face_index;
- }
-}
-
static void
pango_ft2_font_dispose (GObject *object)
{
@@ -788,7 +525,7 @@ pango_ft2_font_dispose (GObject *object)
* freed.
*/
if (!ft2font->in_cache && ft2font->fontmap)
- pango_ft2_fontmap_cache_add (ft2font->fontmap, ft2font);
+ _pango_ft2_font_map_cache_add (ft2font->fontmap, ft2font);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -802,39 +539,25 @@ pango_ft2_free_glyph_info_callback (gpoi
}
static void
-free_metrics_info (PangoFT2MetricsInfo *info)
-{
- pango_font_metrics_unref (info->metrics);
- g_free (info);
-}
-
-static void
pango_ft2_font_finalize (GObject *object)
{
PangoFT2Font *ft2font = (PangoFT2Font *)object;
- PangoFT2FontCache *cache = pango_ft2_font_map_get_font_cache (ft2font->fontmap);
- int i;
- PING ((" "));
+ _pango_ft2_font_map_remove (ft2font->fontmap, ft2font);
- for (i = 0; i < ft2font->n_fonts; i++)
+ if (ft2font->face)
{
- if (ft2font->faces[i])
- pango_ft2_font_cache_unload (cache, ft2font->faces[i]);
+ FT_Done_Face (ft2font->face);
+ ft2font->face = NULL;
}
-
- g_free (ft2font->oa);
- g_free (ft2font->faces);
- g_slist_foreach (ft2font->metrics_by_lang, (GFunc)free_metrics_info, NULL);
- g_slist_free (ft2font->metrics_by_lang);
+ pango_font_description_free (ft2font->description);
+ MiniXftPatternDestroy (ft2font->font_pattern);
- if (ft2font->entry)
- pango_ft2_face_remove (ft2font->entry, (PangoFont *)ft2font);
-
g_object_unref (G_OBJECT (ft2font->fontmap));
- g_hash_table_foreach_remove (ft2font->glyph_info, pango_ft2_free_glyph_info_callback, NULL);
+ g_hash_table_foreach_remove (ft2font->glyph_info,
+ pango_ft2_free_glyph_info_callback, NULL);
g_hash_table_destroy (ft2font->glyph_info);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -848,7 +571,7 @@ pango_ft2_font_describe (PangoFont *font
ft2font = PANGO_FT2_FONT (font);
- desc = pango_font_description_copy (ft2font->entry->description);
+ desc = pango_font_description_copy (ft2font->description);
pango_font_description_set_size (desc, ft2font->size);
return desc;
@@ -869,13 +592,31 @@ pango_ft2_get_shaper_map (PangoLanguage
return pango_find_map (language, engine_type_id, render_type_id);
}
-static PangoCoverage *
+PangoCoverage *
pango_ft2_font_get_coverage (PangoFont *font,
PangoLanguage *language)
{
PangoFT2Font *ft2font = (PangoFT2Font *)font;
+ char *filename = NULL;
+ FT_Face face;
+ PangoCoverage *coverage;
+
+ MiniXftPatternGetString (ft2font->font_pattern, XFT_FILE, 0, &filename);
+
+ coverage = _pango_ft2_font_map_get_coverage (ft2font->fontmap, filename);
+
+ if (coverage)
+ return pango_coverage_ref (coverage);
- return pango_ft2_face_get_coverage (ft2font->entry, font, language);
+ /* Ugh, this is going to be SLOW */
+
+ face = pango_ft2_font_get_face (font);
+
+ coverage = pango_ft2_calc_coverage (font, language);
+
+ _pango_ft2_font_map_set_coverage (ft2font->fontmap, filename, coverage);
+
+ return coverage;
}
static PangoEngineShape *
@@ -902,7 +643,7 @@ pango_ft2_font_find_shaper (PangoFont
PangoGlyph
pango_ft2_get_unknown_glyph (PangoFont *font)
{
- return PANGO_FT2_MAKE_GLYPH (1, 0);
+ return 0;
}
/**
@@ -1140,7 +881,7 @@ ft_error_compare (const void *pkey,
}
const char *
-pango_ft2_ft_strerror (FT_Error error)
+_pango_ft2_ft_strerror (FT_Error error)
{
#undef __FTERRORS_H__
#define FT_ERRORDEF( e, v, s ) { e, s },
Index: pango/pangoft2.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoft2.h,v
retrieving revision 1.7
diff -u -p -r1.7 pangoft2.h
--- pango/pangoft2.h 2001/09/18 20:05:17 1.7
+++ pango/pangoft2.h 2001/11/18 01:40:38
@@ -31,15 +31,9 @@ G_BEGIN_DECLS
#define PANGO_RENDER_TYPE_FT2 "PangoRenderFT2"
-/* Calls for applications
- */
-PangoContext *pango_ft2_get_context (void);
+/* Calls for applications */
+PangoContext *pango_ft2_get_context (double dpi);
-PangoFont *pango_ft2_load_font (PangoFontMap *fontmap,
- FT_Open_Args **open_args,
- FT_Long *face_indices,
- int n_fonts,
- int size);
void pango_ft2_render (FT_Bitmap *bitmap,
PangoFont *font,
PangoGlyphString *glyphs,
@@ -54,50 +48,18 @@ void pango_ft2_render_layout
int x,
int y);
+PangoFontMap *pango_ft2_font_map_for_display (void);
+void pango_ft2_shutdown_display (void);
/* API for rendering modules
*/
-typedef guint16 PangoFT2Subfont;
-
-#define PANGO_FT2_MAKE_GLYPH(subfont,index) ((subfont)<<16 | (index))
-#define PANGO_FT2_GLYPH_SUBFONT(glyph) ((glyph)>>16)
-#define PANGO_FT2_GLYPH_INDEX(glyph) ((glyph) & 0xFFFF)
-
-int pango_ft2_n_subfonts (PangoFont *font);
PangoGlyph pango_ft2_get_unknown_glyph (PangoFont *font);
int pango_ft2_font_get_kerning (PangoFont *font,
PangoGlyph left,
PangoGlyph right);
-PangoCoverage *pango_ft2_get_coverage (PangoFont *font,
+FT_Face pango_ft2_font_get_face (PangoFont *font);
+PangoCoverage *pango_ft2_font_get_coverage (PangoFont *font,
PangoLanguage *language);
-FT_Face pango_ft2_get_face (PangoFont *font,
- PangoFT2Subfont subfont_index);
-
-/* API for libraries that want to use PangoFT2 mixed with classic
- * FT2 fonts.
- */
-typedef struct _PangoFT2FontCache PangoFT2FontCache;
-
-PangoFT2FontCache *pango_ft2_font_cache_new (FT_Library library);
-void pango_ft2_font_cache_free (PangoFT2FontCache *cache);
-FT_Face pango_ft2_font_cache_load (PangoFT2FontCache *cache,
- FT_Open_Args *args,
- FT_Long face_index);
-void pango_ft2_font_cache_unload (PangoFT2FontCache *cache,
- FT_Face face);
-PangoFontMap *pango_ft2_font_map_for_display (void);
-void pango_ft2_shutdown_display (void);
-PangoFT2FontCache *pango_ft2_font_map_get_font_cache (PangoFontMap *font_map);
-void pango_ft2_font_subfont_open_args (PangoFont *font,
- PangoFT2Subfont subfont_id,
- FT_Open_Args **open_args,
- FT_Long *face_index);
-
-
-/* Debugging.
- */
-void pango_ft2_fontmap_dump (int indent,
- PangoFontMap *fontmap);
G_END_DECLS
Index: pango/pangowin32.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangowin32.c,v
retrieving revision 1.28
diff -u -p -r1.28 pangowin32.c
--- pango/pangowin32.c 2001/10/26 21:41:03 1.28
+++ pango/pangowin32.c 2001/11/18 01:40:39
@@ -129,7 +129,7 @@ pango_win32_get_context (void)
}
result = pango_context_new ();
- pango_context_add_font_map (result, pango_win32_font_map_for_display ());
+ pango_context_set_font_map (result, pango_win32_font_map_for_display ());
return result;
}
Index: pango/pangox.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangox.c,v
retrieving revision 1.68
diff -u -p -r1.68 pangox.c
--- pango/pangox.c 2001/10/18 18:47:50 1.68
+++ pango/pangox.c 2001/11/18 01:40:44
@@ -275,7 +275,7 @@ pango_x_get_context (Display *display)
g_quark_from_static_string ("pango-x-info"),
info, (GDestroyNotify)g_free);
- pango_context_add_font_map (result, pango_x_font_map_for_display (display));
+ pango_context_set_font_map (result, pango_x_font_map_for_display (display));
return result;
}
Index: pango/pangoxft-font.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoxft-font.c,v
retrieving revision 1.15
diff -u -p -r1.15 pangoxft-font.c
--- pango/pangoxft-font.c 2001/11/05 17:45:32 1.15
+++ pango/pangoxft-font.c 2001/11/18 01:40:47
@@ -112,22 +112,21 @@ pango_xft_font_class_init (PangoXftFontC
PangoXftFont *
_pango_xft_font_new (PangoFontMap *fontmap,
- const PangoFontDescription *description,
- XftFont *xft_font)
+ XftPattern *pattern)
{
PangoXftFont *xfont;
g_return_val_if_fail (fontmap != NULL, NULL);
- g_return_val_if_fail (description != NULL, NULL);
- g_return_val_if_fail (xft_font != NULL, NULL);
+ g_return_val_if_fail (pattern != NULL, NULL);
xfont = (PangoXftFont *)g_object_new (PANGO_TYPE_XFT_FONT, NULL);
xfont->fontmap = fontmap;
+ xfont->font_pattern = pattern;
g_object_ref (G_OBJECT (fontmap));
- xfont->description = pango_font_description_copy (description);
- xfont->xft_font = xft_font;
+ xfont->description = _pango_xft_font_desc_from_pattern (pattern);
+ xfont->xft_font = NULL;
_pango_xft_font_map_add (xfont->fontmap, xfont);
@@ -158,7 +157,7 @@ get_mini_font (PangoFont *font)
xfont->mini_font = pango_font_map_load_font (xfont->fontmap, desc);
pango_font_description_free (desc);
- mini_xft = ((PangoXftFont *)xfont->mini_font)->xft_font;
+ mini_xft = pango_xft_font_get_font (xfont->mini_font);
face = pango_xft_font_get_face (xfont->mini_font);
for (i = 0 ; i < 16 ; i++)
@@ -247,6 +246,7 @@ pango_xft_real_render (Display
gint y)
{
PangoXftFont *xfont = PANGO_XFT_FONT (font);
+ XftFont *xft_font = pango_xft_font_get_font (font);
int i;
int x_off = 0;
@@ -271,12 +271,12 @@ pango_xft_real_render (Display
int j, k;
PangoFont *mini_font = get_mini_font (font);
- XftFont *mini_xft = ((PangoXftFont *)mini_font)->xft_font;
+ XftFont *mini_xft = pango_xft_font_get_font (mini_font);
FT_Face face = pango_xft_font_get_face (xfont->mini_font);
glyph &= ~PANGO_XFT_UNKNOWN_FLAG;
- ys[0] = y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset) - xfont->xft_font->ascent + (xfont->xft_font->ascent + xfont->xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2;
+ ys[0] = y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset) - xft_font->ascent + (xft_font->ascent + xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2;
ys[1] = ys[0] + 2 * xfont->mini_pad + xfont->mini_height;
ys[2] = ys[1] + xfont->mini_height + xfont->mini_pad;
@@ -307,12 +307,12 @@ pango_xft_real_render (Display
else
{
if (draw)
- XftDrawString32 (draw, color, xfont->xft_font,
+ XftDrawString32 (draw, color, xft_font,
x + PANGO_PIXELS (x_off + glyphs->glyphs[i].geometry.x_offset),
y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset),
&glyph, 1);
else
- XftRenderString32 (display, src_picture, xfont->xft_font->u.ft.font, dest_picture, 0, 0,
+ XftRenderString32 (display, src_picture, xft_font->u.ft.font, dest_picture, 0, 0,
x + PANGO_PIXELS (x_off + glyphs->glyphs[i].geometry.x_offset),
y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset),
&glyph, 1);
@@ -385,13 +385,13 @@ static PangoFontMetrics *
pango_xft_font_get_metrics (PangoFont *font,
PangoLanguage *language)
{
- PangoXftFont *xfont = (PangoXftFont *)font;
PangoFontMetrics *metrics = pango_font_metrics_new ();
+ XftFont *xft_font = pango_xft_font_get_font (font);
- metrics->ascent = PANGO_SCALE * xfont->xft_font->ascent;
- metrics->descent = PANGO_SCALE * xfont->xft_font->descent;
- metrics->approximate_digit_width = PANGO_SCALE * xfont->xft_font->max_advance_width;
- metrics->approximate_char_width = PANGO_SCALE * xfont->xft_font->max_advance_width;
+ metrics->ascent = PANGO_SCALE * xft_font->ascent;
+ metrics->descent = PANGO_SCALE * xft_font->descent;
+ metrics->approximate_digit_width = PANGO_SCALE * xft_font->max_advance_width;
+ metrics->approximate_char_width = PANGO_SCALE * xft_font->max_advance_width;
return metrics;
}
@@ -428,9 +428,11 @@ pango_xft_font_finalize (GObject *object
g_object_unref (xfont->ot_info);
pango_font_description_free (xfont->description);
-
- XftFontClose (display, xfont->xft_font);
+ XftPatternDestroy (xfont->font_pattern);
+ if (xfont->xft_font)
+ XftFontClose (display, xfont->xft_font);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -447,15 +449,17 @@ pango_xft_font_get_coverage (PangoFont
PangoLanguage *language)
{
PangoXftFont *xfont = (PangoXftFont *)font;
- const gchar *family = pango_font_description_get_family (xfont->description);
+ char *filename = NULL;
FT_Face face;
PangoCoverage *coverage;
Display *display;
int i;
_pango_xft_font_map_get_info (xfont->fontmap, &display, NULL);
+
+ XftPatternGetString (xfont->font_pattern, XFT_FILE, 0, &filename);
- coverage = _pango_xft_font_map_get_coverage (xfont->fontmap, family);
+ coverage = _pango_xft_font_map_get_coverage (xfont->fontmap, filename);
if (coverage)
return pango_coverage_ref (coverage);
@@ -473,7 +477,7 @@ pango_xft_font_get_coverage (PangoFont
pango_coverage_set (coverage, i, PANGO_COVERAGE_EXACT);
}
- _pango_xft_font_map_set_coverage (xfont->fontmap, family, coverage);
+ _pango_xft_font_map_set_coverage (xfont->fontmap, g_strdup (filename), coverage);
return coverage;
}
@@ -485,6 +489,7 @@ pango_xft_font_get_glyph_extents (PangoF
PangoRectangle *logical_rect)
{
PangoXftFont *xfont = (PangoXftFont *)font;
+ XftFont *xft_font = pango_xft_font_get_font (font);
XGlyphInfo extents;
Display *display;
@@ -500,7 +505,7 @@ pango_xft_font_get_glyph_extents (PangoF
if (ink_rect)
{
ink_rect->x = 0;
- ink_rect->y = PANGO_SCALE * (- xfont->xft_font->ascent + (xfont->xft_font->ascent + xfont->xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2);
+ ink_rect->y = PANGO_SCALE * (- xft_font->ascent + (xft_font->ascent + xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2);
ink_rect->width = PANGO_SCALE * (xfont->mini_width * 2 + xfont->mini_pad * 5);
ink_rect->height = PANGO_SCALE * (xfont->mini_height * 2 + xfont->mini_pad * 5);
}
@@ -508,14 +513,14 @@ pango_xft_font_get_glyph_extents (PangoF
if (logical_rect)
{
logical_rect->x = 0;
- logical_rect->y = - PANGO_SCALE * xfont->xft_font->ascent;
+ logical_rect->y = - PANGO_SCALE * xft_font->ascent;
logical_rect->width = PANGO_SCALE * (xfont->mini_width * 2 + xfont->mini_pad * 6);
- logical_rect->height = (xfont->xft_font->ascent + xfont->xft_font->descent) * PANGO_SCALE;
+ logical_rect->height = (xft_font->ascent + xft_font->descent) * PANGO_SCALE;
}
}
else
{
- XftTextExtents32 (display, xfont->xft_font, &glyph, 1, &extents);
+ XftTextExtents32 (display, xft_font, &glyph, 1, &extents);
if (ink_rect)
{
@@ -528,9 +533,9 @@ pango_xft_font_get_glyph_extents (PangoF
if (logical_rect)
{
logical_rect->x = 0;
- logical_rect->y = - xfont->xft_font->ascent * PANGO_SCALE;
+ logical_rect->y = - xft_font->ascent * PANGO_SCALE;
logical_rect->width = extents.xOff * PANGO_SCALE;
- logical_rect->height = (xfont->xft_font->ascent + xfont->xft_font->descent) * PANGO_SCALE;
+ logical_rect->height = (xft_font->ascent + xft_font->descent) * PANGO_SCALE;
}
}
}
@@ -573,11 +578,34 @@ XftFont *
pango_xft_font_get_font (PangoFont *font)
{
PangoXftFont *xfont;
+ Display *display;
+ int screen;
+ FT_Face face;
+ FT_Error error;
+ int charmap;
g_return_val_if_fail (PANGO_XFT_IS_FONT (font), NULL);
xfont = PANGO_XFT_FONT (font);
+ if (xfont->xft_font == NULL)
+ {
+ _pango_xft_font_map_get_info (xfont->fontmap, &display, &screen);
+
+ xfont->xft_font = XftFontOpenPattern (display, xfont->font_pattern);
+
+ face = xfont->xft_font->u.ft.font->face;
+
+ /* There should be a unicode encoding, since we queried for it */
+ for (charmap = 0; charmap < face->num_charmaps; charmap++)
+ if (face->charmaps[charmap]->encoding == ft_encoding_unicode)
+ break;
+
+ g_assert (charmap != face->num_charmaps);
+
+ error = FT_Set_Charmap(face, face->charmaps[charmap]);
+ }
+
return xfont->xft_font;
}
@@ -633,16 +661,16 @@ pango_xft_font_get_unknown_glyph (PangoF
FT_Face
pango_xft_font_get_face (PangoFont *font)
{
- PangoXftFont *xfont;
+ XftFont *xft_font;
g_return_val_if_fail (PANGO_XFT_IS_FONT (font), NULL);
- xfont = PANGO_XFT_FONT (font);
+ xft_font = pango_xft_font_get_font (font);
- if (xfont->xft_font->core)
+ if (xft_font->core)
return NULL;
else
- return xfont->xft_font->u.ft.font->face;
+ return xft_font->u.ft.font->face;
}
/**
Index: pango/pangoxft-fontmap.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoxft-fontmap.c,v
retrieving revision 1.8
diff -u -p -r1.8 pangoxft-fontmap.c
--- pango/pangoxft-fontmap.c 2001/10/26 21:41:03 1.8
+++ pango/pangoxft-fontmap.c 2001/11/18 01:40:49
@@ -19,11 +19,14 @@
* Boston, MA 02111-1307, USA.
*/
+#include <string.h>
+
#include "pango-fontmap.h"
#include "pangoxft.h"
#include "pangoxft-private.h"
#include "modules.h"
+#include "X11/Xft/Xft.h"
#include "X11/Xft/XftFreetype.h"
/* Number of freed fonts */
@@ -32,6 +35,7 @@
typedef struct _PangoXftFontMap PangoXftFontMap;
typedef struct _PangoXftFamily PangoXftFamily;
typedef struct _PangoXftFace PangoXftFace;
+typedef struct _PangoXftPatternSet PangoXftPatternSet;
#define PANGO_TYPE_XFT_FONT_MAP (pango_xft_font_map_get_type ())
#define PANGO_XFT_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_XFT_FONT_MAP, PangoXftFontMap))
@@ -40,14 +44,20 @@ typedef struct _PangoXftFace Pan
struct _PangoXftFontMap
{
PangoFontMap parent_instance;
+
+ GHashTable *fontset_hash; /* Maps PangoFontDescription -> PangoXftPatternSet */
+ GHashTable *coverage_hash; /* Maps font file name -> PangoCoverage */
- GHashTable *font_hash;
- GHashTable *coverage_hash;
- GQueue *freed_fonts;
+ GHashTable *fonts; /* Maps XftPattern -> PangoXftFont */
+ GQueue *freed_fonts; /* Fonts in fonts that has been freed */
+ /* List of all families availible */
PangoXftFamily **families;
int n_families; /* -1 == uninitialized */
+ /* List of all fonts (XftPatterns) availible */
+ XftFontSet *font_set;
+
Display *display;
int screen;
};
@@ -67,6 +77,12 @@ struct _PangoXftFamily
int n_faces; /* -1 == uninitialized */
};
+struct _PangoXftPatternSet
+{
+ int n_patterns;
+ XftPattern **patterns;
+};
+
#define PANGO_XFT_TYPE_FACE (pango_xft_face_get_type ())
#define PANGO_XFT_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_XFT_TYPE_FACE, PangoXftFace))
#define PANGO_XFT_IS_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_XFT_TYPE_FACE))
@@ -83,18 +99,23 @@ static GType pango_xft_font_map_get_t
GType pango_xft_family_get_type (void);
GType pango_xft_face_get_type (void);
-static void pango_xft_font_map_init (PangoXftFontMap *fontmap);
-static void pango_xft_font_map_class_init (PangoFontMapClass *class);
-static void pango_xft_font_map_finalize (GObject *object);
-static PangoFont *pango_xft_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description);
-static void pango_xft_font_map_list_families (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
-
-static void pango_xft_font_map_cache_clear (PangoXftFontMap *xfontmap);
-static void pango_xft_font_map_cache_remove (PangoFontMap *fontmap,
- PangoXftFont *xfont);
+static void pango_xft_font_map_init (PangoXftFontMap *fontmap);
+static void pango_xft_font_map_class_init (PangoFontMapClass *class);
+static void pango_xft_font_map_finalize (GObject *object);
+static PangoFont * pango_xft_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description);
+static PangoFontset *pango_xft_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+static void pango_xft_font_map_list_families (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families);
+
+
+static void pango_xft_font_set_free (PangoXftPatternSet *font_set);
+
+static void pango_xft_font_map_cache_clear (PangoXftFontMap *xfontmap);
+static void pango_xft_font_map_cache_remove (PangoFontMap *fontmap,
+ PangoXftFont *xfont);
static PangoFontClass *parent_class; /* Parent class structure for PangoXftFontMap */
@@ -141,11 +162,98 @@ pango_xft_font_map_class_init (PangoFont
object_class->finalize = pango_xft_font_map_finalize;
class->load_font = pango_xft_font_map_load_font;
+ class->load_fontset = pango_xft_font_map_load_fontset;
class->list_families = pango_xft_font_map_list_families;
}
static GSList *fontmaps = NULL;
+guint
+pango_xft_pattern_hash (XftPattern *pattern)
+{
+ char *str;
+ int i;
+ double d;
+ guint hash = 0;
+
+ XftPatternGetString (pattern, XFT_FILE, 0, &str);
+ if (str)
+ hash = g_str_hash (str);
+
+ if (XftPatternGetInteger (pattern, XFT_INDEX, 0, &i) == XftResultMatch)
+ hash ^= i;
+
+ if (XftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &d) == XftResultMatch)
+ hash ^= (guint) (d*1000.0);
+
+ return hash;
+}
+
+gboolean
+pango_xft_pattern_equal (XftPattern *pattern1,
+ XftPattern *pattern2)
+{
+ char *file1, *file2;
+ int index1, index2;
+ double size1, size2;
+ XftResult res1, res2;
+ int int1, int2;
+ Bool bool1, bool2;
+
+ XftPatternGetString (pattern1, XFT_FILE, 0, &file1);
+ XftPatternGetString (pattern2, XFT_FILE, 0, &file2);
+
+ g_assert (file1 != NULL && file2 != NULL);
+
+ if (strcmp (file1, file2) != 0)
+ return FALSE;
+
+ if (XftPatternGetInteger (pattern1, XFT_INDEX, 0, &index1) != XftResultMatch)
+ return FALSE;
+
+ if (XftPatternGetInteger (pattern2, XFT_INDEX, 0, &index2) != XftResultMatch)
+ return FALSE;
+
+ if (index1 != index2)
+ return FALSE;
+
+ if (XftPatternGetDouble (pattern1, XFT_PIXEL_SIZE, 0, &size1) != XftResultMatch)
+ return FALSE;
+
+ if (XftPatternGetDouble (pattern2, XFT_PIXEL_SIZE, 0, &size2) != XftResultMatch)
+ return FALSE;
+
+ if (size1 != size2)
+ return FALSE;
+
+ res1 = XftPatternGetInteger (pattern1, XFT_RGBA, 0, &int1);
+ res2 = XftPatternGetInteger (pattern2, XFT_RGBA, 0, &int2);
+ if (res1 != res2 || (res1 == XftResultMatch && int1 != int2))
+ return FALSE;
+
+ res1 = XftPatternGetBool (pattern1, XFT_ANTIALIAS, 0, &bool1);
+ res2 = XftPatternGetBool (pattern2, XFT_ANTIALIAS, 0, &bool2);
+ if (res1 != res2 || (res1 == XftResultMatch && bool1 != bool2))
+ return FALSE;
+
+ res1 = XftPatternGetBool (pattern1, XFT_MINSPACE, 0, &bool1);
+ res2 = XftPatternGetBool (pattern2, XFT_MINSPACE, 0, &bool2);
+ if (res1 != res2 || (res1 == XftResultMatch && bool1 != bool2))
+ return FALSE;
+
+ res1 = XftPatternGetInteger (pattern1, XFT_SPACING, 0, &int1);
+ res2 = XftPatternGetInteger (pattern2, XFT_SPACING, 0, &int2);
+ if (res1 != res2 || (res1 == XftResultMatch && int1 != int2))
+ return FALSE;
+
+ res1 = XftPatternGetInteger (pattern1, XFT_CHAR_WIDTH, 0, &int1);
+ res2 = XftPatternGetInteger (pattern2, XFT_CHAR_WIDTH, 0, &int2);
+ if (res1 != res2 || (res1 == XftResultMatch && int1 != int2))
+ return FALSE;
+
+ return TRUE;
+}
+
static PangoFontMap *
pango_xft_get_font_map (Display *display,
int screen)
@@ -172,9 +280,15 @@ pango_xft_get_font_map (Display *display
xfontmap->display = display;
xfontmap->screen = screen;
- xfontmap->font_hash = g_hash_table_new ((GHashFunc)pango_font_description_hash,
- (GEqualFunc)pango_font_description_equal);
- xfontmap->coverage_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ xfontmap->fonts = g_hash_table_new ((GHashFunc)pango_xft_pattern_hash,
+ (GEqualFunc)pango_xft_pattern_equal);
+ xfontmap->fontset_hash = g_hash_table_new_full ((GHashFunc)pango_font_description_hash,
+ (GEqualFunc)pango_font_description_equal,
+ (GDestroyNotify)pango_font_description_free,
+ (GDestroyNotify)pango_xft_font_set_free);
+ xfontmap->coverage_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)pango_coverage_unref);
xfontmap->freed_fonts = g_queue_new ();
fontmaps = g_slist_prepend (fontmaps, xfontmap);
@@ -211,21 +325,12 @@ pango_xft_get_context (Display *display,
}
result = pango_context_new ();
- pango_context_add_font_map (result, pango_xft_get_font_map (display, screen));
+ pango_context_set_font_map (result, pango_xft_get_font_map (display, screen));
return result;
}
static void
-coverage_foreach (gpointer key, gpointer value, gpointer data)
-{
- PangoCoverage *coverage = value;
-
- g_free (key);
- pango_coverage_unref (coverage);
-}
-
-static void
pango_xft_font_map_finalize (GObject *object)
{
PangoXftFontMap *xfontmap = PANGO_XFT_FONT_MAP (object);
@@ -233,30 +338,34 @@ pango_xft_font_map_finalize (GObject *ob
fontmaps = g_slist_remove (fontmaps, object);
g_queue_free (xfontmap->freed_fonts);
- g_hash_table_destroy (xfontmap->font_hash);
-
- g_hash_table_foreach (xfontmap->coverage_hash, coverage_foreach, NULL);
+ g_hash_table_destroy (xfontmap->fontset_hash);
g_hash_table_destroy (xfontmap->coverage_hash);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+
+/* Add a mapping from xfont->font_pattern to xfont */
void
_pango_xft_font_map_add (PangoFontMap *fontmap,
- PangoXftFont *xfont)
+ PangoXftFont *xfont)
{
PangoXftFontMap *xfontmap = PANGO_XFT_FONT_MAP (fontmap);
- g_hash_table_insert (xfontmap->font_hash, xfont->description, xfont);
+ g_hash_table_insert (xfontmap->fonts,
+ xfont->font_pattern,
+ xfont);
}
+/* Remove mapping from xfont->font_pattern to xfont */
void
_pango_xft_font_map_remove (PangoFontMap *fontmap,
PangoXftFont *xfont)
{
PangoXftFontMap *xfontmap = PANGO_XFT_FONT_MAP (fontmap);
- g_hash_table_remove (xfontmap->font_hash, xfont->description);
+ g_hash_table_remove (xfontmap->fonts,
+ xfont->font_pattern);
}
static void
@@ -303,38 +412,10 @@ pango_xft_font_map_list_families (PangoF
*families = g_memdup (xfontmap->families, xfontmap->n_families * sizeof (PangoFontFamily *));
}
-static PangoFont *
-pango_xft_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description)
+static int
+pango_xft_convert_weight (PangoWeight pango_weight)
{
- PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap;
- PangoXftFont *font;
- PangoStyle pango_style;
- int slant;
- PangoWeight pango_weight;
int weight;
- XftFont *xft_font;
-
- font = g_hash_table_lookup (xfontmap->font_hash, description);
-
- if (font)
- {
- if (font->in_cache)
- pango_xft_font_map_cache_remove (fontmap, font);
-
- return (PangoFont *)g_object_ref (G_OBJECT (font));
- }
-
- pango_style = pango_font_description_get_style (description);
-
- if (pango_style == PANGO_STYLE_ITALIC)
- slant = XFT_SLANT_ITALIC;
- else if (pango_style == PANGO_STYLE_OBLIQUE)
- slant = XFT_SLANT_OBLIQUE;
- else
- slant = XFT_SLANT_ROMAN;
-
- pango_weight = pango_font_description_get_weight (description);
if (pango_weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2)
weight = XFT_WEIGHT_LIGHT;
@@ -346,55 +427,199 @@ pango_xft_font_map_load_font (PangoFontM
weight = XFT_WEIGHT_BOLD;
else
weight = XFT_WEIGHT_BLACK;
+
+ return weight;
+}
+
+static int
+pango_xft_convert_slant (PangoStyle pango_style)
+{
+ int slant;
+
+ if (pango_style == PANGO_STYLE_ITALIC)
+ slant = XFT_SLANT_ITALIC;
+ else if (pango_style == PANGO_STYLE_OBLIQUE)
+ slant = XFT_SLANT_OBLIQUE;
+ else
+ slant = XFT_SLANT_ROMAN;
+
+ return slant;
+}
+
+
+static XftPattern *
+pango_xft_make_pattern (const PangoFontDescription *description)
+{
+ XftPattern *pattern;
+ PangoStyle pango_style;
+ int slant;
+ int weight;
+
+ pango_style = pango_font_description_get_style (description);
+ slant = pango_xft_convert_slant (pango_style);
+ weight = pango_xft_convert_weight (pango_font_description_get_weight (description));
+
/* To fool Xft into not munging glyph indices, we open it as glyphs-fontspecific
* then set the encoding ourself
*/
- xft_font = XftFontOpen (xfontmap->display, xfontmap->screen,
- XFT_ENCODING, XftTypeString, "glyphs-fontspecific",
- XFT_CORE, XftTypeBool, False,
- XFT_FAMILY, XftTypeString, pango_font_description_get_family (description),
- XFT_WEIGHT, XftTypeInteger, weight,
- XFT_SLANT, XftTypeInteger, slant,
- XFT_SIZE, XftTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE,
- NULL);
+ pattern = XftPatternBuild (0,
+ XFT_ENCODING, XftTypeString, "glyphs-fontspecific",
+ XFT_CORE, XftTypeBool, False,
+ XFT_FAMILY, XftTypeString, pango_font_description_get_family (description),
+ XFT_WEIGHT, XftTypeInteger, weight,
+ XFT_SLANT, XftTypeInteger, slant,
+ XFT_SIZE, XftTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE,
+ NULL);
+
+ return pattern;
+}
- if (xft_font)
+static PangoFont *
+pango_xft_font_map_new_font (PangoFontMap *fontmap,
+ XftPattern *match)
+{
+ PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap;
+ PangoXftFont *font;
+
+ /* Look up cache */
+ font = g_hash_table_lookup (xfontmap->fonts, match);
+
+ if (font)
{
- FT_Face face;
- FT_Error error;
+ /* Revive fonts from cache */
+ if (font->in_cache)
+ pango_xft_font_map_cache_remove (fontmap, font);
+
+ return (PangoFont *)g_object_ref (G_OBJECT(font));
+ }
+
+ return (PangoFont *)_pango_xft_font_new (fontmap, XftPatternDuplicate (match));
+}
+
+static PangoFont *
+pango_xft_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description)
+{
+ PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap;
+ XftPattern *pattern, *match;
+ XftResult res;
+
+ pattern = pango_xft_make_pattern (description);
- int charmap;
+ match = XftFontMatch (xfontmap->display, xfontmap->screen, pattern, &res);
+ XftPatternDestroy (pattern);
+
+ if (match)
+ return pango_xft_font_map_new_font (fontmap, match);
+
+ return NULL;
+}
+
+
+static void
+pango_xft_font_set_free (PangoXftPatternSet *font_set)
+{
+ int i;
+
+ for (i = 0; i < font_set->n_patterns; i++)
+ XftPatternDestroy (font_set->patterns[i]);
+
+ g_free (font_set);
+}
- g_assert (!xft_font->core);
+static PangoFontset *
+pango_xft_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc)
+{
+ PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap;
+ XftPattern *pattern, *pattern_copy;
+ XftPattern *match;
+ int i;
+ char *family, *family_res;
+ XftResult res;
+ int id;
+ GPtrArray *array;
+ PangoXftPatternSet *patterns;
+ int max_patterns;
+ PangoFontsetSimple *simple;
+
+ patterns = g_hash_table_lookup (xfontmap->fontset_hash, desc);
+
+ if (patterns == NULL)
+ {
+ if (xfontmap->font_set == NULL)
+ xfontmap->font_set = XftListFonts (xfontmap->display, xfontmap->screen,
+ XFT_CORE, XftTypeBool, False,
+ XFT_ENCODING, XftTypeString, "iso10646-1",
+ NULL,
+ XFT_FOUNDRY, XFT_STYLE, XFT_FAMILY,
+ XFT_ENCODING, XFT_FILE, XFT_INDEX,
+ XFT_CORE, XFT_FAMILY, XFT_WEIGHT,
+ XFT_SLANT, XFT_CHAR_WIDTH, XFT_MATRIX,
+ XFT_RGBA, XFT_ANTIALIAS, XFT_MINSPACE,
+ XFT_SPACING, XFT_SIZE,
+ NULL);
- face = xft_font->u.ft.font->face;
+ pattern = pango_xft_make_pattern (desc);
- for (charmap = 0; charmap < face->num_charmaps; charmap++)
- if (face->charmaps[charmap]->encoding == ft_encoding_unicode)
- break;
+ XftConfigSubstitute (pattern);
+ XftDefaultSubstitute (xfontmap->display, xfontmap->screen, pattern);
- if (charmap == face->num_charmaps)
- goto error;
+ pattern_copy = XftPatternDuplicate (pattern);
- error = FT_Set_Charmap(face, face->charmaps[charmap]);
+ array = g_ptr_array_new ();
- if (error)
- goto error;
+ patterns = g_new (PangoXftPatternSet, 1);
+
+ match = NULL;
+ id = 0;
+ while (XftPatternGetString (pattern, XFT_FAMILY, id++, &family) == XftResultMatch)
+ {
+ XftPatternDel (pattern_copy, XFT_FAMILY);
+ XftPatternAddString (pattern_copy, XFT_FAMILY, family);
+
+ match = XftFontSetMatch (&xfontmap->font_set, 1, pattern_copy, &res);
+
+ if (match &&
+ XftPatternGetString (match, XFT_FAMILY, 0, &family_res) == XftResultMatch &&
+ g_ascii_strcasecmp (family, family_res) == 0)
+ {
+ g_ptr_array_add (array, match);
+ match = NULL;
+ }
+ if (match)
+ XftPatternDestroy (match);
+ }
- font = _pango_xft_font_new (fontmap, description, xft_font);
- }
- else
- return NULL;
+ if (array->len == 0)
+ {
+ match = XftFontSetMatch (&xfontmap->font_set, 1, pattern, &res);
+ g_ptr_array_add (array, match);
+ }
- return (PangoFont *)font;
+ XftPatternDestroy (pattern);
+ XftPatternDestroy (pattern_copy);
- error:
+ patterns->n_patterns = array->len;
+ patterns->patterns = g_ptr_array_free (array, FALSE);
+
+ g_hash_table_insert (xfontmap->fontset_hash,
+ pango_font_description_copy (desc),
+ patterns);
+ }
- XftFontClose (xfontmap->display, xft_font);
- return NULL;
+
+ simple = pango_fontset_simple_new ();
+
+ for (i = 0; i < patterns->n_patterns; i++)
+ pango_fontset_simple_append (simple,
+ pango_xft_font_map_new_font (fontmap, patterns->patterns[i]));
+
+ return PANGO_FONTSET (simple);
}
+
void
_pango_xft_font_map_cache_add (PangoFontMap *fontmap,
PangoXftFont *xfont)
@@ -482,8 +707,8 @@ _pango_xft_font_map_get_info (PangoFontM
* PangoXftFace
*/
-static PangoFontDescription *
-font_desc_from_pattern (XftPattern *pattern)
+PangoFontDescription *
+_pango_xft_font_desc_from_pattern (XftPattern *pattern)
{
PangoFontDescription *desc;
PangoStyle style;
@@ -560,7 +785,7 @@ pango_xft_face_describe (PangoFontFace *
result_pattern = XftFontMatch (xfontmap->display, xfontmap->screen, match_pattern, &res);
if (result_pattern)
{
- desc = font_desc_from_pattern (result_pattern);
+ desc = _pango_xft_font_desc_from_pattern (result_pattern);
XftPatternDestroy (result_pattern);
}
@@ -645,7 +870,8 @@ pango_xft_family_list_faces (PangoFontFa
XftResult res;
res = XftPatternGetString (fontset->fonts[i], XFT_STYLE, 0, &s);
- g_assert (res == XftResultMatch);
+ if (res != XftResultMatch)
+ s = "Regular";
xfamily->faces[i] = g_object_new (PANGO_XFT_TYPE_FACE, NULL);
xfamily->faces[i]->style = g_strdup (s);
Index: pango/pangoxft-private.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoxft-private.h,v
retrieving revision 1.3
diff -u -p -r1.3 pangoxft-private.h
--- pango/pangoxft-private.h 2001/09/18 20:05:18 1.3
+++ pango/pangoxft-private.h 2001/11/18 01:40:49
@@ -32,7 +32,8 @@ typedef struct _PangoXftFont PangoXftFon
struct _PangoXftFont
{
PangoFont parent_instance;
-
+
+ XftPattern *font_pattern;
XftFont *xft_font;
PangoFont *mini_font;
PangoFontMap *fontmap;
@@ -47,8 +48,7 @@ struct _PangoXftFont
};
PangoXftFont * _pango_xft_font_new (PangoFontMap *font,
- const PangoFontDescription *description,
- XftFont *xft_font);
+ XftPattern *pattern);
void _pango_xft_font_map_cache_add (PangoFontMap *fontmap,
PangoXftFont *xfont);
void _pango_xft_font_map_add (PangoFontMap *fontmap,
@@ -63,6 +63,8 @@ PangoCoverage *_pango_xft_font_map_get_c
void _pango_xft_font_map_get_info (PangoFontMap *fontmap,
Display **display,
int *screen);
+
+PangoFontDescription * _pango_xft_font_desc_from_pattern (XftPattern *pattern);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]