summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-05-28 00:38:05 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-05-28 00:38:05 +0000
commit1a23b2c124df6830bc8a8027bd8b38ccc2c75531 (patch)
tree36998ab8a3d8d1211d5eec8069a8d84c98a96041 /pango
parent62244f7210302bf7608c6130185c17d3d2e714e0 (diff)
downloadpango-1a23b2c124df6830bc8a8027bd8b38ccc2c75531.tar.gz
Add libgobject.
Sat May 27 20:36:56 2000 Owen Taylor <otaylor@redhat.com> * pango/Makefile.am configure.in: Add libgobject. * pango/pango-fontmap.[ch]: GObject'ify PangoFontMap. (Pango now requires GLib-1.3 to compile) * pango/pangox-fontmap.c pango/pangox-private.h: Break the fontmap code in libpangox out into a separate file. Tue May 23 10:32:25 2000 Owen Taylor <otaylor@redhat.com> * pango/pango-layout.c (pango_layout_set_text): Allow -1 for the length.
Diffstat (limited to 'pango')
-rw-r--r--pango/Makefile.am6
-rw-r--r--pango/fonts.c131
-rw-r--r--pango/pango-context.c2
-rw-r--r--pango/pango-context.h1
-rw-r--r--pango/pango-font.h40
-rw-r--r--pango/pango-fontmap.c146
-rw-r--r--pango/pango-fontmap.h80
-rw-r--r--pango/pango-layout.c32
-rw-r--r--pango/pango.h1
-rw-r--r--pango/pangox-fontmap.c1387
-rw-r--r--pango/pangox-private.h71
-rw-r--r--pango/pangox.c1331
-rw-r--r--pango/pangox.h5
13 files changed, 1732 insertions, 1501 deletions
diff --git a/pango/Makefile.am b/pango/Makefile.am
index e9f663e6..74518397 100644
--- a/pango/Makefile.am
+++ b/pango/Makefile.am
@@ -16,6 +16,7 @@ libpango_la_SOURCES = \
pango-attributes.c \
pango-context.c \
pango-coverage.c \
+ pango-fontmap.c \
pango-item.c \
pango-layout.c \
reorder-items.c \
@@ -24,13 +25,14 @@ libpango_la_SOURCES = \
utils.h
libpangox_la_SOURCES = \
- pangox.c
+ pangox.c \
+ pangox-fontmap.c
# We use the -release flag for now until the API settles
# down at which point we'll either use the GTK+ versioning
# scheme or the standard libtool scheme.
#
-libpango_la_LDFLAGS = -release $(VERSION)
+libpango_la_LDFLAGS = -release $(VERSION) $(GLIB_LIBS)
libpangox_la_LDFLAGS = -release $(VERSION)
libpangox_la_LIBADD = $(INCLUDED_MODULES)
diff --git a/pango/fonts.c b/pango/fonts.c
index ad6de117..bfe022fd 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -549,134 +549,3 @@ pango_font_get_metrics (PangoFont *font,
font->klass->get_metrics (font, lang, metrics);
}
-
-/**
- * pango_font_map_init:
- * @fontmap: a #PangoFontMap
- *
- * Initialize a #PangoFontMap structure. This should
- * only be called from the "new" routine of code which
- * is implementing a "subclass" of #PangoFontMap
- */
-void
-pango_font_map_init (PangoFontMap *fontmap)
-{
- g_return_if_fail (fontmap != NULL);
-
- fontmap->ref_count = 1;
-}
-
-/**
- * pango_font_map_ref:
- * @fontmap: a #PangoFontMap
- *
- * Increase the reference count of a #PangoFontMap.
- */
-void
-pango_font_map_ref (PangoFontMap *fontmap)
-{
- g_return_if_fail (fontmap != NULL);
-
- fontmap->ref_count++;
-}
-
-
-/**
- * pango_font_map_unref:
- * @fontmap: a #PangoFontMap
- *
- * Decrease the reference count of a #PangoFontMap.
- * if the result is zero, destroy the font
- * and free the associated memory.
- */
-void
-pango_font_map_unref (PangoFontMap *fontmap)
-{
- g_return_if_fail (fontmap != NULL);
- g_return_if_fail (fontmap->ref_count > 0);
-
- fontmap->ref_count--;
- if (fontmap->ref_count == 0)
- fontmap->klass->destroy (fontmap);
-}
-
-/**
- * pango_font_map_load_font:
- * @fontmap: a #PangoFontMap
- * @desc: a #PangoFontDescription describing the font to load
- *
- * Load the font in the fontmap that is the closest match for @desc.
- *
- * Returns the font loaded, or %NULL if no font matched.
- **/
-PangoFont *
-pango_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *desc)
-{
- g_return_val_if_fail (fontmap != NULL, NULL);
-
- return fontmap->klass->load_font (fontmap, desc);
-}
-
-/**
- * pango_font_map_list_fonts:
- * @fontmap: a #PangoFontMap
- * @family: the family for which to list the fonts, or %NULL
- * to list fonts in all families.
- * @descs: location to store a pointer to an array of pointers to
- * #PangoFontDescription. This array should be freed
- * with pango_font_descriptions_free().
- * @n_descs: location to store the number of elements in @descs
- *
- * List all fonts in a fontmap, or the fonts in a particular family.
- **/
-void
-pango_font_map_list_fonts (PangoFontMap *fontmap,
- const char *family,
- PangoFontDescription ***descs,
- int *n_descs)
-{
- g_return_if_fail (fontmap != NULL);
-
- fontmap->klass->list_fonts (fontmap, family, descs, n_descs);
-}
-
-/**
- * pango_font_map_list_families:
- * @fontmap: a #PangoFontMap
- * @families: location to store a pointer to an array of strings.
- * This array should be freed with pango_font_map_free_families().
- * @n_families: location to store the number of elements in @descs
- *
- * List all families for a fontmap.
- **/
-void
-pango_font_map_list_families (PangoFontMap *fontmap,
- gchar ***families,
- int *n_families)
-{
- g_return_if_fail (fontmap != NULL);
-
- fontmap->klass->list_families (fontmap, families, n_families);
-}
-
-/**
- * pango_font_map_free_families:
- * @families: a list of families
- * @n_families: number of elements in @families
- *
- * Free a list of families returned from pango_font_map_list_families()
- **/
-void
-pango_font_map_free_families (gchar **families,
- int n_families)
-{
- int i;
-
- g_return_if_fail (n_families == 0 || families != NULL);
-
- for (i=0; i<n_families; i++)
- g_free (families[i]);
-
- g_free (families);
-}
diff --git a/pango/pango-context.c b/pango/pango-context.c
index 9b1db987..60a54a7d 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -111,7 +111,7 @@ pango_context_unref (PangoContext *context)
if (context->lang)
g_free (context->lang);
- g_slist_foreach (context->font_maps, (GFunc)pango_font_map_unref, NULL);
+ g_slist_foreach (context->font_maps, (GFunc)g_object_unref, NULL);
g_slist_free (context->font_maps);
}
}
diff --git a/pango/pango-context.h b/pango/pango-context.h
index 26228b1c..5b5d663d 100644
--- a/pango/pango-context.h
+++ b/pango/pango-context.h
@@ -23,6 +23,7 @@
#define __PANGO_CONTEXT_H__
#include <pango/pango-font.h>
+#include <pango/pango-fontmap.h>
#include <pango/pango-attributes.h>
#ifdef __cplusplus
diff --git a/pango/pango-font.h b/pango/pango-font.h
index 063b0cea..62d18e44 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -31,8 +31,6 @@ extern "C" {
typedef struct _PangoFontDescription PangoFontDescription;
typedef struct _PangoFontClass PangoFontClass;
-typedef struct _PangoFontMap PangoFontMap;
-typedef struct _PangoFontMapClass PangoFontMapClass;
typedef struct _PangoFontMetrics PangoFontMetrics;
typedef enum {
@@ -150,44 +148,6 @@ void pango_font_get_glyph_extents (PangoFont *font,
* Font Map
*/
-struct _PangoFontMap
-{
- PangoFontMapClass *klass;
-
- /*< private >*/
- gint ref_count;
-};
-
-struct _PangoFontMapClass
-{
- void (*destroy) (PangoFontMap *fontmap);
- PangoFont *(*load_font) (PangoFontMap *fontmap,
- const PangoFontDescription *desc);
- void (*list_fonts) (PangoFontMap *fontmap,
- const gchar *family,
- PangoFontDescription ***descs,
- int *n_descs);
- void (*list_families) (PangoFontMap *fontmap,
- gchar ***families,
- int *n_families);
-};
-
-void pango_font_map_init (PangoFontMap *fontmap);
-void pango_font_map_ref (PangoFontMap *fontmap);
-void pango_font_map_unref (PangoFontMap *fontmap);
-PangoFont *pango_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *desc);
-
-void pango_font_map_list_fonts (PangoFontMap *fontmap,
- const gchar *family,
- PangoFontDescription ***descs,
- int *n_descs);
-void pango_font_map_list_families (PangoFontMap *fontmap,
- gchar ***families,
- int *n_families);
-void pango_font_map_free_families (gchar **families,
- int n_families);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/pango/pango-fontmap.c b/pango/pango-fontmap.c
new file mode 100644
index 00000000..c5cadec3
--- /dev/null
+++ b/pango/pango-fontmap.c
@@ -0,0 +1,146 @@
+/* Pango
+ * pango-font.h: Font handling
+ *
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "pango-fontmap.h"
+
+static void pango_font_map_init (PangoFontMap *fontmap);
+static void pango_font_map_class_init (PangoFontMapClass *class);
+
+GType
+pango_font_map_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (PangoFontMapClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) pango_font_map_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PangoFontMap),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pango_font_map_init,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "PangoFontMap",
+ &object_info);
+ }
+
+ return object_type;
+}
+
+static void
+pango_font_map_init (PangoFontMap *fontmap)
+{
+}
+
+static void
+pango_font_map_class_init (PangoFontMapClass *class)
+{
+}
+
+/**
+ * pango_font_map_load_font:
+ * @fontmap: a #PangoFontMap
+ * @desc: a #PangoFontDescription describing the font to load
+ *
+ * Load the font in the fontmap that is the closest match for @desc.
+ *
+ * Returns the font loaded, or %NULL if no font matched.
+ **/
+PangoFont *
+pango_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *desc)
+{
+ g_return_val_if_fail (fontmap != NULL, NULL);
+
+ return PANGO_FONT_MAP_GET_CLASS (fontmap)->load_font (fontmap, desc);
+}
+
+/**
+ * pango_font_map_list_fonts:
+ * @fontmap: a #PangoFontMap
+ * @family: the family for which to list the fonts, or %NULL
+ * to list fonts in all families.
+ * @descs: location to store a pointer to an array of pointers to
+ * #PangoFontDescription. This array should be freed
+ * with pango_font_descriptions_free().
+ * @n_descs: location to store the number of elements in @descs
+ *
+ * List all fonts in a fontmap, or the fonts in a particular family.
+ **/
+void
+pango_font_map_list_fonts (PangoFontMap *fontmap,
+ const char *family,
+ PangoFontDescription ***descs,
+ int *n_descs)
+{
+ g_return_if_fail (fontmap != NULL);
+
+ return PANGO_FONT_MAP_GET_CLASS (fontmap)->list_fonts (fontmap, family, descs, n_descs);
+}
+
+/**
+ * pango_font_map_list_families:
+ * @fontmap: a #PangoFontMap
+ * @families: location to store a pointer to an array of strings.
+ * This array should be freed with pango_font_map_free_families().
+ * @n_families: location to store the number of elements in @descs
+ *
+ * List all families for a fontmap.
+ **/
+void
+pango_font_map_list_families (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families)
+{
+ g_return_if_fail (fontmap != NULL);
+
+ return PANGO_FONT_MAP_GET_CLASS (fontmap)->list_families (fontmap, families, n_families);
+}
+
+/**
+ * pango_font_map_free_families:
+ * @families: a list of families
+ * @n_families: number of elements in @families
+ *
+ * Free a list of families returned from pango_font_map_list_families()
+ **/
+void
+pango_font_map_free_families (gchar **families,
+ int n_families)
+{
+ int i;
+
+ g_return_if_fail (n_families == 0 || families != NULL);
+
+ for (i=0; i<n_families; i++)
+ g_free (families[i]);
+
+ g_free (families);
+}
+
+
diff --git a/pango/pango-fontmap.h b/pango/pango-fontmap.h
new file mode 100644
index 00000000..7fbe3785
--- /dev/null
+++ b/pango/pango-fontmap.h
@@ -0,0 +1,80 @@
+/* Pango
+ * pango-font.h: Font handling
+ *
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PANGO_FONTMAP_H__
+#define __PANGO_FONTMAP_H__
+
+#include <pango/pango-font.h>
+#include <glib-object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define PANGO_TYPE_FONT_MAP (pango_font_map_get_type ())
+#define PANGO_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONT_MAP, PangoFontMap))
+#define PANGO_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_MAP, PangoFontMapClass))
+#define PANGO_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONT_MAP))
+#define PANGO_IS_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FONT_MAP))
+#define PANGO_FONT_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONT_MAP, PangoFontMapClass))
+
+typedef struct _PangoFontMap PangoFontMap;
+typedef struct _PangoFontMapClass PangoFontMapClass;
+
+struct _PangoFontMap
+{
+ GObject parent_instance;
+};
+
+struct _PangoFontMapClass
+{
+ GObjectClass parent_class;
+
+ void (*destroy) (PangoFontMap *fontmap);
+ PangoFont *(*load_font) (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+ void (*list_fonts) (PangoFontMap *fontmap,
+ const gchar *family,
+ PangoFontDescription ***descs,
+ int *n_descs);
+ void (*list_families) (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families);
+};
+
+GType pango_font_map_get_type (void);
+PangoFont *pango_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+void pango_font_map_list_fonts (PangoFontMap *fontmap,
+ const gchar *family,
+ PangoFontDescription ***descs,
+ int *n_descs);
+void pango_font_map_list_families (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families);
+void pango_font_map_free_families (gchar **families,
+ int n_families);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif __PANGO_FONTMAP_H__
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 08af0edc..9cfa39f8 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -377,7 +377,9 @@ pango_layout_get_alignment (PangoLayout *layout)
* pango_layout_set_text:
* @layout: a #PangoLayout
* @text: a UTF8-string
- * @length: the length of @text, in bytes.
+ * @length: the length of @text, in bytes. -1 indicates that
+ * the string is null terminated and the length should be
+ * calculated.
*
* Set the text of the layout.
**/
@@ -392,22 +394,35 @@ pango_layout_set_text (PangoLayout *layout,
if (layout->text)
g_free (layout->text);
- if (length > 0)
+ if (length == 0)
+ {
+ layout->text = g_strdup ("");
+ layout->n_chars = 0;
+ }
+ else
{
- int n_chars = unicode_strlen (text, length);
unicode_char_t junk;
char *p = text;
- int i;
+ int n_chars = 0;
- for (i=0; i<n_chars; i++)
+ while (*p && (length < 0 || p < text + length))
{
p = unicode_get_utf8 (p, &junk);
- if (!p || !junk)
+ if (!p)
{
g_warning ("Invalid UTF8 string passed to pango_layout_set_text()");
return;
}
+ n_chars++;
}
+
+ if (length < 0)
+ length = p - text;
+
+ if (length >= 0 && p != text + length)
+ g_warning ("string passed to pango_layout_set_text() contains embedded NULL");
+
+ length = p - text;
/* NULL-terminate the text, since we currently use unicode_next_utf8()
* in quite a few places, and for convenience.
@@ -419,11 +434,6 @@ pango_layout_set_text (PangoLayout *layout,
layout->n_chars = n_chars;
}
- else
- {
- layout->text = g_strdup ("");
- layout->n_chars = 0;
- }
layout->length = length;
diff --git a/pango/pango.h b/pango/pango.h
index 3e7d1d5d..5d083b9f 100644
--- a/pango/pango.h
+++ b/pango/pango.h
@@ -33,6 +33,7 @@ extern "C" {
#include <pango/pango-coverage.h>
#include <pango/pango-engine.h>
#include <pango/pango-font.h>
+#include <pango/pango-fontmap.h>
#include <pango/pango-glyph.h>
#include <pango/pango-item.h>
#include <pango/pango-layout.h>
diff --git a/pango/pangox-fontmap.c b/pango/pangox-fontmap.c
new file mode 100644
index 00000000..49cbfb06
--- /dev/null
+++ b/pango/pangox-fontmap.c
@@ -0,0 +1,1387 @@
+/* Pango
+ * pango-font.h: Font handling
+ *
+ * Copyright (C) 2000 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "pango-fontmap.h"
+#include "pangox-private.h"
+
+#define PANGO_TYPE_X_FONT_MAP (pango_x_font_map_get_type ())
+#define PANGO_X_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_X_FONT_MAP, PangoXFontMap))
+#define PANGO_X_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_X_FONT_MAP, PangoXFontMapClass))
+#define PANGO_IS_X_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_X_FONT_MAP))
+#define PANGO_IS_X_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_X_FONT_MAP))
+#define PANGO_X_FONT_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_X_FONT_MAP, PangoXFontMapClass))
+
+typedef struct _PangoXFamilyEntry PangoXFamilyEntry;
+typedef struct _PangoXFontMap PangoXFontMap;
+typedef struct _PangoXFontMapClass PangoXFontMapClass;
+typedef struct _PangoXSizeInfo PangoXSizeInfo;
+
+/* This is the largest field length we will accept. If a fontname has a field
+ larger than this we will skip it. */
+#define XLFD_MAX_FIELD_LEN 64
+#define MAX_FONTS 32767
+
+/* These are the field numbers in the X Logical Font Description fontnames,
+ e.g. -adobe-courier-bold-o-normal--25-180-100-100-m-150-iso8859-1 */
+typedef enum
+{
+ XLFD_FOUNDRY = 0,
+ XLFD_FAMILY = 1,
+ XLFD_WEIGHT = 2,
+ XLFD_SLANT = 3,
+ XLFD_SET_WIDTH = 4,
+ XLFD_ADD_STYLE = 5,
+ XLFD_PIXELS = 6,
+ XLFD_POINTS = 7,
+ XLFD_RESOLUTION_X = 8,
+ XLFD_RESOLUTION_Y = 9,
+ XLFD_SPACING = 10,
+ XLFD_AVERAGE_WIDTH = 11,
+ XLFD_CHARSET = 12,
+ XLFD_NUM_FIELDS
+} FontField;
+
+struct _PangoXFontMap
+{
+ PangoFontMap parent_instance;
+
+ Display *display;
+
+ GHashTable *families;
+ GHashTable *size_infos;
+
+ int n_fonts;
+
+ double resolution; /* (points / pixel) * PANGO_SCALE */
+};
+
+struct _PangoXFontMapClass
+{
+ PangoFontMapClass parent_class;
+};
+
+struct _PangoXFamilyEntry
+{
+ char *family_name;
+ GSList *font_entries;
+};
+
+struct _PangoXFontEntry
+{
+ char *xlfd;
+ PangoFontDescription description;
+ PangoCoverage *coverage;
+
+ GSList *cached_fonts;
+};
+
+struct _PangoXSizeInfo
+{
+ char *identifier;
+ GSList *xlfds;
+};
+
+const struct {
+ const gchar *text;
+ PangoWeight value;
+} weights_map[] = {
+ { "light", 300 },
+ { "regular", 400 },
+ { "book", 400 },
+ { "medium", 500 },
+ { "semibold", 600 },
+ { "demibold", 600 },
+ { "bold", 700 },
+ { "extrabold", 800 },
+ { "ultrabold", 800 },
+ { "heavy", 900 },
+ { "black", 900 }
+};
+
+const struct {
+ const gchar *text;
+ PangoStyle value;
+} styles_map[] = {
+ { "r", PANGO_STYLE_NORMAL },
+ { "i", PANGO_STYLE_ITALIC },
+ { "o", PANGO_STYLE_OBLIQUE }
+};
+
+const struct {
+ const gchar *text;
+ PangoStretch value;
+} stretches_map[] = {
+ { "normal", PANGO_STRETCH_NORMAL },
+ { "semicondensed", PANGO_STRETCH_SEMI_CONDENSED },
+ { "condensed", PANGO_STRETCH_CONDENSED },
+};
+
+static GType pango_x_font_map_get_type (void);
+static void pango_x_font_map_init (PangoXFontMap *fontmap);
+static void pango_x_font_map_class_init (PangoXFontMapClass *class);
+
+static void pango_x_font_map_finalize (GObject *object);
+static PangoFont *pango_x_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description);
+static void pango_x_font_map_list_fonts (PangoFontMap *fontmap,
+ const gchar *family,
+ PangoFontDescription ***descs,
+ int *n_descs);
+static void pango_x_font_map_list_families (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families);
+
+static void pango_x_font_map_read_aliases (PangoXFontMap *xfontmap);
+
+static gint pango_x_get_size (PangoXFontMap *fontmap,
+ const char *fontname);
+static void pango_x_insert_font (PangoXFontMap *fontmap,
+ const char *fontname);
+static gboolean pango_x_is_xlfd_font_name (const char *fontname);
+static char * pango_x_get_xlfd_field (const char *fontname,
+ FontField field_num,
+ char *buffer);
+static char * pango_x_get_identifier (const char *fontname);
+
+static GType
+pango_x_font_map_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (PangoXFontMapClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) pango_x_font_map_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PangoXFontMap),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pango_x_font_map_init,
+ };
+
+ object_type = g_type_register_static (PANGO_TYPE_FONT_MAP,
+ "PangoXFontMap",
+ &object_info);
+ }
+
+ return object_type;
+}
+
+static void
+pango_x_font_map_init (PangoXFontMap *xfontmap)
+{
+ xfontmap->families = g_hash_table_new (g_str_hash, g_str_equal);
+ xfontmap->size_infos = g_hash_table_new (g_str_hash, g_str_equal);
+ xfontmap->n_fonts = 0;
+}
+
+static void
+pango_x_font_map_class_init (PangoXFontMapClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontMapClass *font_map_class = PANGO_FONT_MAP_CLASS (class);
+
+ object_class->finalize = pango_x_font_map_finalize;
+ font_map_class->load_font = pango_x_font_map_load_font;
+ font_map_class->list_fonts = pango_x_font_map_list_fonts;
+ font_map_class->list_families = pango_x_font_map_list_families;
+}
+
+static GList *fontmaps = NULL;
+
+PangoFontMap *
+pango_x_font_map_for_display (Display *display)
+{
+ PangoXFontMap *xfontmap;
+ GList *tmp_list = fontmaps;
+ char **xfontnames;
+ int num_fonts, i;
+ int screen;
+
+ /* Make sure that the type system is initialized */
+ g_type_init();
+
+ while (tmp_list)
+ {
+ xfontmap = tmp_list->data;
+
+ if (xfontmap->display == display)
+ {
+ g_object_ref (G_OBJECT (xfontmap));
+ return PANGO_FONT_MAP (xfontmap);
+ }
+ }
+
+ xfontmap = (PangoXFontMap *)g_type_create_instance (PANGO_TYPE_X_FONT_MAP);
+
+ xfontmap->display = display;
+
+ /* Get a maximum of MAX_FONTS fontnames from the X server.
+ Use "-*" as the pattern rather than "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" since
+ the latter may result in fonts being returned which don't actually exist.
+ xlsfonts also uses "*" so I think it's OK. "-*" gets rid of aliases. */
+ xfontnames = XListFonts (xfontmap->display, "-*", MAX_FONTS, &num_fonts);
+ if (num_fonts == MAX_FONTS)
+ g_warning("MAX_FONTS exceeded. Some fonts may be missing.");
+
+ /* Insert the font families into the main table */
+ for (i = 0; i < num_fonts; i++)
+ {
+ if (pango_x_is_xlfd_font_name (xfontnames[i]))
+ pango_x_insert_font (xfontmap, xfontnames[i]);
+ }
+
+ XFreeFontNames (xfontnames);
+
+ pango_x_font_map_read_aliases (xfontmap);
+
+ fontmaps = g_list_prepend (fontmaps, xfontmap);
+
+ /* This is a little screwed up, since different screens on the same display
+ * might have different resolutions
+ */
+ screen = DefaultScreen (xfontmap->display);
+ xfontmap->resolution = (PANGO_SCALE * 72.27 / 25.4) * ((double) DisplayWidthMM (xfontmap->display, screen) /
+ DisplayWidth (xfontmap->display, screen));
+
+ g_object_ref (G_OBJECT (xfontmap));
+ return PANGO_FONT_MAP (xfontmap);
+}
+
+static void
+pango_x_font_map_finalize (GObject *object)
+{
+ fontmaps = g_list_remove (fontmaps, object);
+}
+
+typedef struct
+{
+ int n_found;
+ PangoFontDescription **descs;
+} ListFontsInfo;
+
+static void
+list_fonts_foreach (gpointer key, gpointer value, gpointer user_data)
+{
+ PangoXFamilyEntry *entry = value;
+ ListFontsInfo *info = user_data;
+
+ GSList *tmp_list = entry->font_entries;
+
+ while (tmp_list)
+ {
+ PangoXFontEntry *font_entry = tmp_list->data;
+
+ info->descs[info->n_found++] = pango_font_description_copy (&font_entry->description);
+ tmp_list = tmp_list->next;
+ }
+}
+
+static void
+pango_x_font_map_list_fonts (PangoFontMap *fontmap,
+ const gchar *family,
+ PangoFontDescription ***descs,
+ int *n_descs)
+{
+ PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;
+ ListFontsInfo info;
+
+ if (!n_descs)
+ return;
+
+ if (family)
+ {
+ PangoXFamilyEntry *entry = g_hash_table_lookup (xfontmap->families, family);
+ if (entry)
+ {
+ *n_descs = g_slist_length (entry->font_entries);
+ if (descs)
+ {
+ *descs = g_new (PangoFontDescription *, *n_descs);
+
+ info.descs = *descs;
+ info.n_found = 0;
+
+ list_fonts_foreach ((gpointer)family, (gpointer)entry, &info);
+ }
+ }
+ else
+ {
+ *n_descs = 0;
+ if (descs)
+ *descs = NULL;
+ }
+ }
+ else
+ {
+ *n_descs = xfontmap->n_fonts;
+ if (descs)
+ {
+ *descs = g_new (PangoFontDescription *, xfontmap->n_fonts);
+
+ info.descs = *descs;
+ info.n_found = 0;
+
+ g_hash_table_foreach (xfontmap->families, list_fonts_foreach, &info);
+ }
+ }
+}
+
+static void
+list_families_foreach (gpointer key, gpointer value, gpointer user_data)
+{
+ GSList **list = user_data;
+
+ *list = g_slist_prepend (*list, key);
+}
+
+static void
+pango_x_font_map_list_families (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families)
+{
+ GSList *family_list = NULL;
+ GSList *tmp_list;
+ PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;
+
+ if (!n_families)
+ return;
+
+ g_hash_table_foreach (xfontmap->families, list_families_foreach, &family_list);
+
+ *n_families = g_slist_length (family_list);
+
+ if (families)
+ {
+ int i = 0;
+
+ *families = g_new (gchar *, *n_families);
+
+ tmp_list = family_list;
+ while (tmp_list)
+ {
+ (*families)[i] = g_strdup (tmp_list->data);
+ i++;
+ tmp_list = tmp_list->next;
+ }
+ }
+
+ g_slist_free (family_list);
+}
+
+static PangoXFamilyEntry *
+pango_x_get_family_entry (PangoXFontMap *xfontmap,
+ const char *family_name)
+{
+ PangoXFamilyEntry *family_entry = g_hash_table_lookup (xfontmap->families, family_name);
+ if (!family_entry)
+ {
+ family_entry = g_new (PangoXFamilyEntry, 1);
+ family_entry->family_name = g_strdup (family_name);
+ family_entry->font_entries = NULL;
+
+ g_hash_table_insert (xfontmap->families, family_entry->family_name, family_entry);
+ }
+
+ return family_entry;
+}
+
+static PangoFont *
+pango_x_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description)
+{
+ PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;
+ PangoXFamilyEntry *family_entry;
+ PangoFont *result = NULL;
+ GSList *tmp_list;
+ gchar *name;
+
+ g_return_val_if_fail (description != NULL, NULL);
+ g_return_val_if_fail (description->size > 0, NULL);
+
+ name = g_strdup (description->family_name);
+ g_strdown (name);
+
+ family_entry = g_hash_table_lookup (xfontmap->families, name);
+ if (family_entry)
+ {
+ PangoXFontEntry *best_match = NULL;
+
+ tmp_list = family_entry->font_entries;
+ while (tmp_list)
+ {
+ PangoXFontEntry *font_entry = tmp_list->data;
+
+ if (font_entry->description.style == description->style &&
+ font_entry->description.variant == description->variant &&
+ font_entry->description.stretch == description->stretch)
+ {
+ int distance = abs(font_entry->description.weight - description->weight);
+ int old_distance = best_match ? abs(best_match->description.weight - description->weight) : G_MAXINT;
+
+ if (distance < old_distance)
+ {
+ best_match = font_entry;
+ }
+ }
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (best_match)
+ {
+ GSList *tmp_list = best_match->cached_fonts;
+
+ while (tmp_list)
+ {
+ PangoXFont *xfont = tmp_list->data;
+ if (xfont->size == description->size)
+ {
+ result = (PangoFont *)xfont;
+ pango_font_ref (result);
+ break;
+ }
+ tmp_list = tmp_list->next;
+ }
+
+ if (!result)
+ {
+ result = pango_x_load_font_with_size (xfontmap->display, best_match->xlfd, description->size);
+ ((PangoXFont *)result)->entry = best_match;
+ best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, result);
+ }
+
+ /* HORRIBLE performance hack until some better caching scheme is arrived at
+ */
+ if (result)
+ pango_font_ref (result);
+ }
+ }
+
+ g_free (name);
+ return result;
+}
+
+/* Similar to GNU libc's getline, but buffer is g_malloc'd */
+static size_t
+pango_getline (char **lineptr, size_t *n, FILE *stream)
+{
+#define EXPAND_CHUNK 16
+
+ int n_read = 0;
+ int result = -1;
+
+ g_return_val_if_fail (lineptr != NULL, -1);
+ g_return_val_if_fail (n != NULL, -1);
+ g_return_val_if_fail (*lineptr != NULL || *n == 0, -1);
+
+#ifdef HAVE_FLOCKFILE
+ flockfile (stream);
+#endif
+
+ while (1)
+ {
+ int c;
+
+#ifdef HAVE_FLOCKFILE
+ c = getc_unlocked (stream);
+#else
+ c = getc (stream);
+#endif
+
+ if (c == EOF)
+ {
+ if (n_read > 0)
+ {
+ result = n_read;
+ (*lineptr)[n_read] = '\0';
+ }
+ break;
+ }
+
+ if (n_read + 2 >= *n)
+ {
+ *n += EXPAND_CHUNK;
+ *lineptr = g_realloc (*lineptr, *n);
+ }
+
+ (*lineptr)[n_read] = c;
+ n_read++;
+
+ if (c == '\n' || c == '\r')
+ {
+ result = n_read;
+ (*lineptr)[n_read] = '\0';
+ break;
+ }
+ }
+
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stream);
+#endif
+
+ return n_read - 1;
+}
+
+static int
+find_tok (char **start, char **tok)
+{
+ char *p = *start;
+
+ while (*p && (*p == ' ' || *p == '\t'))
+ p++;
+
+ if (*p == 0 || *p == '\n' || *p == '\r')
+ return -1;
+
+ if (*p == '"')
+ {
+ p++;
+ *tok = p;
+
+ while (*p && *p != '"')
+ p++;
+
+ if (*p != '"')
+ return -1;
+
+ *start = p + 1;
+ return p - *tok;
+ }
+ else
+ {
+ *tok = p;
+
+ while (*p && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n')
+ p++;
+
+ *start = p;
+ return p - *tok;
+ }
+}
+
+static gboolean
+get_style (char *tok, int toksize, PangoFontDescription *desc)
+{
+ if (toksize == 0)
+ return FALSE;
+
+ switch (tok[0])
+ {
+ case 'n':
+ case 'N':
+ if (strncasecmp (tok, "normal", toksize) == 0)
+ {
+ desc->style = PANGO_STYLE_NORMAL;
+ return TRUE;
+ }
+ break;
+ case 'i':
+ if (strncasecmp (tok, "italic", toksize) == 0)
+ {
+ desc->style = PANGO_STYLE_ITALIC;
+ return TRUE;
+ }
+ break;
+ case 'o':
+ if (strncasecmp (tok, "oblique", toksize) == 0)
+ {
+ desc->style = PANGO_STYLE_OBLIQUE;
+ return TRUE;
+ }
+ break;
+ }
+ g_warning ("Style must be normal, italic, or oblique");
+
+ return FALSE;
+}
+
+static gboolean
+get_variant (char *tok, int toksize, PangoFontDescription *desc)
+{
+ if (toksize == 0)
+ return FALSE;
+
+ switch (tok[0])
+ {
+ case 'n':
+ case 'N':
+ if (strncasecmp (tok, "normal", toksize) == 0)
+ {
+ desc->variant = PANGO_VARIANT_NORMAL;
+ return TRUE;
+ }
+ break;
+ case 's':
+ case 'S':
+ if (strncasecmp (tok, "small_caps", toksize) == 0)
+ {
+ desc->variant = PANGO_VARIANT_SMALL_CAPS;
+ return TRUE;
+ }
+ break;
+ }
+
+ g_warning ("Variant must be normal, or small_caps");
+ return FALSE;
+}
+
+static gboolean
+get_weight (char *tok, int toksize, PangoFontDescription *desc)
+{
+ if (toksize == 0)
+ return FALSE;
+
+ switch (tok[0])
+ {
+ case 'n':
+ case 'N':
+ if (strncasecmp (tok, "normal", toksize) == 0)
+ {
+ desc->weight = PANGO_WEIGHT_NORMAL;
+ return TRUE;
+ }
+ break;
+ case 'b':
+ case 'B':
+ if (strncasecmp (tok, "bold", toksize) == 0)
+ {
+ desc->weight = PANGO_WEIGHT_BOLD;
+ return TRUE;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ char *numstr, *end;
+
+ numstr = g_strndup (tok, toksize);
+
+ desc->weight = strtol (numstr, &end, 0);
+ if (*end != '\0')
+ {
+ g_warning ("Cannot parse numerical weight '%s'", numstr);
+ g_free (numstr);
+ return FALSE;
+ }
+
+ g_free (numstr);
+ return TRUE;
+ }
+ }
+
+ g_warning ("Weight must be normal, bold, or an integer");
+ return FALSE;
+}
+
+static gboolean
+get_stretch (char *tok, int toksize, PangoFontDescription *desc)
+{
+ if (toksize == 0)
+ return FALSE;
+
+ switch (tok[0])
+ {
+ case 'c':
+ case 'C':
+ if (strncasecmp (tok, "condensed", toksize) == 0)
+ {
+ desc->stretch = PANGO_STRETCH_CONDENSED;
+ return TRUE;
+ }
+ break;
+ case 'e':
+ case 'E':
+ if (strncasecmp (tok, "extra_condensed", toksize) == 0)
+ {
+ desc->stretch = PANGO_STRETCH_EXTRA_CONDENSED;
+ return TRUE;
+ }
+ if (strncasecmp (tok, "extra_expanded", toksize) == 0)
+ {
+ desc->stretch = PANGO_STRETCH_EXTRA_EXPANDED;
+ return TRUE;
+ }
+ if (strncasecmp (tok, "expanded", toksize) == 0)
+ {
+ desc->stretch = PANGO_STRETCH_EXPANDED;
+ return TRUE;
+ }
+ break;
+ case 'n':
+ case 'N':
+ if (strncasecmp (tok, "normal", toksize) == 0)
+ {
+ desc->stretch = PANGO_STRETCH_NORMAL;
+ return TRUE;
+ }
+ break;
+ case 's':
+ case 'S':
+ if (strncasecmp (tok, "semi_condensed", toksize) == 0)
+ {
+ desc->stretch = PANGO_STRETCH_SEMI_CONDENSED;
+ return TRUE;
+ }
+ if (strncasecmp (tok, "semi_expanded", toksize) == 0)
+ {
+ desc->stretch = PANGO_STRETCH_SEMI_EXPANDED;
+ return TRUE;
+ }
+ break;
+ case 'u':
+ case 'U':
+ if (strncasecmp (tok, "ultra_condensed", toksize) == 0)
+ {
+ desc->stretch = PANGO_STRETCH_ULTRA_CONDENSED;
+ return TRUE;
+ }
+ if (strncasecmp (tok, "ultra_expanded", toksize) == 0)
+ {
+ desc->variant = PANGO_STRETCH_ULTRA_EXPANDED;
+ return TRUE;
+ }
+ break;
+ }
+
+ g_warning ("Stretch must be ultra_condensed, extra_condensed, condensed, semi_condensed, normal, semi_expanded, expanded, extra_expanded, or ultra_expanded");
+ return FALSE;
+}
+
+static void
+pango_x_font_map_read_alias_file (PangoXFontMap *xfontmap,
+ const char *filename)
+{
+ FILE *infile;
+ char **xlfds;
+ char *buf = NULL;
+ size_t bufsize = 0;
+ int lineno = 0;
+ int i;
+ PangoXFontEntry *font_entry = NULL;
+
+ infile = fopen (filename, "r");
+ if (infile)
+ {
+ while (pango_getline (&buf, &bufsize, infile) != EOF)
+ {
+ PangoXFamilyEntry *family_entry;
+
+ char *tok;
+ char *p = buf;
+
+ int toksize;
+ lineno++;
+
+ while (*p && (*p == ' ' || *p == '\t'))
+ p++;
+
+ if (*p == 0 || *p == '#' || *p == '\n' || *p == '\r')
+ continue;
+
+ toksize = find_tok (&p, &tok);
+ if (toksize == -1)
+ goto error;
+
+ font_entry = g_new (PangoXFontEntry, 1);
+ font_entry->xlfd = NULL;
+ font_entry->description.family_name = g_strndup (tok, toksize);
+ g_strdown (font_entry->description.family_name);
+
+ toksize = find_tok (&p, &tok);
+ if (toksize == -1)
+ goto error;
+
+ if (!get_style (tok, toksize, &font_entry->description))
+ goto error;
+
+ toksize = find_tok (&p, &tok);
+ if (toksize == -1)
+ goto error;
+
+ if (!get_variant (tok, toksize, &font_entry->description))
+ goto error;
+
+ toksize = find_tok (&p, &tok);
+ if (toksize == -1)
+ goto error;
+
+ if (!get_weight (tok, toksize, &font_entry->description))
+ goto error;
+
+ toksize = find_tok (&p, &tok);
+ if (toksize == -1)
+ goto error;
+
+ if (!get_stretch (tok, toksize, &font_entry->description))
+ goto error;
+
+ toksize = find_tok (&p, &tok);
+ if (toksize == -1)
+ goto error;
+
+ font_entry->xlfd = g_strndup (tok, toksize);
+
+ /* Check for complete fields */
+
+ xlfds = g_strsplit (font_entry->xlfd, ",", -1);
+ for (i=0; xlfds[i]; i++)
+ if (!pango_x_is_xlfd_font_name (xlfds[i]))
+ {
+ g_warning ("XLFD '%s' must be complete (14 fields)", xlfds[i]);
+ g_strfreev (xlfds);
+ goto error;
+ }
+
+ g_strfreev (xlfds);
+
+
+ /* Insert the font entry into our structures */
+
+ family_entry = pango_x_get_family_entry (xfontmap, font_entry->description.family_name);
+ family_entry->font_entries = g_slist_prepend (family_entry->font_entries, font_entry);
+ xfontmap->n_fonts++;
+
+ g_free (font_entry->description.family_name);
+ font_entry->description.family_name = family_entry->family_name;
+ font_entry->cached_fonts = NULL;
+ font_entry->coverage = NULL;
+ }
+
+ if (ferror (infile))
+ g_warning ("Error reading '%s': %s", filename, g_strerror(errno));
+
+ goto out;
+
+ error:
+ if (font_entry)
+ {
+ if (font_entry->xlfd)
+ g_free (font_entry->xlfd);
+ if (font_entry->description.family_name)
+ g_free (font_entry->description.family_name);
+ g_free (font_entry);
+ }
+
+ g_warning ("Error parsing line %d of alias file '%s'", lineno, filename);
+
+ out:
+ g_free (buf);
+ fclose (infile);
+ return;
+ }
+
+}
+
+static void
+pango_x_font_map_read_aliases (PangoXFontMap *xfontmap)
+{
+ char *filename;
+
+ pango_x_font_map_read_alias_file (xfontmap, SYSCONFDIR "/pango/pangox_aliases");
+
+ filename = g_strconcat (g_get_home_dir(), "/.pangox_aliases", NULL);
+ pango_x_font_map_read_alias_file (xfontmap, filename);
+ g_free (filename);
+
+ /* FIXME: Remove this one */
+ pango_x_font_map_read_alias_file (xfontmap, "pangox_aliases");
+}
+
+/*
+ * Returns TRUE if the fontname is a valid XLFD.
+ * (It just checks if the number of dashes is 14, and that each
+ * field < XLFD_MAX_FIELD_LEN characters long - that's not in the XLFD but it
+ * makes it easier for me).
+ */
+static gboolean
+pango_x_is_xlfd_font_name (const char *fontname)
+{
+ int i = 0;
+ int field_len = 0;
+
+ while (*fontname)
+ {
+ if (*fontname++ == '-')
+ {
+ if (field_len > XLFD_MAX_FIELD_LEN) return FALSE;
+ field_len = 0;
+ i++;
+ }
+ else
+ field_len++;
+ }
+
+ return (i == 14) ? TRUE : FALSE;
+}
+
+static int
+pango_x_get_size (PangoXFontMap *xfontmap, const char *fontname)
+{
+ char size_buffer[XLFD_MAX_FIELD_LEN];
+ int size;
+
+ if (!pango_x_get_xlfd_field (fontname, XLFD_PIXELS, size_buffer))
+ return -1;
+
+ size = atoi (size_buffer);
+ if (size != 0)
+ {
+ return (int)(0.5 + size * xfontmap->resolution);
+ }
+ else
+ {
+ /* We use the trick that scaled bitmaps have a non-zero RESOLUTION_X, while
+ * actual scaleable fonts have a zero RESOLUTION_X */
+ if (!pango_x_get_xlfd_field (fontname, XLFD_RESOLUTION_X, size_buffer))
+ return -1;
+
+ if (atoi (size_buffer) == 0)
+ return 0;
+ else
+ return -1;
+ }
+}
+
+static char *
+pango_x_get_identifier (const char *fontname)
+{
+ const char *p = fontname;
+ const char *start;
+ int n_dashes = 0;
+
+ while (n_dashes < 2)
+ {
+ if (*p == '-')
+ n_dashes++;
+ p++;
+ }
+
+ start = p;
+
+ while (n_dashes < 6)
+ {
+ if (*p == '-')
+ n_dashes++;
+ p++;
+ }
+
+ return g_strndup (start, (p - 1 - start));
+}
+
+/*
+ * This fills the buffer with the specified field from the X Logical Font
+ * Description name, and returns it. If fontname is NULL or the field is
+ * longer than XFLD_MAX_FIELD_LEN it returns NULL.
+ * Note: For the charset field, we also return the encoding, e.g. 'iso8859-1'.
+ */
+static char*
+pango_x_get_xlfd_field (const char *fontname,
+ FontField field_num,
+ char *buffer)
+{
+ const char *t1, *t2;
+ int countdown, len, num_dashes;
+
+ if (!fontname)
+ return NULL;
+
+ /* we assume this is a valid fontname...that is, it has 14 fields */
+
+ countdown = field_num;
+ t1 = fontname;
+ while (*t1 && (countdown >= 0))
+ if (*t1++ == '-')
+ countdown--;
+
+ num_dashes = (field_num == XLFD_CHARSET) ? 2 : 1;
+ for (t2 = t1; *t2; t2++)
+ {
+ if (*t2 == '-' && --num_dashes == 0)
+ break;
+ }
+
+ if (t1 != t2)
+ {
+ /* Check we don't overflow the buffer */
+ len = (long) t2 - (long) t1;
+ if (len > XLFD_MAX_FIELD_LEN - 1)
+ return NULL;
+ strncpy (buffer, t1, len);
+ buffer[len] = 0;
+ /* Convert to lower case. */
+ g_strdown (buffer);
+ }
+ else
+ strcpy(buffer, "(nil)");
+
+ return buffer;
+}
+
+/* This inserts the given fontname into the FontInfo table.
+ If a FontInfo already exists with the same family and foundry, then the
+ fontname is added to the FontInfos list of fontnames, else a new FontInfo
+ is created and inserted in alphabetical order in the table. */
+static void
+pango_x_insert_font (PangoXFontMap *xfontmap,
+ const char *fontname)
+{
+ PangoFontDescription description;
+ char family_buffer[XLFD_MAX_FIELD_LEN];
+ char weight_buffer[XLFD_MAX_FIELD_LEN];
+ char slant_buffer[XLFD_MAX_FIELD_LEN];
+ char set_width_buffer[XLFD_MAX_FIELD_LEN];
+ GSList *tmp_list;
+ PangoXFamilyEntry *family_entry;
+ PangoXFontEntry *font_entry;
+ PangoXSizeInfo *size_info;
+ char *identifier;
+ int i;
+
+ description.size = 0;
+
+ /* First insert the XLFD into the list of XLFDs for the "identifier" - which
+ * is the 2-4th fields of the XLFD
+ */
+ identifier = pango_x_get_identifier (fontname);
+ size_info = g_hash_table_lookup (xfontmap->size_infos, identifier);
+ if (!size_info)
+ {
+ size_info = g_new (PangoXSizeInfo, 1);
+ size_info->identifier = identifier;
+ size_info->xlfds = NULL;
+
+ g_hash_table_insert (xfontmap->size_infos, identifier, size_info);
+ }
+ else
+ g_free (identifier);
+
+ size_info->xlfds = g_slist_prepend (size_info->xlfds, g_strdup (fontname));
+
+ /* Convert the XLFD into a PangoFontDescription */
+
+ description.family_name = pango_x_get_xlfd_field (fontname, XLFD_FAMILY, family_buffer);
+ g_strdown (description.family_name);
+
+ if (!description.family_name)
+ return;
+
+ description.style = PANGO_STYLE_NORMAL;
+ if (pango_x_get_xlfd_field (fontname, XLFD_SLANT, slant_buffer))
+ {
+ for (i=0; i<G_N_ELEMENTS(styles_map); i++)
+ {
+ if (!strcmp (styles_map[i].text, slant_buffer))
+ {
+ description.style = styles_map[i].value;
+ break;
+ }
+ }
+ }
+ else
+ strcpy (slant_buffer, "*");
+
+ description.variant = PANGO_VARIANT_NORMAL;
+
+ description.weight = PANGO_WEIGHT_NORMAL;
+ if (pango_x_get_xlfd_field (fontname, XLFD_WEIGHT, weight_buffer))
+ {
+ for (i=0; i<G_N_ELEMENTS(weights_map); i++)
+ {
+ if (!strcmp (weights_map[i].text, weight_buffer))
+ {
+ description.weight = weights_map[i].value;
+ break;
+ }
+ }
+ }
+ else
+ strcpy (weight_buffer, "*");
+
+ description.stretch = PANGO_STRETCH_NORMAL;
+ if (pango_x_get_xlfd_field (fontname, XLFD_SET_WIDTH, set_width_buffer))
+ {
+ for (i=0; i<G_N_ELEMENTS(stretches_map); i++)
+ {
+ if (!strcmp (stretches_map[i].text, set_width_buffer))
+ {
+ description.stretch = stretches_map[i].value;
+ break;
+ }
+ }
+ }
+ else
+ strcpy (set_width_buffer, "*");
+
+ family_entry = pango_x_get_family_entry (xfontmap, description.family_name);
+
+ tmp_list = family_entry->font_entries;
+ while (tmp_list)
+ {
+ font_entry = tmp_list->data;
+
+ if (font_entry->description.style == description.style &&
+ font_entry->description.variant == description.variant &&
+ font_entry->description.weight == description.weight &&
+ font_entry->description.stretch == description.stretch)
+ return;
+
+ tmp_list = tmp_list->next;
+ }
+
+ font_entry = g_new (PangoXFontEntry, 1);
+ font_entry->description = description;
+ font_entry->description.family_name = family_entry->family_name;
+ font_entry->cached_fonts = NULL;
+ font_entry->coverage = NULL;
+
+ font_entry->xlfd = g_strconcat ("-*-",
+ family_buffer,
+ "-",
+ weight_buffer,
+ "-",
+ slant_buffer,
+ "-",
+ set_width_buffer,
+ "--*-*-*-*-*-*-*-*",
+ NULL);
+
+ family_entry->font_entries = g_slist_append (family_entry->font_entries, font_entry);
+ xfontmap->n_fonts++;
+}
+
+/* Compare the tail of a to b */
+static gboolean
+match_end (char *a, char *b)
+{
+ size_t len_a = strlen (a);
+ size_t len_b = strlen (b);
+
+ if (len_b > len_a)
+ return FALSE;
+ else
+ return (strcmp (a + len_a - len_b, b) == 0);
+}
+
+/* Given a xlfd, charset and size, find the best matching installed X font.
+ * The XLFD must be a full XLFD (14 fields)
+ */
+char *
+pango_x_make_matching_xlfd (PangoFontMap *fontmap, char *xlfd, const char *charset, int size)
+{
+ PangoXFontMap *xfontmap;
+
+ GSList *tmp_list;
+ PangoXSizeInfo *size_info;
+ char *identifier;
+ char *closest_match = NULL;
+ gint match_distance = 0;
+ gboolean match_scaleable = FALSE;
+ char *result = NULL;
+
+ char *dash_charset;
+
+ xfontmap = PANGO_X_FONT_MAP (fontmap);
+
+ dash_charset = g_strconcat ("-", charset, NULL);
+
+ if (!match_end (xlfd, "-*-*") && !match_end (xlfd, dash_charset))
+ {
+ g_free (dash_charset);
+ return NULL;
+ }
+
+ identifier = pango_x_get_identifier (xlfd);
+ size_info = g_hash_table_lookup (xfontmap->size_infos, identifier);
+ g_free (identifier);
+
+ if (!size_info)
+ {
+ g_free (dash_charset);
+ return NULL;
+ }
+
+ tmp_list = size_info->xlfds;
+ while (tmp_list)
+ {
+ char *tmp_xlfd = tmp_list->data;
+
+ if (match_end (tmp_xlfd, dash_charset))
+ {
+ int font_size = pango_x_get_size (xfontmap, tmp_xlfd);
+
+ if (size != -1)
+ {
+ int new_distance = (font_size == 0) ? 0 : abs (font_size - size);
+
+ if (!closest_match ||
+ new_distance < match_distance ||
+ (new_distance < PANGO_SCALE && match_scaleable && font_size != 0))
+ {
+ closest_match = tmp_xlfd;
+ match_scaleable = (font_size == 0);
+ match_distance = new_distance;
+ }
+ }
+ }
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (closest_match)
+ {
+ if (match_scaleable)
+ {
+ char *prefix_end, *p;
+ char *size_end;
+ int n_dashes = 0;
+ int target_size;
+ char *prefix;
+
+ /* OK, we have a match; let's modify it to fit this size and charset */
+
+ p = closest_match;
+ while (n_dashes < 6)
+ {
+ if (*p == '-')
+ n_dashes++;
+ p++;
+ }
+
+ prefix_end = p - 1;
+
+ while (n_dashes < 9)
+ {
+ if (*p == '-')
+ n_dashes++;
+ p++;
+ }
+
+ size_end = p - 1;
+
+ target_size = (int)((double)size / xfontmap->resolution + 0.5);
+ prefix = g_strndup (closest_match, prefix_end - closest_match);
+ result = g_strdup_printf ("%s--%d-*-*-*-*-*-%s", prefix, target_size, charset);
+ g_free (prefix);
+ }
+ else
+ {
+ result = g_strdup (closest_match);
+ }
+ }
+
+ g_free (dash_charset);
+
+ return result;
+}
+
+static void
+free_coverages_foreach (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ pango_coverage_unref (value);
+}
+
+PangoCoverage *
+pango_x_font_entry_get_coverage (PangoXFontEntry *entry,
+ PangoFont *font,
+ const char *lang)
+{
+ guint32 ch;
+ PangoMap *shape_map;
+ PangoCoverage *coverage;
+ PangoCoverage *result;
+ PangoCoverageLevel font_level;
+ PangoMapEntry *map_entry;
+ GHashTable *coverage_hash;
+
+ if (entry)
+ if (entry->coverage)
+ {
+ pango_coverage_ref (entry->coverage);
+ return entry->coverage;
+ }
+
+ result = pango_coverage_new ();
+
+ coverage_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ shape_map = pango_x_get_shaper_map (lang);
+
+ 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, lang);
+ 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);
+
+ if (entry)
+ {
+ entry->coverage = result;
+ pango_coverage_ref (result);
+ }
+
+ return result;
+}
+
+void
+pango_x_font_entry_remove (PangoXFontEntry *entry,
+ PangoFont *font)
+{
+ entry->cached_fonts = g_slist_remove (entry->cached_fonts, font);
+}
diff --git a/pango/pangox-private.h b/pango/pangox-private.h
new file mode 100644
index 00000000..345213d5
--- /dev/null
+++ b/pango/pangox-private.h
@@ -0,0 +1,71 @@
+/* Pango
+ * pangox-private.h:
+ *
+ * Copyright (C) 1999 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PANGOX_PRIVATE_H__
+#define __PANGOX_PRIVATE_H__
+
+#include "modules.h"
+#include "pangox.h"
+#include "pangox-private.h"
+
+typedef struct _PangoXFont PangoXFont;
+typedef struct _PangoXFontEntry PangoXFontEntry;
+typedef struct _PangoXSubfontInfo PangoXSubfontInfo;
+
+struct _PangoXFont
+{
+ PangoFont font;
+ Display *display;
+
+ char **fonts;
+ int n_fonts;
+ int size;
+
+ /* hash table mapping from charset-name to array of PangoXSubfont ids,
+ * of length n_fonts
+ */
+ GHashTable *subfonts_by_charset;
+
+ PangoXSubfontInfo **subfonts;
+
+ int n_subfonts;
+ int max_subfonts;
+
+ GSList *metrics_by_lang;
+
+ PangoXFontEntry *entry; /* Used to remove cached fonts */
+};
+
+PangoFont * pango_x_load_font_with_size (Display *display,
+ char *spec,
+ int size);
+PangoMap * pango_x_get_shaper_map (const char *lang);
+char * pango_x_make_matching_xlfd (PangoFontMap *fontmap,
+ char *xlfd,
+ const char *charset,
+ int size);
+PangoCoverage *pango_x_font_entry_get_coverage (PangoXFontEntry *entry,
+ PangoFont *font,
+ const char *lang);
+void pango_x_font_entry_remove (PangoXFontEntry *entry,
+ PangoFont *font);
+
+#endif /* __PANGOX_PRIVATE_H__ */
diff --git a/pango/pangox.c b/pango/pangox.c
index d45989bf..407aa574 100644
--- a/pango/pangox.c
+++ b/pango/pangox.c
@@ -19,53 +19,23 @@
* Boston, MA 02111-1307, USA.
*/
+#include <string.h>
+#include <math.h>
+
#include <X11/Xlib.h>
#include <fribidi/fribidi.h>
#include <unicode.h>
-#include "modules.h"
#include "pangox.h"
+#include "pangox-private.h"
+
#include "utils.h"
-#include <ctype.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
#include <config.h>
-typedef struct _PangoXFont PangoXFont;
-typedef struct _PangoXFontMap PangoXFontMap;
-typedef struct _PangoXSubfontInfo PangoXSubfontInfo;
-
-typedef struct _PangoXSizeInfo PangoXSizeInfo;
typedef struct _PangoXMetricsInfo PangoXMetricsInfo;
-typedef struct _PangoXFamilyEntry PangoXFamilyEntry;
-typedef struct _PangoXFontEntry PangoXFontEntry;
typedef struct _PangoXContextInfo PangoXContextInfo;
-struct _PangoXSizeInfo
-{
- char *identifier;
- GSList *xlfds;
-};
-
-struct _PangoXFontEntry
-{
- char *xlfd;
- PangoFontDescription description;
- PangoCoverage *coverage;
-
- GSList *cached_fonts;
-};
-
-struct _PangoXFamilyEntry
-{
- char *family_name;
- GSList *font_entries;
-};
-
struct _PangoXSubfontInfo
{
char *xlfd;
@@ -81,122 +51,12 @@ struct _PangoXMetricsInfo
PangoFontMetrics metrics;
};
-struct _PangoXFont
-{
- PangoFont font;
- Display *display;
-
- char **fonts;
- int n_fonts;
- int size;
-
- /* hash table mapping from charset-name to array of PangoXSubfont ids,
- * of length n_fonts
- */
- GHashTable *subfonts_by_charset;
-
- PangoXSubfontInfo **subfonts;
-
- int n_subfonts;
- int max_subfonts;
-
- GSList *metrics_by_lang;
-
- PangoXFontEntry *entry; /* Used to remove cached fonts */
-};
-
-struct _PangoXFontMap
-{
- PangoFontMap fontmap;
-
- Display *display;
-
- GHashTable *families;
- GHashTable *size_infos;
-
- int n_fonts;
-
- double resolution; /* (points / pixel) * PANGO_SCALE */
-};
-
struct _PangoXContextInfo
{
PangoGetGCFunc get_gc_func;
PangoFreeGCFunc free_gc_func;
};
-/* This is the largest field length we will accept. If a fontname has a field
- larger than this we will skip it. */
-#define XLFD_MAX_FIELD_LEN 64
-#define MAX_FONTS 32767
-
-/* These are the field numbers in the X Logical Font Description fontnames,
- e.g. -adobe-courier-bold-o-normal--25-180-100-100-m-150-iso8859-1 */
-typedef enum
-{
- XLFD_FOUNDRY = 0,
- XLFD_FAMILY = 1,
- XLFD_WEIGHT = 2,
- XLFD_SLANT = 3,
- XLFD_SET_WIDTH = 4,
- XLFD_ADD_STYLE = 5,
- XLFD_PIXELS = 6,
- XLFD_POINTS = 7,
- XLFD_RESOLUTION_X = 8,
- XLFD_RESOLUTION_Y = 9,
- XLFD_SPACING = 10,
- XLFD_AVERAGE_WIDTH = 11,
- XLFD_CHARSET = 12,
- XLFD_NUM_FIELDS
-} FontField;
-
-const struct {
- const gchar *text;
- PangoWeight value;
-} weights_map[] = {
- { "light", 300 },
- { "regular", 400 },
- { "book", 400 },
- { "medium", 500 },
- { "semibold", 600 },
- { "demibold", 600 },
- { "bold", 700 },
- { "extrabold", 800 },
- { "ultrabold", 800 },
- { "heavy", 900 },
- { "black", 900 }
-};
-
-const struct {
- const gchar *text;
- PangoStyle value;
-} styles_map[] = {
- { "r", PANGO_STYLE_NORMAL },
- { "i", PANGO_STYLE_ITALIC },
- { "o", PANGO_STYLE_OBLIQUE }
-};
-
-const struct {
- const gchar *text;
- PangoStretch value;
-} stretches_map[] = {
- { "normal", PANGO_STRETCH_NORMAL },
- { "semicondensed", PANGO_STRETCH_SEMI_CONDENSED },
- { "condensed", PANGO_STRETCH_CONDENSED },
-};
-
-static void pango_x_font_map_destroy (PangoFontMap *fontmap);
-static PangoFont *pango_x_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *desc);
-static void pango_x_font_map_list_fonts (PangoFontMap *fontmap,
- const gchar *family,
- PangoFontDescription ***descs,
- int *n_descs);
-static void pango_x_font_map_list_families (PangoFontMap *fontmap,
- gchar ***families,
- int *n_families);
-static void pango_x_font_map_read_aliases (PangoXFontMap *xfontmap);
-
static void pango_x_font_destroy (PangoFont *font);
static PangoFontDescription *pango_x_font_describe (PangoFont *font);
static PangoCoverage * pango_x_font_get_coverage (PangoFont *font,
@@ -224,19 +84,6 @@ static gboolean pango_x_find_glyph (PangoFont *font,
static XFontStruct * pango_x_get_font_struct (PangoFont *font,
PangoXSubfontInfo *info);
-static PangoFont *pango_x_load_font_with_size (Display *display,
- char *spec,
- int size);
-
-static gboolean pango_x_is_xlfd_font_name (const char *fontname);
-static char * pango_x_get_xlfd_field (const char *fontname,
- FontField field_num,
- char *buffer);
-static char * pango_x_get_identifier (const char *fontname);
-static gint pango_x_get_size (PangoXFontMap *fontmap,
- const char *fontname);
-static void pango_x_insert_font (PangoXFontMap *fontmap,
- const char *fontname);
static void pango_x_get_item_properties (PangoItem *item,
PangoUnderline *uline,
PangoAttrColor *fg_color,
@@ -244,8 +91,6 @@ static void pango_x_get_item_properties (PangoItem *item,
PangoAttrColor *bg_color,
gboolean *bg_set);
-static GList *fontmaps;
-
PangoFontClass pango_x_font_class = {
pango_x_font_destroy,
pango_x_font_describe,
@@ -255,13 +100,6 @@ PangoFontClass pango_x_font_class = {
pango_x_font_get_metrics
};
-PangoFontMapClass pango_x_font_map_class = {
- pango_x_font_map_destroy,
- pango_x_font_map_load_font,
- pango_x_font_map_list_fonts,
- pango_x_font_map_list_families
-};
-
static inline PangoXSubfontInfo *
pango_x_find_subfont (PangoFont *font,
PangoXSubfont subfont_index)
@@ -300,981 +138,6 @@ pango_x_get_font_struct (PangoFont *font, PangoXSubfontInfo *info)
return info->font_struct;
}
-static PangoFontMap *
-pango_x_font_map_for_display (Display *display)
-{
- PangoXFontMap *xfontmap;
- GList *tmp_list = fontmaps;
- char **xfontnames;
- int num_fonts, i;
- int screen;
-
- while (tmp_list)
- {
- xfontmap = tmp_list->data;
-
- if (xfontmap->display == display)
- {
- pango_font_map_ref ((PangoFontMap *)xfontmap);
- return (PangoFontMap *)xfontmap;
- }
- }
-
- xfontmap = g_new (PangoXFontMap, 1);
-
- xfontmap->fontmap.klass = &pango_x_font_map_class;
- xfontmap->display = display;
- xfontmap->families = g_hash_table_new (g_str_hash, g_str_equal);
- xfontmap->size_infos = g_hash_table_new (g_str_hash, g_str_equal);
- xfontmap->n_fonts = 0;
-
- pango_font_map_init ((PangoFontMap *)xfontmap);
-
- /* Get a maximum of MAX_FONTS fontnames from the X server.
- Use "-*" as the pattern rather than "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" since
- the latter may result in fonts being returned which don't actually exist.
- xlsfonts also uses "*" so I think it's OK. "-*" gets rid of aliases. */
- xfontnames = XListFonts (xfontmap->display, "-*", MAX_FONTS, &num_fonts);
- if (num_fonts == MAX_FONTS)
- g_warning("MAX_FONTS exceeded. Some fonts may be missing.");
-
- /* Insert the font families into the main table */
- for (i = 0; i < num_fonts; i++)
- {
- if (pango_x_is_xlfd_font_name (xfontnames[i]))
- pango_x_insert_font (xfontmap, xfontnames[i]);
- }
-
- XFreeFontNames (xfontnames);
-
- pango_x_font_map_read_aliases (xfontmap);
-
- fontmaps = g_list_prepend (fontmaps, xfontmap);
-
- /* This is a little screwed up, since different screens on the same display
- * might have different resolutions
- */
- screen = DefaultScreen (xfontmap->display);
- xfontmap->resolution = (PANGO_SCALE * 72.27 / 25.4) * ((double) DisplayWidthMM (xfontmap->display, screen) /
- DisplayWidth (xfontmap->display, screen));
-
- return (PangoFontMap *)xfontmap;
-}
-
-static void
-pango_x_font_map_destroy (PangoFontMap *fontmap)
-{
- fontmaps = g_list_remove (fontmaps, fontmap);
-
- g_free (fontmap);
-}
-
-static PangoXFamilyEntry *
-pango_x_get_family_entry (PangoXFontMap *xfontmap,
- const char *family_name)
-{
- PangoXFamilyEntry *family_entry = g_hash_table_lookup (xfontmap->families, family_name);
- if (!family_entry)
- {
- family_entry = g_new (PangoXFamilyEntry, 1);
- family_entry->family_name = g_strdup (family_name);
- family_entry->font_entries = NULL;
-
- g_hash_table_insert (xfontmap->families, family_entry->family_name, family_entry);
- }
-
- return family_entry;
-}
-
-static PangoFont *
-pango_x_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description)
-{
- PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;
- PangoXFamilyEntry *family_entry;
- PangoFont *result = NULL;
- GSList *tmp_list;
- gchar *name;
-
- g_return_val_if_fail (description != NULL, NULL);
- g_return_val_if_fail (description->size > 0, NULL);
-
- name = g_strdup (description->family_name);
- g_strdown (name);
-
- family_entry = g_hash_table_lookup (xfontmap->families, name);
- if (family_entry)
- {
- PangoXFontEntry *best_match = NULL;
-
- tmp_list = family_entry->font_entries;
- while (tmp_list)
- {
- PangoXFontEntry *font_entry = tmp_list->data;
-
- if (font_entry->description.style == description->style &&
- font_entry->description.variant == description->variant &&
- font_entry->description.stretch == description->stretch)
- {
- int distance = abs(font_entry->description.weight - description->weight);
- int old_distance = best_match ? abs(best_match->description.weight - description->weight) : G_MAXINT;
-
- if (distance < old_distance)
- {
- best_match = font_entry;
- }
- }
-
- tmp_list = tmp_list->next;
- }
-
- if (best_match)
- {
- GSList *tmp_list = best_match->cached_fonts;
-
- while (tmp_list)
- {
- PangoXFont *xfont = tmp_list->data;
- if (xfont->size == description->size)
- {
- result = (PangoFont *)xfont;
- pango_font_ref (result);
- break;
- }
- tmp_list = tmp_list->next;
- }
-
- if (!result)
- {
- result = pango_x_load_font_with_size (xfontmap->display, best_match->xlfd, description->size);
- ((PangoXFont *)result)->entry = best_match;
- best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, result);
- }
-
- /* HORRIBLE performance hack until some better caching scheme is arrived at
- */
- if (result)
- pango_font_ref (result);
- }
- }
-
- g_free (name);
- return result;
-}
-
-typedef struct
-{
- int n_found;
- PangoFontDescription **descs;
-} ListFontsInfo;
-
-static void
-list_fonts_foreach (gpointer key, gpointer value, gpointer user_data)
-{
- PangoXFamilyEntry *entry = value;
- ListFontsInfo *info = user_data;
-
- GSList *tmp_list = entry->font_entries;
-
- while (tmp_list)
- {
- PangoXFontEntry *font_entry = tmp_list->data;
-
- info->descs[info->n_found++] = pango_font_description_copy (&font_entry->description);
- tmp_list = tmp_list->next;
- }
-}
-
-static void
-pango_x_font_map_list_fonts (PangoFontMap *fontmap,
- const gchar *family,
- PangoFontDescription ***descs,
- int *n_descs)
-{
- PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;
- ListFontsInfo info;
-
- if (!n_descs)
- return;
-
- if (family)
- {
- PangoXFamilyEntry *entry = g_hash_table_lookup (xfontmap->families, family);
- if (entry)
- {
- *n_descs = g_slist_length (entry->font_entries);
- if (descs)
- {
- *descs = g_new (PangoFontDescription *, *n_descs);
-
- info.descs = *descs;
- info.n_found = 0;
-
- list_fonts_foreach ((gpointer)family, (gpointer)entry, &info);
- }
- }
- else
- {
- *n_descs = 0;
- if (descs)
- *descs = NULL;
- }
- }
- else
- {
- *n_descs = xfontmap->n_fonts;
- if (descs)
- {
- *descs = g_new (PangoFontDescription *, xfontmap->n_fonts);
-
- info.descs = *descs;
- info.n_found = 0;
-
- g_hash_table_foreach (xfontmap->families, list_fonts_foreach, &info);
- }
- }
-}
-
-static void
-list_families_foreach (gpointer key, gpointer value, gpointer user_data)
-{
- GSList **list = user_data;
-
- *list = g_slist_prepend (*list, key);
-}
-
-static void
-pango_x_font_map_list_families (PangoFontMap *fontmap,
- gchar ***families,
- int *n_families)
-{
- GSList *family_list = NULL;
- GSList *tmp_list;
- PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;
-
- if (!n_families)
- return;
-
- g_hash_table_foreach (xfontmap->families, list_families_foreach, &family_list);
-
- *n_families = g_slist_length (family_list);
-
- if (families)
- {
- int i = 0;
-
- *families = g_new (gchar *, *n_families);
-
- tmp_list = family_list;
- while (tmp_list)
- {
- (*families)[i] = g_strdup (tmp_list->data);
- i++;
- tmp_list = tmp_list->next;
- }
- }
-
- g_slist_free (family_list);
-}
-
-/* Similar to GNU libc's getline, but buffer is g_malloc'd */
-static size_t
-pango_getline (char **lineptr, size_t *n, FILE *stream)
-{
-#define EXPAND_CHUNK 16
-
- int n_read = 0;
- int result = -1;
-
- g_return_val_if_fail (lineptr != NULL, -1);
- g_return_val_if_fail (n != NULL, -1);
- g_return_val_if_fail (*lineptr != NULL || *n == 0, -1);
-
-#ifdef HAVE_FLOCKFILE
- flockfile (stream);
-#endif
-
- while (1)
- {
- int c;
-
-#ifdef HAVE_FLOCKFILE
- c = getc_unlocked (stream);
-#else
- c = getc (stream);
-#endif
-
- if (c == EOF)
- {
- if (n_read > 0)
- {
- result = n_read;
- (*lineptr)[n_read] = '\0';
- }
- break;
- }
-
- if (n_read + 2 >= *n)
- {
- *n += EXPAND_CHUNK;
- *lineptr = g_realloc (*lineptr, *n);
- }
-
- (*lineptr)[n_read] = c;
- n_read++;
-
- if (c == '\n' || c == '\r')
- {
- result = n_read;
- (*lineptr)[n_read] = '\0';
- break;
- }
- }
-
-#ifdef HAVE_FLOCKFILE
- funlockfile (stream);
-#endif
-
- return n_read - 1;
-}
-
-static int
-find_tok (char **start, char **tok)
-{
- char *p = *start;
-
- while (*p && (*p == ' ' || *p == '\t'))
- p++;
-
- if (*p == 0 || *p == '\n' || *p == '\r')
- return -1;
-
- if (*p == '"')
- {
- p++;
- *tok = p;
-
- while (*p && *p != '"')
- p++;
-
- if (*p != '"')
- return -1;
-
- *start = p + 1;
- return p - *tok;
- }
- else
- {
- *tok = p;
-
- while (*p && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n')
- p++;
-
- *start = p;
- return p - *tok;
- }
-}
-
-static gboolean
-get_style (char *tok, int toksize, PangoFontDescription *desc)
-{
- if (toksize == 0)
- return FALSE;
-
- switch (tok[0])
- {
- case 'n':
- case 'N':
- if (strncasecmp (tok, "normal", toksize) == 0)
- {
- desc->style = PANGO_STYLE_NORMAL;
- return TRUE;
- }
- break;
- case 'i':
- if (strncasecmp (tok, "italic", toksize) == 0)
- {
- desc->style = PANGO_STYLE_ITALIC;
- return TRUE;
- }
- break;
- case 'o':
- if (strncasecmp (tok, "oblique", toksize) == 0)
- {
- desc->style = PANGO_STYLE_OBLIQUE;
- return TRUE;
- }
- break;
- }
- g_warning ("Style must be normal, italic, or oblique");
-
- return FALSE;
-}
-
-static gboolean
-get_variant (char *tok, int toksize, PangoFontDescription *desc)
-{
- if (toksize == 0)
- return FALSE;
-
- switch (tok[0])
- {
- case 'n':
- case 'N':
- if (strncasecmp (tok, "normal", toksize) == 0)
- {
- desc->variant = PANGO_VARIANT_NORMAL;
- return TRUE;
- }
- break;
- case 's':
- case 'S':
- if (strncasecmp (tok, "small_caps", toksize) == 0)
- {
- desc->variant = PANGO_VARIANT_SMALL_CAPS;
- return TRUE;
- }
- break;
- }
-
- g_warning ("Variant must be normal, or small_caps");
- return FALSE;
-}
-
-static gboolean
-get_weight (char *tok, int toksize, PangoFontDescription *desc)
-{
- if (toksize == 0)
- return FALSE;
-
- switch (tok[0])
- {
- case 'n':
- case 'N':
- if (strncasecmp (tok, "normal", toksize) == 0)
- {
- desc->weight = PANGO_WEIGHT_NORMAL;
- return TRUE;
- }
- break;
- case 'b':
- case 'B':
- if (strncasecmp (tok, "bold", toksize) == 0)
- {
- desc->weight = PANGO_WEIGHT_BOLD;
- return TRUE;
- }
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- char *numstr, *end;
-
- numstr = g_strndup (tok, toksize);
-
- desc->weight = strtol (numstr, &end, 0);
- if (*end != '\0')
- {
- g_warning ("Cannot parse numerical weight '%s'", numstr);
- g_free (numstr);
- return FALSE;
- }
-
- g_free (numstr);
- return TRUE;
- }
- }
-
- g_warning ("Weight must be normal, bold, or an integer");
- return FALSE;
-}
-
-static gboolean
-get_stretch (char *tok, int toksize, PangoFontDescription *desc)
-{
- if (toksize == 0)
- return FALSE;
-
- switch (tok[0])
- {
- case 'c':
- case 'C':
- if (strncasecmp (tok, "condensed", toksize) == 0)
- {
- desc->stretch = PANGO_STRETCH_CONDENSED;
- return TRUE;
- }
- break;
- case 'e':
- case 'E':
- if (strncasecmp (tok, "extra_condensed", toksize) == 0)
- {
- desc->stretch = PANGO_STRETCH_EXTRA_CONDENSED;
- return TRUE;
- }
- if (strncasecmp (tok, "extra_expanded", toksize) == 0)
- {
- desc->stretch = PANGO_STRETCH_EXTRA_EXPANDED;
- return TRUE;
- }
- if (strncasecmp (tok, "expanded", toksize) == 0)
- {
- desc->stretch = PANGO_STRETCH_EXPANDED;
- return TRUE;
- }
- break;
- case 'n':
- case 'N':
- if (strncasecmp (tok, "normal", toksize) == 0)
- {
- desc->stretch = PANGO_STRETCH_NORMAL;
- return TRUE;
- }
- break;
- case 's':
- case 'S':
- if (strncasecmp (tok, "semi_condensed", toksize) == 0)
- {
- desc->stretch = PANGO_STRETCH_SEMI_CONDENSED;
- return TRUE;
- }
- if (strncasecmp (tok, "semi_expanded", toksize) == 0)
- {
- desc->stretch = PANGO_STRETCH_SEMI_EXPANDED;
- return TRUE;
- }
- break;
- case 'u':
- case 'U':
- if (strncasecmp (tok, "ultra_condensed", toksize) == 0)
- {
- desc->stretch = PANGO_STRETCH_ULTRA_CONDENSED;
- return TRUE;
- }
- if (strncasecmp (tok, "ultra_expanded", toksize) == 0)
- {
- desc->variant = PANGO_STRETCH_ULTRA_EXPANDED;
- return TRUE;
- }
- break;
- }
-
- g_warning ("Stretch must be ultra_condensed, extra_condensed, condensed, semi_condensed, normal, semi_expanded, expanded, extra_expanded, or ultra_expanded");
- return FALSE;
-}
-
-static void
-pango_x_font_map_read_alias_file (PangoXFontMap *xfontmap,
- const char *filename)
-{
- FILE *infile;
- char **xlfds;
- char *buf = NULL;
- size_t bufsize = 0;
- int lineno = 0;
- int i;
- PangoXFontEntry *font_entry = NULL;
-
- infile = fopen (filename, "r");
- if (infile)
- {
- while (pango_getline (&buf, &bufsize, infile) != EOF)
- {
- PangoXFamilyEntry *family_entry;
-
- char *tok;
- char *p = buf;
-
- int toksize;
- lineno++;
-
- while (*p && (*p == ' ' || *p == '\t'))
- p++;
-
- if (*p == 0 || *p == '#' || *p == '\n' || *p == '\r')
- continue;
-
- toksize = find_tok (&p, &tok);
- if (toksize == -1)
- goto error;
-
- font_entry = g_new (PangoXFontEntry, 1);
- font_entry->xlfd = NULL;
- font_entry->description.family_name = g_strndup (tok, toksize);
- g_strdown (font_entry->description.family_name);
-
- toksize = find_tok (&p, &tok);
- if (toksize == -1)
- goto error;
-
- if (!get_style (tok, toksize, &font_entry->description))
- goto error;
-
- toksize = find_tok (&p, &tok);
- if (toksize == -1)
- goto error;
-
- if (!get_variant (tok, toksize, &font_entry->description))
- goto error;
-
- toksize = find_tok (&p, &tok);
- if (toksize == -1)
- goto error;
-
- if (!get_weight (tok, toksize, &font_entry->description))
- goto error;
-
- toksize = find_tok (&p, &tok);
- if (toksize == -1)
- goto error;
-
- if (!get_stretch (tok, toksize, &font_entry->description))
- goto error;
-
- toksize = find_tok (&p, &tok);
- if (toksize == -1)
- goto error;
-
- font_entry->xlfd = g_strndup (tok, toksize);
-
- /* Check for complete fields */
-
- xlfds = g_strsplit (font_entry->xlfd, ",", -1);
- for (i=0; xlfds[i]; i++)
- if (!pango_x_is_xlfd_font_name (xlfds[i]))
- {
- g_warning ("XLFD '%s' must be complete (14 fields)", xlfds[i]);
- g_strfreev (xlfds);
- goto error;
- }
-
- g_strfreev (xlfds);
-
-
- /* Insert the font entry into our structures */
-
- family_entry = pango_x_get_family_entry (xfontmap, font_entry->description.family_name);
- family_entry->font_entries = g_slist_prepend (family_entry->font_entries, font_entry);
- xfontmap->n_fonts++;
-
- g_free (font_entry->description.family_name);
- font_entry->description.family_name = family_entry->family_name;
- font_entry->cached_fonts = NULL;
- font_entry->coverage = NULL;
- }
-
- if (ferror (infile))
- g_warning ("Error reading '%s': %s", filename, g_strerror(errno));
-
- goto out;
-
- error:
- if (font_entry)
- {
- if (font_entry->xlfd)
- g_free (font_entry->xlfd);
- if (font_entry->description.family_name)
- g_free (font_entry->description.family_name);
- g_free (font_entry);
- }
-
- g_warning ("Error parsing line %d of alias file '%s'", lineno, filename);
-
- out:
- g_free (buf);
- fclose (infile);
- return;
- }
-
-}
-
-static void
-pango_x_font_map_read_aliases (PangoXFontMap *xfontmap)
-{
- char *filename;
-
- pango_x_font_map_read_alias_file (xfontmap, SYSCONFDIR "/pango/pangox_aliases");
-
- filename = g_strconcat (g_get_home_dir(), "/.pangox_aliases", NULL);
- pango_x_font_map_read_alias_file (xfontmap, filename);
- g_free (filename);
-
- /* FIXME: Remove this one */
- pango_x_font_map_read_alias_file (xfontmap, "pangox_aliases");
-}
-
-
-/*
- * Returns TRUE if the fontname is a valid XLFD.
- * (It just checks if the number of dashes is 14, and that each
- * field < XLFD_MAX_FIELD_LEN characters long - that's not in the XLFD but it
- * makes it easier for me).
- */
-static gboolean
-pango_x_is_xlfd_font_name (const char *fontname)
-{
- int i = 0;
- int field_len = 0;
-
- while (*fontname)
- {
- if (*fontname++ == '-')
- {
- if (field_len > XLFD_MAX_FIELD_LEN) return FALSE;
- field_len = 0;
- i++;
- }
- else
- field_len++;
- }
-
- return (i == 14) ? TRUE : FALSE;
-}
-
-static int
-pango_x_get_size (PangoXFontMap *xfontmap, const char *fontname)
-{
- char size_buffer[XLFD_MAX_FIELD_LEN];
- int size;
-
- if (!pango_x_get_xlfd_field (fontname, XLFD_PIXELS, size_buffer))
- return -1;
-
- size = atoi (size_buffer);
- if (size != 0)
- {
- return (int)(0.5 + size * xfontmap->resolution);
- }
- else
- {
- /* We use the trick that scaled bitmaps have a non-zero RESOLUTION_X, while
- * actual scaleable fonts have a zero RESOLUTION_X */
- if (!pango_x_get_xlfd_field (fontname, XLFD_RESOLUTION_X, size_buffer))
- return -1;
-
- if (atoi (size_buffer) == 0)
- return 0;
- else
- return -1;
- }
-}
-
-static char *
-pango_x_get_identifier (const char *fontname)
-{
- const char *p = fontname;
- const char *start;
- int n_dashes = 0;
-
- while (n_dashes < 2)
- {
- if (*p == '-')
- n_dashes++;
- p++;
- }
-
- start = p;
-
- while (n_dashes < 6)
- {
- if (*p == '-')
- n_dashes++;
- p++;
- }
-
- return g_strndup (start, (p - 1 - start));
-}
-
-/*
- * This fills the buffer with the specified field from the X Logical Font
- * Description name, and returns it. If fontname is NULL or the field is
- * longer than XFLD_MAX_FIELD_LEN it returns NULL.
- * Note: For the charset field, we also return the encoding, e.g. 'iso8859-1'.
- */
-static char*
-pango_x_get_xlfd_field (const char *fontname,
- FontField field_num,
- char *buffer)
-{
- const char *t1, *t2;
- int countdown, len, num_dashes;
-
- if (!fontname)
- return NULL;
-
- /* we assume this is a valid fontname...that is, it has 14 fields */
-
- countdown = field_num;
- t1 = fontname;
- while (*t1 && (countdown >= 0))
- if (*t1++ == '-')
- countdown--;
-
- num_dashes = (field_num == XLFD_CHARSET) ? 2 : 1;
- for (t2 = t1; *t2; t2++)
- {
- if (*t2 == '-' && --num_dashes == 0)
- break;
- }
-
- if (t1 != t2)
- {
- /* Check we don't overflow the buffer */
- len = (long) t2 - (long) t1;
- if (len > XLFD_MAX_FIELD_LEN - 1)
- return NULL;
- strncpy (buffer, t1, len);
- buffer[len] = 0;
- /* Convert to lower case. */
- g_strdown (buffer);
- }
- else
- strcpy(buffer, "(nil)");
-
- return buffer;
-}
-
-/* This inserts the given fontname into the FontInfo table.
- If a FontInfo already exists with the same family and foundry, then the
- fontname is added to the FontInfos list of fontnames, else a new FontInfo
- is created and inserted in alphabetical order in the table. */
-static void
-pango_x_insert_font (PangoXFontMap *xfontmap,
- const char *fontname)
-{
- PangoFontDescription description;
- char family_buffer[XLFD_MAX_FIELD_LEN];
- char weight_buffer[XLFD_MAX_FIELD_LEN];
- char slant_buffer[XLFD_MAX_FIELD_LEN];
- char set_width_buffer[XLFD_MAX_FIELD_LEN];
- GSList *tmp_list;
- PangoXFamilyEntry *family_entry;
- PangoXFontEntry *font_entry;
- PangoXSizeInfo *size_info;
- char *identifier;
- int i;
-
- description.size = 0;
-
- /* First insert the XLFD into the list of XLFDs for the "identifier" - which
- * is the 2-4th fields of the XLFD
- */
- identifier = pango_x_get_identifier (fontname);
- size_info = g_hash_table_lookup (xfontmap->size_infos, identifier);
- if (!size_info)
- {
- size_info = g_new (PangoXSizeInfo, 1);
- size_info->identifier = identifier;
- size_info->xlfds = NULL;
-
- g_hash_table_insert (xfontmap->size_infos, identifier, size_info);
- }
- else
- g_free (identifier);
-
- size_info->xlfds = g_slist_prepend (size_info->xlfds, g_strdup (fontname));
-
- /* Convert the XLFD into a PangoFontDescription */
-
- description.family_name = pango_x_get_xlfd_field (fontname, XLFD_FAMILY, family_buffer);
- g_strdown (description.family_name);
-
- if (!description.family_name)
- return;
-
- description.style = PANGO_STYLE_NORMAL;
- if (pango_x_get_xlfd_field (fontname, XLFD_SLANT, slant_buffer))
- {
- for (i=0; i<G_N_ELEMENTS(styles_map); i++)
- {
- if (!strcmp (styles_map[i].text, slant_buffer))
- {
- description.style = styles_map[i].value;
- break;
- }
- }
- }
- else
- strcpy (slant_buffer, "*");
-
- description.variant = PANGO_VARIANT_NORMAL;
-
- description.weight = PANGO_WEIGHT_NORMAL;
- if (pango_x_get_xlfd_field (fontname, XLFD_WEIGHT, weight_buffer))
- {
- for (i=0; i<G_N_ELEMENTS(weights_map); i++)
- {
- if (!strcmp (weights_map[i].text, weight_buffer))
- {
- description.weight = weights_map[i].value;
- break;
- }
- }
- }
- else
- strcpy (weight_buffer, "*");
-
- description.stretch = PANGO_STRETCH_NORMAL;
- if (pango_x_get_xlfd_field (fontname, XLFD_SET_WIDTH, set_width_buffer))
- {
- for (i=0; i<G_N_ELEMENTS(stretches_map); i++)
- {
- if (!strcmp (stretches_map[i].text, set_width_buffer))
- {
- description.stretch = stretches_map[i].value;
- break;
- }
- }
- }
- else
- strcpy (set_width_buffer, "*");
-
- family_entry = pango_x_get_family_entry (xfontmap, description.family_name);
-
- tmp_list = family_entry->font_entries;
- while (tmp_list)
- {
- font_entry = tmp_list->data;
-
- if (font_entry->description.style == description.style &&
- font_entry->description.variant == description.variant &&
- font_entry->description.weight == description.weight &&
- font_entry->description.stretch == description.stretch)
- return;
-
- tmp_list = tmp_list->next;
- }
-
- font_entry = g_new (PangoXFontEntry, 1);
- font_entry->description = description;
- font_entry->description.family_name = family_entry->family_name;
- font_entry->cached_fonts = NULL;
- font_entry->coverage = NULL;
-
- font_entry->xlfd = g_strconcat ("-*-",
- family_buffer,
- "-",
- weight_buffer,
- "-",
- slant_buffer,
- "-",
- set_width_buffer,
- "--*-*-*-*-*-*-*-*",
- NULL);
-
- family_entry->font_entries = g_slist_append (family_entry->font_entries, font_entry);
- xfontmap->n_fonts++;
-}
-
-
/**
* pango_x_get_context:
* @display: an X display (As returned by XOpenDisplay().)
@@ -1383,7 +246,7 @@ pango_x_load_font (Display *display,
*
* Returns a new #PangoFont
*/
-static PangoFont *
+PangoFont *
pango_x_load_font_with_size (Display *display,
char *spec,
int size)
@@ -1831,114 +694,6 @@ name_for_charset (char *xlfd, char *charset)
return result;
}
-/* Given a xlfd, charset and size, find the best matching installed X font.
- * The XLFD must be a full XLFD (14 fields)
- */
-static char *
-pango_x_make_matching_xlfd (PangoXFontMap *xfontmap, char *xlfd, const char *charset, int size)
-{
- GSList *tmp_list;
- PangoXSizeInfo *size_info;
- char *identifier;
- char *closest_match = NULL;
- gint match_distance = 0;
- gboolean match_scaleable = FALSE;
- char *result = NULL;
-
- char *dash_charset;
-
- dash_charset = g_strconcat ("-", charset, NULL);
-
- if (!match_end (xlfd, "-*-*") && !match_end (xlfd, dash_charset))
- {
- g_free (dash_charset);
- return NULL;
- }
-
- identifier = pango_x_get_identifier (xlfd);
- size_info = g_hash_table_lookup (xfontmap->size_infos, identifier);
- g_free (identifier);
-
- if (!size_info)
- {
- g_free (dash_charset);
- return NULL;
- }
-
- tmp_list = size_info->xlfds;
- while (tmp_list)
- {
- char *tmp_xlfd = tmp_list->data;
-
- if (match_end (tmp_xlfd, dash_charset))
- {
- int font_size = pango_x_get_size (xfontmap, tmp_xlfd);
-
- if (size != -1)
- {
- int new_distance = (font_size == 0) ? 0 : abs (font_size - size);
-
- if (!closest_match ||
- new_distance < match_distance ||
- (new_distance < PANGO_SCALE && match_scaleable && font_size != 0))
- {
- closest_match = tmp_xlfd;
- match_scaleable = (font_size == 0);
- match_distance = new_distance;
- }
- }
- }
-
- tmp_list = tmp_list->next;
- }
-
- if (closest_match)
- {
- if (match_scaleable)
- {
- char *prefix_end, *p;
- char *size_end;
- int n_dashes = 0;
- int target_size;
- char *prefix;
-
- /* OK, we have a match; let's modify it to fit this size and charset */
-
- p = closest_match;
- while (n_dashes < 6)
- {
- if (*p == '-')
- n_dashes++;
- p++;
- }
-
- prefix_end = p - 1;
-
- while (n_dashes < 9)
- {
- if (*p == '-')
- n_dashes++;
- p++;
- }
-
- size_end = p - 1;
-
- target_size = (int)((double)size / xfontmap->resolution + 0.5);
- prefix = g_strndup (closest_match, prefix_end - closest_match);
- result = g_strdup_printf ("%s--%d-*-*-*-*-*-%s", prefix, target_size, charset);
- g_free (prefix);
- }
- else
- {
- result = g_strdup (closest_match);
- }
- }
-
- g_free (dash_charset);
-
- return result;
-}
-
static PangoXSubfont
pango_x_insert_subfont (PangoFont *font, const char *xlfd)
{
@@ -1984,14 +739,14 @@ pango_x_list_subfonts (PangoFont *font,
{
PangoXFont *xfont = (PangoXFont *)font;
PangoXSubfont **subfont_lists;
- PangoXFontMap *xfontmap;
+ PangoFontMap *fontmap;
int i, j;
int n_subfonts = 0;
g_return_val_if_fail (font != NULL, 0);
g_return_val_if_fail (n_charsets == 0 || charsets != NULL, 0);
- xfontmap = (PangoXFontMap *)pango_x_font_map_for_display (xfont->display);
+ fontmap = pango_x_font_map_for_display (xfont->display);
subfont_lists = g_new (PangoXSubfont *, n_charsets);
@@ -2024,7 +779,7 @@ pango_x_list_subfonts (PangoFont *font,
}
else
{
- xlfd = pango_x_make_matching_xlfd (xfontmap, xfont->fonts[i], charsets[j], xfont->size);
+ xlfd = pango_x_make_matching_xlfd (fontmap, xfont->fonts[i], charsets[j], xfont->size);
if (xlfd)
{
subfont = pango_x_insert_subfont (font, xlfd);
@@ -2117,7 +872,7 @@ pango_x_font_destroy (PangoFont *font)
g_slist_free (xfont->metrics_by_lang);
if (xfont->entry)
- xfont->entry->cached_fonts = g_slist_remove (xfont->entry->cached_fonts, xfont);
+ pango_x_font_entry_remove (xfont->entry, font);
g_strfreev (xfont->fonts);
g_free (font);
@@ -2130,15 +885,7 @@ pango_x_font_describe (PangoFont *font)
return NULL;
}
-static void
-free_coverages_foreach (gpointer key,
- gpointer value,
- gpointer data)
-{
- pango_coverage_unref (value);
-}
-
-static PangoMap *
+PangoMap *
pango_x_get_shaper_map (const char *lang)
{
static guint engine_type_id = 0;
@@ -2157,60 +904,9 @@ static PangoCoverage *
pango_x_font_get_coverage (PangoFont *font,
const char *lang)
{
- guint32 ch;
- PangoMap *shape_map;
- PangoCoverage *coverage;
- PangoCoverage *result;
- PangoCoverageLevel font_level;
- PangoMapEntry *entry;
- GHashTable *coverage_hash;
PangoXFont *xfont = (PangoXFont *)font;
- if (xfont->entry)
- if (xfont->entry->coverage)
- {
- pango_coverage_ref (xfont->entry->coverage);
- return xfont->entry->coverage;
- }
-
- result = pango_coverage_new ();
-
- coverage_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- shape_map = pango_x_get_shaper_map (lang);
-
- for (ch = 0; ch < 65536; ch++)
- {
- entry = _pango_map_get_entry (shape_map, ch);
- if (entry->info)
- {
- coverage = g_hash_table_lookup (coverage_hash, entry->info->id);
- if (!coverage)
- {
- PangoEngineShape *engine = (PangoEngineShape *)_pango_map_get_engine (shape_map, ch);
- coverage = engine->get_coverage (font, lang);
- g_hash_table_insert (coverage_hash, entry->info->id, coverage);
- }
-
- font_level = pango_coverage_get (coverage, ch);
- if (font_level == PANGO_COVERAGE_EXACT && !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);
-
- if (xfont->entry)
- {
- xfont->entry->coverage = result;
- pango_coverage_ref (result);
- }
-
- return result;
+ return pango_x_font_entry_get_coverage (xfont->entry, font, lang);
}
static PangoEngineShape *
@@ -2578,3 +1274,6 @@ pango_x_get_item_properties (PangoItem *item,
tmp_list = tmp_list->next;
}
}
+
+
+
diff --git a/pango/pangox.h b/pango/pangox.h
index c81eba70..2c465b61 100644
--- a/pango/pangox.h
+++ b/pango/pangox.h
@@ -82,6 +82,11 @@ gboolean pango_x_has_glyph (PangoFont *font,
PangoGlyph glyph);
PangoGlyph pango_x_get_unknown_glyph (PangoFont *font);
+
+/* API for libraries that want to use PangoX mixed with classic X fonts.
+ */
+PangoFontMap *pango_x_font_map_for_display (Display *display);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */