diff options
author | Owen Taylor <otaylor@redhat.com> | 2000-01-15 06:12:19 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2000-01-15 06:12:19 +0000 |
commit | 08be81c00f4fce735979e6a684eeade00c1ce328 (patch) | |
tree | 5fc105b5c494741d01e484fbb43fb737cb777ccd /pango | |
parent | a26b023b2859fed3e178a92e3d93c71672644e7d (diff) | |
download | pango-08be81c00f4fce735979e6a684eeade00c1ce328.tar.gz |
Eliminate PangoCFont; For X, encode charset into upper 16 bits of 32 bit
Sat Jan 15 01:06:45 2000 Owen Taylor <otaylor@redhat.com>
* libpango/pangox.c libpango/pangox.h libpango/fonts.c
libpango/glyphstring.c modules/basic/basic.c:
Eliminate PangoCFont; For X, encode charset into upper
16 bits of 32 bit glyph IDs. Revise X core <=> module
interfaces to support this change.
Remove support for X_XLFD_FONT_RANGES, which has been
disavowed by its proponents, in favor of checking metrics
to figure out if the relevant characters are there.
Rework operation of basic module to be faster and simple.
* modules/Makefile.am: temporarily comment out Tamil and
Hangul modules until I finish mucking with the
X font interfaces.
Diffstat (limited to 'pango')
-rw-r--r-- | pango/fonts.c | 60 | ||||
-rw-r--r-- | pango/glyphstring.c | 15 | ||||
-rw-r--r-- | pango/pango.h | 38 | ||||
-rw-r--r-- | pango/pangox.c | 763 | ||||
-rw-r--r-- | pango/pangox.h | 46 |
5 files changed, 349 insertions, 573 deletions
diff --git a/pango/fonts.c b/pango/fonts.c index 473d3936..ed016031 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -77,7 +77,7 @@ pango_font_unref (PangoFont *font) /** * pango_font_set_data: - * @font: a #PangoCFont + * @font: a #PangoFont * @key: a string identifying the type of user data. * @data: the data to store. If %NULL, the current * data for the key will be removed. @@ -92,16 +92,16 @@ pango_font_unref (PangoFont *font) */ void pango_font_set_data (PangoFont *font, - gchar *key, - gpointer data, - GDestroyNotify destroy_func) + gchar *key, + gpointer data, + GDestroyNotify destroy_func) { g_datalist_set_data_full (&font->data, key, data, destroy_func); } /** * pango_font_get_data: - * @font: a #PangoCFont + * @font: a #PangoFont * @key: a string identifying the type of user data. * * Look up user data tagged with a particular key. @@ -115,53 +115,3 @@ pango_font_get_data (PangoFont *font, return g_datalist_get_data (&font->data, key); } -/** - * pango_cfont_init: - * @font: a #PangoCFont - * - * Initialize a #PangoCFont structure. This should - * only be called from the "new" routine of code which - * is implementing a "subclass" of #PangoCFont - */ -void -pango_cfont_init (PangoCFont *font) -{ - g_return_if_fail (font != NULL); - - font->ref_count = 1; -} - -/** - * pango_cfont_ref: - * @font: a #PangoCFont - * - * Increase the reference count of a #GScripCFont. - */ -void -pango_cfont_ref (PangoCFont *font) -{ - g_return_if_fail (font != NULL); - - font->ref_count++; -} - -/** - * pango_cfont_unref: - * @font: a #PangoCFont - * - * Decrease the reference count of a #PangoXFont. - * if the result is zero, destroy the font component - * and free the associated memory. - */ -void -pango_cfont_unref (PangoCFont *font) -{ - g_return_if_fail (font != NULL); - g_return_if_fail (font->ref_count > 0); - - font->ref_count--; - if (font->ref_count == 0) - font->klass->destroy (font); -} - - diff --git a/pango/glyphstring.c b/pango/glyphstring.c index d965ceb8..82d7d440 100644 --- a/pango/glyphstring.c +++ b/pango/glyphstring.c @@ -83,21 +83,6 @@ pango_glyph_string_set_size (PangoGlyphString *string, gint new_len) void pango_glyph_string_free (PangoGlyphString *string) { - int i; - PangoCFont *last_cfont = NULL; - - for (i=0; i<string->num_glyphs; i++) - { - if (last_cfont && string->glyphs[i].font != last_cfont) - { - pango_cfont_unref (last_cfont); - last_cfont = string->glyphs[i].font; - } - } - - if (last_cfont) - pango_cfont_unref (last_cfont); - g_free (string->glyphs); g_free (string->geometry); g_free (string->attrs); diff --git a/pango/pango.h b/pango/pango.h index 0b375a96..efc3669e 100644 --- a/pango/pango.h +++ b/pango/pango.h @@ -46,8 +46,6 @@ typedef struct _PangoLogAttr PangoLogAttr; typedef struct _PangoFont PangoFont; typedef struct _PangoFontClass PangoFontClass; -typedef struct _PangoCFont PangoCFont; -typedef struct _PangoCFontClass PangoCFontClass; typedef struct _PangoGlyph PangoGlyph; typedef struct _PangoGlyphGeometry PangoGlyphGeometry; @@ -128,9 +126,9 @@ struct _PangoLogAttr { * of Unicode text. */ void pango_break (gchar *text, - gint length, - PangoAnalysis *analysis, - PangoLogAttr *attrs); + gint length, + PangoAnalysis *analysis, + PangoLogAttr *attrs); /* * FONT OPERATIONS @@ -159,25 +157,6 @@ void pango_font_set_data (PangoFont *font, gpointer data, GDestroyNotify destroy_func); -/* A component of a font. The contents of this are completely - * rendering system dependent - */ -struct _PangoCFont { - PangoCFontClass *klass; - - /*< private >*/ - gint ref_count; -}; - -struct _PangoCFontClass { - void (*destroy) (PangoCFont *cfont); -}; - -void pango_cfont_init (PangoCFont *font); -void pango_cfont_ref (PangoCFont *font); -void pango_cfont_unref (PangoCFont *font); - - /* * GLYPH STORAGE */ @@ -191,7 +170,6 @@ typedef guint32 PangoGlyphIndex; struct _PangoGlyph { PangoGlyphIndex glyph; - PangoCFont *font; }; /* Positioning information about a glyph @@ -236,11 +214,11 @@ void pango_glyph_string_free (PangoGlyphString *string); /* Turn a string of characters into a string of glyphs */ -void pango_shape (PangoFont *font, - gchar *text, - gint length, - PangoAnalysis *analysis, - PangoGlyphString *glyphs); +void pango_shape (PangoFont *font, + gchar *text, + gint length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs); /* [ pango_place - subsume into g_script_shape? ] */ diff --git a/pango/pangox.c b/pango/pangox.c index 21c2d24d..e49d0465 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -1,5 +1,5 @@ /* Pango - * gscriptx.c: + * gscriptx.c: Routines for handling X fonts * * Copyright (C) 1999 Red Hat Software * @@ -26,33 +26,45 @@ #include <string.h> typedef struct _PangoXFont PangoXFont; -typedef struct _XLFDInfo XLFDInfo; +typedef struct _PangoXCFont PangoXCFont; +typedef struct _PangoXCharsetInfo PangoXCharsetInfo; + +struct _PangoXCFont { + gchar *xlfd; + XFontStruct *font_struct; +}; + +struct _PangoXCharsetInfo { + PangoXCharset charset; + gchar *name; + GSList *cfonts; +}; struct _PangoXFont { PangoFont font; Display *display; - gchar **fonts; - gint n_fonts; - GHashTable *name_hash; - GHashTable *xlfd_hash; -}; -struct _XLFDInfo { - XFontStruct *font_struct; - PangoCFont *cfont; + char **fonts; + + GHashTable *charsets_by_name; + PangoXCharsetInfo **charsets; + + gint n_charsets; + gint max_charsets; }; -static void pango_x_font_destroy (PangoFont *font); -static void pango_x_cfont_destroy (PangoCFont *cfont); +static XCharStruct *pango_x_get_per_char (PangoXCFont *cfont, + guint16 glyph_index); +static PangoXCFont *pango_x_find_cfont (PangoXFont *font, + PangoXCharset charset, + guint16 index, + XCharStruct **per_char_return); +static void pango_x_font_destroy (PangoFont *font); PangoFontClass pango_x_font_class = { pango_x_font_destroy }; -PangoCFontClass pango_x_cfont_class = { - pango_x_cfont_destroy -}; - /** * pango_x_load_font: * @display: the X display @@ -65,7 +77,7 @@ PangoCFontClass pango_x_cfont_class = { */ PangoFont * pango_x_load_font (Display *display, - gchar *spec) + gchar *spec) { PangoXFont *result; @@ -80,12 +92,12 @@ pango_x_load_font (Display *display, result->font.klass = &pango_x_font_class; result->fonts = g_strsplit(spec, ",", -1); - result->n_fonts = 0; - while (result->fonts[result->n_fonts]) - result->n_fonts++; - - result->name_hash = g_hash_table_new (g_str_hash, g_str_equal); - result->xlfd_hash = g_hash_table_new (g_str_hash, g_str_equal); + + result->charsets_by_name = g_hash_table_new (g_str_hash, g_str_equal); + result->charsets = g_new (PangoXCharsetInfo *, 1); + + result->n_charsets = 0; + result->max_charsets = 1; return (PangoFont *)result; } @@ -102,43 +114,62 @@ pango_x_load_font (Display *display, * Render a PangoGlyphString onto an X drawable */ void -pango_x_render (Display *display, - Drawable d, - GC gc, - PangoGlyphString *glyphs, - gint x, - gint y) +pango_x_render (Display *display, + Drawable d, + GC gc, + PangoFont *font, + PangoGlyphString *glyphs, + gint x, + gint y) { /* Slow initial implementation. For speed, it should really * collect the characters into runs, and draw multiple * characters with each XDrawString16 call. */ - XChar2b c; - PangoXCFont *cfont; + PangoXFont *xfont = (PangoXFont *)font; Font old_fid = None; XFontStruct *fs; int i; + g_return_if_fail (display != NULL); + g_return_if_fail (glyphs != NULL); + for (i=0; i<glyphs->num_glyphs; i++) { - c.byte1 = glyphs->glyphs[i].glyph / 256; - c.byte2 = glyphs->glyphs[i].glyph % 256; - cfont = (PangoXCFont *)glyphs->glyphs[i].font; - fs = cfont->font_struct; + guint16 index = PANGO_X_GLYPH_INDEX (glyphs->glyphs[i].glyph); + guint16 charset = PANGO_X_GLYPH_CHARSET (glyphs->glyphs[i].glyph); + PangoXCFont *cfont; - if (fs->fid != old_fid) + XChar2b c; + + if (charset < 1 || charset > xfont->n_charsets) { - XSetFont (display, gc, fs->fid); - old_fid = fs->fid; + g_warning ("Glyph string contains invalid charset %d", charset); + continue; } - XDrawString16 (display, d, gc, - x + glyphs->geometry[i].x_offset / 72, - y + glyphs->geometry[i].y_offset / 72, - &c, 1); + cfont = pango_x_find_cfont (xfont, charset, index, NULL); + + if (cfont) + { + c.byte1 = index / 256; + c.byte2 = index % 256; - x += glyphs->geometry[i].width / 72; + fs = cfont->font_struct; + + if (fs->fid != old_fid) + { + XSetFont (display, gc, fs->fid); + old_fid = fs->fid; + } + + XDrawString16 (display, d, gc, + x + glyphs->geometry[i].x_offset / 72, + y + glyphs->geometry[i].y_offset / 72, + &c, 1); + x += glyphs->geometry[i].width / 72; + } } } @@ -158,55 +189,66 @@ pango_x_render (Display *display, * Compute the measurements of a single glyph in pixels. */ void -pango_x_glyph_extents (PangoGlyph *glyph, - gint *lbearing, - gint *rbearing, - gint *width, - gint *ascent, - gint *descent, - gint *logical_ascent, - gint *logical_descent) +pango_x_glyph_extents (PangoFont *font, + PangoGlyphIndex glyph, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent, + gint *logical_ascent, + gint *logical_descent) { - int index; - + PangoXFont *xfont = (PangoXFont *)font; PangoXCFont *cfont; - XFontStruct *fs; + XCharStruct *cs; - XChar2b c; - - c.byte1 = glyph->glyph / 256; - c.byte2 = glyph->glyph % 256; - cfont = (PangoXCFont *)glyph->font; - fs = cfont->font_struct; - - if ((fs->min_byte1 == 0) && (fs->max_byte1 == 0)) - index = c.byte2 - fs->min_char_or_byte2; - else + + guint16 index = PANGO_X_GLYPH_INDEX (glyph); + guint16 charset = PANGO_X_GLYPH_CHARSET (glyph); + + if (charset < 1 || charset > xfont->n_charsets) { - index = ((c.byte1 - fs->min_byte1) * - (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) + - c.byte2 - fs->min_char_or_byte2; + g_warning ("Glyph string contains invalid charset %d\n", charset); + return; } - - if (fs->per_char) - cs = &fs->per_char[index]; - else - cs = &fs->min_bounds; - if (lbearing) - *lbearing = cs->lbearing; - if (rbearing) - *rbearing = cs->rbearing; - if (width) - *width = cs->width; - if (ascent) - *ascent = cs->ascent; - if (descent) - *descent = cs->descent; - if (logical_ascent) - *logical_ascent = fs->ascent; - if (logical_descent) - *logical_descent = fs->descent; + cfont = pango_x_find_cfont (xfont, charset, index, &cs); + + if (cfont) + { + if (lbearing) + *lbearing = cs->lbearing; + if (rbearing) + *rbearing = cs->rbearing; + if (width) + *width = cs->width; + if (ascent) + *ascent = cs->ascent; + if (descent) + *descent = cs->descent; + if (logical_ascent) + *logical_ascent = cfont->font_struct->ascent; + if (logical_descent) + *logical_descent = cfont->font_struct->descent; + } + else + { + if (lbearing) + *lbearing = 0; + if (rbearing) + *rbearing = 0; + if (width) + *width = 0; + if (ascent) + *ascent = 0; + if (descent) + *descent = 0; + if (logical_ascent) + *logical_ascent = 0; + if (logical_descent) + *logical_descent = 0; + } } /** @@ -227,23 +269,18 @@ pango_x_glyph_extents (PangoGlyph *glyph, * nicer to use structures as in XmbTextExtents. */ void -pango_x_extents (PangoGlyphString *glyphs, - gint *lbearing, - gint *rbearing, - gint *width, - gint *ascent, - gint *descent, - gint *logical_ascent, - gint *logical_descent) +pango_x_extents (PangoFont *font, + PangoGlyphString *glyphs, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent, + gint *logical_ascent, + gint *logical_descent) { - int index; - - PangoXCFont *cfont; - XFontStruct *fs; - XCharStruct *cs; - PangoGlyphGeometry *geometry; - XChar2b c; - + PangoXFont *xfont = (PangoXFont *)font; + int i; int t_lbearing = 0; @@ -254,48 +291,42 @@ pango_x_extents (PangoGlyphString *glyphs, int t_logical_descent = 0; int t_width = 0; + g_return_if_fail (font != NULL); + g_return_if_fail (glyphs != NULL); + for (i=0; i<glyphs->num_glyphs; i++) { - c.byte1 = glyphs->glyphs[i].glyph / 256; - c.byte2 = glyphs->glyphs[i].glyph % 256; - cfont = (PangoXCFont *)glyphs->glyphs[i].font; - fs = cfont->font_struct; + XCharStruct *cs; - if ((fs->min_byte1 == 0) && (fs->min_byte1 == 0)) - index = c.byte2 - fs->min_char_or_byte2; - else - { - index = ((c.byte1 - fs->min_byte1) * - (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) + - c.byte2 - fs->min_char_or_byte2; - } - - if (fs->per_char) - cs = &fs->per_char[index]; - else - cs = &fs->min_bounds; - - geometry = &glyphs->geometry[i]; + guint16 index = PANGO_X_GLYPH_INDEX (glyphs->glyphs[i].glyph); + guint16 charset = PANGO_X_GLYPH_CHARSET (glyphs->glyphs[i].glyph); + + PangoGlyphGeometry *geometry = &glyphs->geometry[i]; + PangoXCFont *cfont = pango_x_find_cfont (xfont, charset, index, &cs); - if (i == 0) - { - t_lbearing = cs->lbearing - geometry->x_offset / 72; - t_rbearing = cs->rbearing + geometry->x_offset / 72; - t_ascent = cs->ascent + geometry->y_offset / 72; - t_descent = cs->descent - geometry->y_offset / 72; - t_logical_ascent = fs->ascent + geometry->y_offset / 72; - t_logical_descent = fs->descent - geometry->y_offset / 72; - } - else + if (cfont) { - t_lbearing = MAX (t_lbearing, - cs->lbearing - geometry->x_offset / 72 - t_width); - t_rbearing = MAX (t_rbearing, - t_width + cs->rbearing + geometry->x_offset / 72); - t_ascent = MAX (t_ascent, cs->ascent + geometry->y_offset / 72); - t_descent = MAX (t_descent, cs->descent - geometry->y_offset / 72); - t_logical_ascent = MAX (t_logical_ascent, fs->ascent + geometry->y_offset / 72); - t_logical_descent = MAX (t_logical_descent, fs->descent - geometry->y_offset / 72); + if (i == 0) + { + t_lbearing = cs->lbearing - geometry->x_offset / 72; + t_rbearing = cs->rbearing + geometry->x_offset / 72; + t_ascent = cs->ascent + geometry->y_offset / 72; + t_descent = cs->descent - geometry->y_offset / 72; + + t_logical_ascent = cfont->font_struct->ascent + geometry->y_offset / 72; + t_logical_descent = cfont->font_struct->descent - geometry->y_offset / 72; + } + else + { + t_lbearing = MAX (t_lbearing, + cs->lbearing - geometry->x_offset / 72 - t_width); + t_rbearing = MAX (t_rbearing, + t_width + cs->rbearing + geometry->x_offset / 72); + t_ascent = MAX (t_ascent, cs->ascent + geometry->y_offset / 72); + t_descent = MAX (t_descent, cs->descent - geometry->y_offset / 72); + t_logical_ascent = MAX (t_logical_ascent, cfont->font_struct->ascent + geometry->y_offset / 72); + t_logical_descent = MAX (t_logical_descent, cfont->font_struct->descent - geometry->y_offset / 72); + } } t_width += geometry->width / 72; @@ -385,373 +416,217 @@ name_for_charset (char *xlfd, char *charset) } /** - * pango_x_load_xlfd: - * @font: a #PangoFont - * @xlfd: the XLFD of a component font to load - * - * Create a component font from a XLFD. It is assumed that - * the xlfd matches a font matching one of the names - * of @font, but this is not currently required. + * pango_x_find_charset: + * @font: a #PangoFont + * @charset: string name of charset * - * Returns the new #PangoXCFont - */ -PangoCFont * -pango_x_load_xlfd (PangoFont *font, - gchar *xlfd) + * Look up the character set ID for a character set in the given font. + * If a character set ID has not yet been assigned, a new ID will be assigned. + * + * Return value: Character ID for character set, if there is a match in this + * font, otherwise 0. + **/ +PangoXCharset +pango_x_find_charset (PangoFont *font, + gchar *charset) { - XFontStruct *fs; PangoXFont *xfont = (PangoXFont *)font; - XLFDInfo *info; + PangoXCharsetInfo *info; + int i; - g_return_val_if_fail (font != NULL, NULL); + g_return_val_if_fail (font != NULL, 0); + g_return_val_if_fail (charset != NULL, 0); - info = g_hash_table_lookup (xfont->xlfd_hash, xlfd); - if (!info) - { - info = g_new (XLFDInfo, 1); - info->cfont = NULL; - info->font_struct = NULL; - - g_hash_table_insert (xfont->xlfd_hash, g_strdup(xlfd), info); - } + info = g_hash_table_lookup (xfont->charsets_by_name, charset); - if (!info->cfont) + if (!info) { - fs = XLoadQueryFont (xfont->display, xlfd); - if (fs) - { - PangoXCFont *cfont = g_new (PangoXCFont, 1); - cfont->display = xfont->display; - cfont->font_struct = fs; - cfont->font.klass = &pango_x_cfont_class; - - info->cfont = (PangoCFont *)cfont; - - pango_cfont_init (info->cfont); - pango_cfont_ref (info->cfont); - - if (info->font_struct) - XFreeFontInfo (NULL, info->font_struct, 1); - - info->font_struct = fs; - } - } + info = g_new (PangoXCharsetInfo, 1); - return info->cfont; -} + info->cfonts = NULL; -static gchar ** -find_cfonts (PangoFont *font, gchar *charset) -{ - PangoXFont *xfont = (PangoXFont *)font; - gchar **cfonts; - int i; - - cfonts = g_hash_table_lookup (xfont->name_hash, charset); - if (!cfonts) - { - cfonts = g_new (gchar *, xfont->n_fonts + 1); - for (i=0; i<xfont->n_fonts; i++) + for (i = 0; xfont->fonts[i]; i++) { char *xlfd = name_for_charset (xfont->fonts[i], charset); - gchar **names; - gint count; - cfonts[i] = NULL; if (xlfd) { - names = XListFonts (xfont->display, xlfd, 1, &count); + int count; + char **names = XListFonts (xfont->display, xlfd, 1, &count); if (count > 0) - cfonts[i] = g_strdup (names[0]); + { + PangoXCFont *cfont = g_new (PangoXCFont, 1); + + cfont->xlfd = g_strdup (names[0]); + cfont->font_struct = NULL; + + info->cfonts = g_slist_append (info->cfonts, cfont); + } XFreeFontNames (names); g_free (xlfd); } } - g_hash_table_insert (xfont->name_hash, g_strdup(charset), cfonts); - } - - return cfonts; -} - -/** - * pango_x_find_cfont: - * @font: A font from pango_x_load_font() - * @charset: characterset descript (last two components of XLFD) - * - * Find a component font of a #PangoFont. - * - * Returns the #PangoCFont for @charset, or NULL, if no appropriate - * font could be found. - */ -PangoCFont * -pango_x_find_cfont (PangoFont *font, - gchar *charset) -{ - PangoXFont *xfont = (PangoXFont *)font; - gchar **names; - int i; - - names = find_cfonts (font, charset); - for (i=0; i<xfont->n_fonts; i++) - if (names[i]) - return pango_x_load_xlfd (font, names[i]); - - return NULL; -} - -void -font_struct_get_ranges (Display *display, - XFontStruct *fs, - gint **ranges, - gint *n_ranges) -{ - gint i, j; - static Atom bounds_atom = None; - gint *range_buf = NULL; - size_t range_buf_size = 8; - - if (bounds_atom == None) - bounds_atom = XInternAtom (display, "_XFREE86_GLYPH_RANGES", False); - - j = 0; - for (i=0; i<fs->n_properties; i++) - { - if (fs->properties[i].name == bounds_atom) + if (info->cfonts) { - char *val = XGetAtomName (display, fs->properties[i].card32); - char *p; - guint start, end; - - p = val; - while (*p) - { - int count; - - while (*p && isspace (*p)) - p++; + info->name = g_strdup (charset); + g_hash_table_insert (xfont->charsets_by_name, info->name, info); - count = sscanf (p, "%u_%u", &start, &end); - - if (count > 0) - { - if (count == 1) - end = start; - - if (!range_buf || (2*j+1) >= range_buf_size) - { - size_t new_size = range_buf_size * 2; - if (new_size < range_buf_size) /* Paranoia */ - { - XFree (val); - *ranges = NULL; - *n_ranges = 0; - - return; - } - range_buf_size = new_size; - range_buf = g_realloc (range_buf, sizeof(gint) * range_buf_size); - } - - range_buf[2*j] = start; - range_buf[2*j + 1] = end; - j++; - } - else - { - goto error; - } + xfont->n_charsets++; - while (*p && !isspace (*p)) - p++; + if (xfont->n_charsets > xfont->max_charsets) + { + xfont->max_charsets *= 2; + xfont->charsets = g_renew (PangoXCharsetInfo *, xfont->charsets, xfont->max_charsets); } - - error: - XFree (val); + + info->charset = xfont->n_charsets; + xfont->charsets[xfont->n_charsets - 1] = info; + } + else + { + g_free (info); + info = NULL; } - } - if (j > 0) - { - *n_ranges = j; - *ranges = g_malloc (sizeof(gint) * 2*j); - memcpy (*ranges, range_buf, sizeof(gint) * 2*j); - } + if (info) + return info->charset; else - { - *n_ranges = 1; - *ranges = g_malloc (sizeof(gint) * 2); - - (*ranges)[0] = fs->min_byte1 * 256 + fs->min_char_or_byte2; - (*ranges)[1] = fs->max_byte1 * 256 + fs->max_char_or_byte2; - } - - g_free (range_buf); + return 0; } -/** - * pango_x_xlfd_get_ranges: - * @font: a #PangoFont. - * @xlfd: a XLFD of a component font. - * @ranges: location to store returned ranges. - * @n_ranges: location to store the number of ranges. - * - * Find the range of valid characters for a particular - * XLFD representing a component of the given font. - * - * Returns %TRUE if the XLFD matches a font, FALSE otherwise. - * in the latter case, @ranges and @n_ranges are unchanged. - */ gboolean -pango_x_xlfd_get_ranges (PangoFont *font, - gchar *xlfd, - gint **ranges, - gint *n_ranges) +pango_x_has_glyph (PangoFont *font, + PangoGlyphIndex glyph) { PangoXFont *xfont = (PangoXFont *)font; - gchar **names; - gint count; - XLFDInfo *info; - - info = g_hash_table_lookup (xfont->xlfd_hash, xlfd); - if (!info) - { - info = g_new (XLFDInfo, 1); - info->cfont = NULL; - info->font_struct = NULL; - g_hash_table_insert (xfont->xlfd_hash, g_strdup(xlfd), info); - } - - if (!info->font_struct) - { - names = XListFontsWithInfo (xfont->display, xlfd, 1, &count, &info->font_struct); - - if (count == 0) - info->font_struct = NULL; - - XFreeFontNames (names); - } + + guint16 index, charset; + + g_return_val_if_fail (font != NULL, FALSE); + + index = PANGO_X_GLYPH_INDEX (glyph); + charset = PANGO_X_GLYPH_CHARSET (glyph); - if (info->font_struct) + if (charset < 1 || charset > xfont->n_charsets) { - font_struct_get_ranges (xfont->display, info->font_struct, ranges, n_ranges); - return TRUE; + g_warning ("Glyph string contains invalid charset %d", charset); + return FALSE; } - else - return FALSE; + + return (pango_x_find_cfont (xfont, charset, index, NULL) != NULL); } -/** - * pango_x_xlfd_list_cfonts: - * @font: a #PangoFont. - * @charsets: the list of character sets to match against. - * @n_charsets: the number of elements in @charsets. - * @xlfds: location to store a pointer to an array of returned XLFDs. - * @n_xlfds: location to store the number of XLFDs. - * - * List all possible XLFDs that can match a particular set - * of character sets for the given #PangoFont. The - * returned values are sorted at highest priority by - * the order of the names in fontlist used to create - * the #PangoFont, and then sorted by the ordering - * of the character sets in @charsets. - * - */ -void -pango_x_list_cfonts (PangoFont *font, - gchar **charsets, - gint n_charsets, - gchar ***xlfds, - gint *n_xlfds) +static void +pango_x_font_destroy (PangoFont *font) { PangoXFont *xfont = (PangoXFont *)font; + int i; - int i, j; + g_hash_table_destroy (xfont->charsets_by_name); - GSList *result = NULL; - GSList *tmp_list; + for (i=0; i<xfont->n_charsets; i++) + { + GSList *cfonts = xfont->charsets[i]->cfonts; - gchar ***names = g_new (gchar **, n_charsets); + while (cfonts) + { + PangoXCFont *cfont = cfonts->data; - *n_xlfds = 0; - for (j=0; j<n_charsets; j++) - names[j] = find_cfonts (font, charsets[j]); + g_free (cfont->xlfd); + if (cfont->font_struct) + XFreeFont (xfont->display, cfont->font_struct); - for (i=0; i < xfont->n_fonts; i++) - for (j=0; j < n_charsets; j++) - if (names[j][i] != 0) - { - (*n_xlfds)++; - result = g_slist_prepend (result, g_strdup (names[j][i])); + g_free (cfont); + + cfonts = cfonts->next; } - result = g_slist_reverse (result); - *xlfds = g_new (gchar *, *n_xlfds); + g_slist_free (xfont->charsets[i]->cfonts); - tmp_list = result; - for (i=0; i< *n_xlfds; i++) - { - (*xlfds)[i] = tmp_list->data; - tmp_list = tmp_list->next; + g_free (xfont->charsets[i]->name); + g_free (xfont->charsets[i]); } - - g_slist_free (result); - g_free (names); -} -void -name_hash_foreach (gpointer key, gpointer value, gpointer data) -{ - gchar *charset = key; - gchar **names = value; - PangoXFont *xfont = data; - int i; + g_free (xfont->charsets); - for (i=0; i<xfont->n_fonts; i++) - g_free (names[i]); - g_free (names); - g_free (charset); + g_strfreev (xfont->fonts); + g_free (font); } -void -xlfd_hash_foreach (gpointer key, gpointer value, gpointer data) -{ - gchar *xlfd = key; - XLFDInfo *info = value; +/* Utility functions */ - if (info->cfont) - pango_cfont_unref (info->cfont); - else if (info->font_struct) - XFreeFontInfo (NULL, info->font_struct, 1); +static XCharStruct * +pango_x_get_per_char (PangoXCFont *cfont, guint16 glyph_index) +{ + guint8 byte1; + guint8 byte2; + + XFontStruct *fs = cfont->font_struct; + int index; - g_free (info); + byte1 = glyph_index / 256; + byte2 = glyph_index % 256; - g_free (xlfd); + if ((fs->min_byte1 == 0) && (fs->min_byte1 == 0)) + { + if (byte2 < fs->min_char_or_byte2 || byte2 > fs->max_char_or_byte2) + return NULL; + + index = byte2 - fs->min_char_or_byte2; + } + else + { + if (byte1 < fs->min_byte1 || byte1 > fs->max_byte1 || + byte2 < fs->min_char_or_byte2 || byte2 > fs->max_char_or_byte2) + return NULL; + + index = ((byte1 - fs->min_byte1) * + (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) + + byte2 - fs->min_char_or_byte2; + } + + if (fs->per_char) + return &fs->per_char[index]; + else + return &fs->min_bounds; } -static void -pango_x_font_destroy (PangoFont *font) +static PangoXCFont * +pango_x_find_cfont (PangoXFont *font, PangoXCharset charset, guint16 index, XCharStruct **per_char_return) { - PangoXFont *xfont = (PangoXFont *)font; - - g_hash_table_foreach (xfont->name_hash, name_hash_foreach, xfont); - g_hash_table_destroy (xfont->name_hash); + GSList *cfonts = font->charsets[charset - 1]->cfonts; + + while (cfonts) + { + XCharStruct *per_char; + PangoXCFont *cfont = cfonts->data; + + if (!cfont->font_struct) + { + cfont->font_struct = XLoadQueryFont (font->display, cfont->xlfd); + if (!cfont->font_struct) + g_error ("Error loading font '%s'\n", cfont->xlfd); + } - g_hash_table_foreach (xfont->xlfd_hash, xlfd_hash_foreach, xfont); - g_hash_table_destroy (xfont->xlfd_hash); + per_char = pango_x_get_per_char (cfont, index); - g_strfreev (xfont->fonts); - g_free (font); -} - -static void -pango_x_cfont_destroy (PangoCFont *font) -{ - PangoXCFont *xcfont = (PangoXCFont *)font; + if (per_char && per_char->width != 0) + { + if (per_char_return) + *per_char_return = per_char; + + return cfont; + } + + cfonts = cfonts->next; + } - XFreeFont (xcfont->display, xcfont->font_struct); + if (per_char_return) + *per_char_return = NULL; - g_free (font); + return NULL; } + diff --git a/pango/pangox.h b/pango/pangox.h index 731ced79..c3a7d7f2 100644 --- a/pango/pangox.h +++ b/pango/pangox.h @@ -33,17 +33,6 @@ extern "C" { #define PANGO_RENDER_TYPE_X "PangoRenderX" -typedef struct _PangoXCFont PangoXCFont; - -struct _PangoXCFont { - /*< private >*/ - PangoCFont font; - - /*< public >*/ - Display *display; - XFontStruct *font_struct; -}; - /* Calls for applications */ PangoFont *pango_x_load_font (Display *display, @@ -51,10 +40,12 @@ PangoFont *pango_x_load_font (Display *display, void pango_x_render (Display *display, Drawable d, GC gc, + PangoFont *font, PangoGlyphString *glyphs, gint x, gint y); -void pango_x_extents (PangoGlyphString *glyphs, +void pango_x_extents (PangoFont *font, + PangoGlyphString *glyphs, gint *lbearing, gint *rbearing, gint *width, @@ -62,7 +53,8 @@ void pango_x_extents (PangoGlyphString *glyphs, gint *descent, gint *logical_ascent, gint *logical_descent); -void pango_x_glyph_extents (PangoGlyph *glyph, +void pango_x_glyph_extents (PangoFont *font, + PangoGlyphIndex glyph, gint *lbearing, gint *rbearing, gint *width, @@ -71,23 +63,19 @@ void pango_x_glyph_extents (PangoGlyph *glyph, gint *logical_ascent, gint *logical_descent); - -/* Calls for rendering modules +/* API for rendering modules */ -PangoCFont *pango_x_find_cfont (PangoFont *font, - gchar *charset); -void pango_x_list_cfonts (PangoFont *font, - gchar **charsets, - gint n_charsets, - gchar ***xlfds, - gint *n_xlfds); -gboolean pango_x_xlfd_get_ranges (PangoFont *font, - gchar *xlfd, - gint **ranges, - gint *n_ranges); -PangoCFont *pango_x_load_xlfd (PangoFont *font, - gchar *xlfd); - +typedef guint16 PangoXCharset; + +#define PANGO_X_MAKE_GLYPH(charset,index) (charset<<16 | index) +#define PANGO_X_GLYPH_CHARSET(glyph) (glyph>>16) +#define PANGO_X_GLYPH_INDEX(glyph) (glyph & 0xffff) + +PangoXCharset pango_x_find_charset (PangoFont *font, + gchar *charset); +gboolean pango_x_has_glyph (PangoFont *font, + PangoGlyphIndex glyph); + #ifdef __cplusplus } #endif /* __cplusplus */ |