summaryrefslogtreecommitdiff
path: root/pango/pangox.c
diff options
context:
space:
mode:
Diffstat (limited to 'pango/pangox.c')
-rw-r--r--pango/pangox.c1331
1 files changed, 15 insertions, 1316 deletions
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;
}
}
+
+
+