summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-01-15 06:12:19 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-01-15 06:12:19 +0000
commit08be81c00f4fce735979e6a684eeade00c1ce328 (patch)
tree5fc105b5c494741d01e484fbb43fb737cb777ccd /modules
parenta26b023b2859fed3e178a92e3d93c71672644e7d (diff)
downloadpango-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 'modules')
-rw-r--r--modules/Makefile.am2
-rw-r--r--modules/basic/basic-x.c218
-rw-r--r--modules/basic/basic.c218
3 files changed, 123 insertions, 315 deletions
diff --git a/modules/Makefile.am b/modules/Makefile.am
index f51d2bd6..33fc1857 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -1,3 +1,3 @@
## Process this file with automake to create Makefile.in.
-SUBDIRS=basic hangul tamil \ No newline at end of file
+SUBDIRS=basic # hangul tamil \ No newline at end of file
diff --git a/modules/basic/basic-x.c b/modules/basic/basic-x.c
index dbb71164..f1ac5649 100644
--- a/modules/basic/basic-x.c
+++ b/modules/basic/basic-x.c
@@ -36,8 +36,8 @@ typedef struct _CharCache CharCache;
typedef struct _MaskTable MaskTable;
typedef PangoGlyphIndex (*ConvFunc) (CharCache *cache,
- gchar *id,
- gchar *input);
+ gchar *id,
+ gchar *input);
struct _Charset
{
@@ -56,12 +56,10 @@ struct _CharRange
struct _MaskTable
{
guint mask;
- int n_els;
- char **xlfds;
- gint **ranges;
- gint *n_ranges;
+ PangoXCharset *charset_ids;
Charset **charsets;
- PangoCFont **cfonts;
+
+ int n_charsets;
};
struct _CharCache
@@ -71,14 +69,14 @@ struct _CharCache
};
static PangoGlyphIndex conv_8bit (CharCache *cache,
- gchar *id,
- char *input);
+ gchar *id,
+ char *input);
static PangoGlyphIndex conv_euc (CharCache *cache,
- gchar *id,
- char *input);
+ gchar *id,
+ char *input);
static PangoGlyphIndex conv_ucs4 (CharCache *cache,
- gchar *id,
- char *input);
+ gchar *id,
+ char *input);
#include "tables-big.i"
@@ -186,7 +184,6 @@ static void
char_cache_free (CharCache *cache)
{
GSList *tmp_list;
- int i;
tmp_list = cache->mask_tables;
while (tmp_list)
@@ -194,20 +191,9 @@ char_cache_free (CharCache *cache)
MaskTable *mask_table = tmp_list->data;
tmp_list = tmp_list->next;
- for (i=0; i<mask_table->n_els; i++)
- {
- g_free (mask_table->xlfds[i]);
- g_free (mask_table->ranges[i]);
- if (mask_table->cfonts[i])
- pango_cfont_unref (mask_table->cfonts[i]);
- }
-
- g_free (mask_table->xlfds);
- g_free (mask_table->ranges);
- g_free (mask_table->n_ranges);
+ g_free (mask_table->charset_ids);
g_free (mask_table->charsets);
- g_free (mask_table->cfonts);
-
+
g_free (mask_table);
}
@@ -219,60 +205,13 @@ char_cache_free (CharCache *cache)
g_free (cache);
}
-static gboolean
-check_character (gint *ranges, gint n_ranges, GUChar4 wc)
-{
- int start, end, middle;
-
- start = 0;
- end = n_ranges - 1;
-
- if (ranges[2*start] > wc || ranges[2*end + 1] < wc)
- return FALSE;
-
- while (1)
- {
- middle = (start + end) / 2;
- if (middle == start)
- {
- if (ranges[2 * middle] > wc || ranges[2 * middle + 1] < wc)
- return FALSE;
- else
- return TRUE;
- }
- else
- {
- if (ranges[2*middle] <= wc)
- start = middle;
- else if (ranges[2*middle + 1] >= wc)
- end = middle;
- else
- return FALSE;
- }
- }
-}
-
-/* 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);
-}
-
-static gboolean
-find_char (CharCache *cache, PangoFont *font, GUChar4 wc, char *input,
- PangoCFont **cfont, PangoGlyphIndex *glyph)
+PangoGlyphIndex
+find_char (CharCache *cache, PangoFont *font, GUChar4 wc, char *input)
{
guint mask = find_char_mask (wc);
GSList *tmp_list;
MaskTable *mask_table;
- int i, j;
+ int i;
tmp_list = cache->mask_tables;
while (tmp_list)
@@ -287,87 +226,61 @@ find_char (CharCache *cache, PangoFont *font, GUChar4 wc, char *input,
if (!tmp_list)
{
- gchar **charset_list;
- gint n_charsets = 0;
-
+ PangoXCharset tmp_charset_ids[MEMBERS(charsets)];
+ Charset *tmp_charsets[MEMBERS(charsets)];
+
mask_table = g_new (MaskTable, 1);
+ mask_table->mask = mask;
+ mask_table->n_charsets = 0;
+
/* Find the character sets that are included in this mask
*/
- charset_list = g_new (gchar *, MEMBERS(charsets));
for (i=0; i<MEMBERS(charsets); i++)
{
if (mask & (1 << i))
- charset_list[n_charsets++] = charsets[i].x_charset;
- }
-
- /* Find the possible xlfds for the charset list
- */
- mask_table->mask = mask;
- pango_x_list_cfonts (font, charset_list, n_charsets,
- &mask_table->xlfds,
- &mask_table->n_els);
-
- g_free (charset_list);
-
- mask_table->cfonts = g_new0 (PangoCFont *, mask_table->n_els);
-
- mask_table->ranges = g_new (gint *, mask_table->n_els);
- mask_table->n_ranges = g_new (gint, mask_table->n_els);
- mask_table->charsets = g_new (Charset *, mask_table->n_els);
-
- for (i=0; i < mask_table->n_els; i++)
- {
- pango_x_xlfd_get_ranges (font,
- mask_table->xlfds[i],
- &mask_table->ranges[i],
- &mask_table->n_ranges[i]);
-
- mask_table->charsets[i] = NULL;
- for (j=0; j < MEMBERS(charsets); j++)
- if (match_end (mask_table->xlfds[i], charsets[j].x_charset))
- {
- mask_table->charsets[i] = &charsets[j];
- break;
- }
+ {
+ PangoXCharset charset_id = pango_x_find_charset (font, charsets[i].x_charset);
+ if (charset_id)
+ {
+ tmp_charset_ids[mask_table->n_charsets] = charset_id;
+ tmp_charsets[mask_table->n_charsets] = &charsets[i];
+ mask_table->n_charsets++;
+ }
+ }
}
+
+ mask_table->charset_ids = g_new (PangoXCharset, mask_table->n_charsets);
+ mask_table->charsets = g_new (Charset *, mask_table->n_charsets);
+
+ memcpy (mask_table->charset_ids, tmp_charset_ids, sizeof(PangoXCharset) * mask_table->n_charsets);
+ memcpy (mask_table->charsets, tmp_charsets, sizeof(Charset *) * mask_table->n_charsets);
cache->mask_tables = g_slist_prepend (cache->mask_tables, mask_table);
}
- for (i=0; i < mask_table->n_els; i++)
+ for (i=0; i < mask_table->n_charsets; i++)
{
- if (mask_table->charsets[i])
- {
- PangoGlyphIndex index;
+ PangoGlyphIndex index;
+ PangoGlyphIndex glyph;
- index = (*mask_table->charsets[i]->conv_func) (cache, mask_table->charsets[i]->id, input);
-
- if (check_character (mask_table->ranges[i], mask_table->n_ranges[i], index))
- {
- if (!mask_table->cfonts[i])
- mask_table->cfonts[i] = pango_x_load_xlfd (font, mask_table->xlfds[i]);
-
- *cfont = mask_table->cfonts[i];
- pango_cfont_ref (*cfont);
+ index = (*mask_table->charsets[i]->conv_func) (cache, mask_table->charsets[i]->id, input);
- *glyph = index;
+ glyph = PANGO_X_MAKE_GLYPH (mask_table->charset_ids[i], index);
- return TRUE;
- }
- }
+ if (pango_x_has_glyph (font, glyph))
+ return glyph;
}
- return FALSE;
+ return 0;
}
static void
-set_glyph (PangoGlyphString *glyphs, gint i, PangoCFont *cfont, PangoGlyphIndex glyph)
+set_glyph (PangoFont *font, PangoGlyphString *glyphs, gint i, PangoGlyphIndex glyph)
{
gint width;
- glyphs->glyphs[i].font = cfont;
glyphs->glyphs[i].glyph = glyph;
glyphs->geometry[i].x_offset = 0;
@@ -375,8 +288,8 @@ set_glyph (PangoGlyphString *glyphs, gint i, PangoCFont *cfont, PangoGlyphIndex
glyphs->log_clusters[i] = i;
- pango_x_glyph_extents (&glyphs->glyphs[i],
- NULL, NULL, &width, NULL, NULL, NULL, NULL);
+ pango_x_glyph_extents (font, glyphs->glyphs[i].glyph,
+ NULL, NULL, &width, NULL, NULL, NULL, NULL);
glyphs->geometry[i].width = width * 72;
}
@@ -488,17 +401,17 @@ swap_range (PangoGlyphString *glyphs, int start, int end)
}
static void
-basic_engine_shape (PangoFont *font,
- gchar *text,
- gint length,
- PangoAnalysis *analysis,
- PangoGlyphString *glyphs)
+basic_engine_shape (PangoFont *font,
+ gchar *text,
+ gint length,
+ PangoAnalysis *analysis,
+ PangoGlyphString *glyphs)
{
int n_chars;
int i;
char *p, *next;
- PangoCFont *fallback_font = NULL;
+ PangoXCharset fallback_charset = 0;
CharCache *cache;
g_return_if_fail (font != NULL);
@@ -511,7 +424,7 @@ basic_engine_shape (PangoFont *font,
{
cache = char_cache_new ();
pango_font_set_data (font, "basic-char-cache",
- cache, (GDestroyNotify)char_cache_free);
+ cache, (GDestroyNotify)char_cache_free);
}
n_chars = unicode_strlen (text, length);
@@ -522,7 +435,6 @@ basic_engine_shape (PangoFont *font,
{
GUChar4 wc;
FriBidiChar mirrored_ch;
- PangoCFont *cfont = NULL;
PangoGlyphIndex index;
_pango_utf8_iterate (p, &next, &wc);
@@ -531,12 +443,10 @@ basic_engine_shape (PangoFont *font,
if (fribidi_get_mirror_char (wc, &mirrored_ch))
wc = mirrored_ch;
- if (find_char (cache, font, wc, p, &cfont, &index))
+ index = find_char (cache, font, wc, p);
+ if (index)
{
- set_glyph (glyphs, i, cfont, index);
-
- if (i != 0 && glyphs->glyphs[i-1].font == cfont)
- pango_cfont_unref (cfont);
+ set_glyph (font, glyphs, i, index);
if (unicode_type (wc) == UNICODE_NON_SPACING_MARK)
{
@@ -551,13 +461,10 @@ basic_engine_shape (PangoFont *font,
}
else
{
- if (!fallback_font)
- fallback_font = pango_x_find_cfont (font, "iso8859-1");
+ if (!fallback_charset)
+ fallback_charset = pango_x_find_charset (font, "iso8859-1");
- if (i == 0 || glyphs->glyphs[i-1].font != fallback_font)
- pango_cfont_ref (fallback_font);
-
- set_glyph (glyphs, i, fallback_font, ' ');
+ set_glyph (font, glyphs, i, PANGO_X_MAKE_GLYPH (fallback_charset, ' '));
}
p = next;
@@ -584,9 +491,6 @@ basic_engine_shape (PangoFont *font,
start = end;
}
}
-
- if (fallback_font)
- pango_cfont_unref (fallback_font);
}
static PangoEngine *
diff --git a/modules/basic/basic.c b/modules/basic/basic.c
index dbb71164..f1ac5649 100644
--- a/modules/basic/basic.c
+++ b/modules/basic/basic.c
@@ -36,8 +36,8 @@ typedef struct _CharCache CharCache;
typedef struct _MaskTable MaskTable;
typedef PangoGlyphIndex (*ConvFunc) (CharCache *cache,
- gchar *id,
- gchar *input);
+ gchar *id,
+ gchar *input);
struct _Charset
{
@@ -56,12 +56,10 @@ struct _CharRange
struct _MaskTable
{
guint mask;
- int n_els;
- char **xlfds;
- gint **ranges;
- gint *n_ranges;
+ PangoXCharset *charset_ids;
Charset **charsets;
- PangoCFont **cfonts;
+
+ int n_charsets;
};
struct _CharCache
@@ -71,14 +69,14 @@ struct _CharCache
};
static PangoGlyphIndex conv_8bit (CharCache *cache,
- gchar *id,
- char *input);
+ gchar *id,
+ char *input);
static PangoGlyphIndex conv_euc (CharCache *cache,
- gchar *id,
- char *input);
+ gchar *id,
+ char *input);
static PangoGlyphIndex conv_ucs4 (CharCache *cache,
- gchar *id,
- char *input);
+ gchar *id,
+ char *input);
#include "tables-big.i"
@@ -186,7 +184,6 @@ static void
char_cache_free (CharCache *cache)
{
GSList *tmp_list;
- int i;
tmp_list = cache->mask_tables;
while (tmp_list)
@@ -194,20 +191,9 @@ char_cache_free (CharCache *cache)
MaskTable *mask_table = tmp_list->data;
tmp_list = tmp_list->next;
- for (i=0; i<mask_table->n_els; i++)
- {
- g_free (mask_table->xlfds[i]);
- g_free (mask_table->ranges[i]);
- if (mask_table->cfonts[i])
- pango_cfont_unref (mask_table->cfonts[i]);
- }
-
- g_free (mask_table->xlfds);
- g_free (mask_table->ranges);
- g_free (mask_table->n_ranges);
+ g_free (mask_table->charset_ids);
g_free (mask_table->charsets);
- g_free (mask_table->cfonts);
-
+
g_free (mask_table);
}
@@ -219,60 +205,13 @@ char_cache_free (CharCache *cache)
g_free (cache);
}
-static gboolean
-check_character (gint *ranges, gint n_ranges, GUChar4 wc)
-{
- int start, end, middle;
-
- start = 0;
- end = n_ranges - 1;
-
- if (ranges[2*start] > wc || ranges[2*end + 1] < wc)
- return FALSE;
-
- while (1)
- {
- middle = (start + end) / 2;
- if (middle == start)
- {
- if (ranges[2 * middle] > wc || ranges[2 * middle + 1] < wc)
- return FALSE;
- else
- return TRUE;
- }
- else
- {
- if (ranges[2*middle] <= wc)
- start = middle;
- else if (ranges[2*middle + 1] >= wc)
- end = middle;
- else
- return FALSE;
- }
- }
-}
-
-/* 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);
-}
-
-static gboolean
-find_char (CharCache *cache, PangoFont *font, GUChar4 wc, char *input,
- PangoCFont **cfont, PangoGlyphIndex *glyph)
+PangoGlyphIndex
+find_char (CharCache *cache, PangoFont *font, GUChar4 wc, char *input)
{
guint mask = find_char_mask (wc);
GSList *tmp_list;
MaskTable *mask_table;
- int i, j;
+ int i;
tmp_list = cache->mask_tables;
while (tmp_list)
@@ -287,87 +226,61 @@ find_char (CharCache *cache, PangoFont *font, GUChar4 wc, char *input,
if (!tmp_list)
{
- gchar **charset_list;
- gint n_charsets = 0;
-
+ PangoXCharset tmp_charset_ids[MEMBERS(charsets)];
+ Charset *tmp_charsets[MEMBERS(charsets)];
+
mask_table = g_new (MaskTable, 1);
+ mask_table->mask = mask;
+ mask_table->n_charsets = 0;
+
/* Find the character sets that are included in this mask
*/
- charset_list = g_new (gchar *, MEMBERS(charsets));
for (i=0; i<MEMBERS(charsets); i++)
{
if (mask & (1 << i))
- charset_list[n_charsets++] = charsets[i].x_charset;
- }
-
- /* Find the possible xlfds for the charset list
- */
- mask_table->mask = mask;
- pango_x_list_cfonts (font, charset_list, n_charsets,
- &mask_table->xlfds,
- &mask_table->n_els);
-
- g_free (charset_list);
-
- mask_table->cfonts = g_new0 (PangoCFont *, mask_table->n_els);
-
- mask_table->ranges = g_new (gint *, mask_table->n_els);
- mask_table->n_ranges = g_new (gint, mask_table->n_els);
- mask_table->charsets = g_new (Charset *, mask_table->n_els);
-
- for (i=0; i < mask_table->n_els; i++)
- {
- pango_x_xlfd_get_ranges (font,
- mask_table->xlfds[i],
- &mask_table->ranges[i],
- &mask_table->n_ranges[i]);
-
- mask_table->charsets[i] = NULL;
- for (j=0; j < MEMBERS(charsets); j++)
- if (match_end (mask_table->xlfds[i], charsets[j].x_charset))
- {
- mask_table->charsets[i] = &charsets[j];
- break;
- }
+ {
+ PangoXCharset charset_id = pango_x_find_charset (font, charsets[i].x_charset);
+ if (charset_id)
+ {
+ tmp_charset_ids[mask_table->n_charsets] = charset_id;
+ tmp_charsets[mask_table->n_charsets] = &charsets[i];
+ mask_table->n_charsets++;
+ }
+ }
}
+
+ mask_table->charset_ids = g_new (PangoXCharset, mask_table->n_charsets);
+ mask_table->charsets = g_new (Charset *, mask_table->n_charsets);
+
+ memcpy (mask_table->charset_ids, tmp_charset_ids, sizeof(PangoXCharset) * mask_table->n_charsets);
+ memcpy (mask_table->charsets, tmp_charsets, sizeof(Charset *) * mask_table->n_charsets);
cache->mask_tables = g_slist_prepend (cache->mask_tables, mask_table);
}
- for (i=0; i < mask_table->n_els; i++)
+ for (i=0; i < mask_table->n_charsets; i++)
{
- if (mask_table->charsets[i])
- {
- PangoGlyphIndex index;
+ PangoGlyphIndex index;
+ PangoGlyphIndex glyph;
- index = (*mask_table->charsets[i]->conv_func) (cache, mask_table->charsets[i]->id, input);
-
- if (check_character (mask_table->ranges[i], mask_table->n_ranges[i], index))
- {
- if (!mask_table->cfonts[i])
- mask_table->cfonts[i] = pango_x_load_xlfd (font, mask_table->xlfds[i]);
-
- *cfont = mask_table->cfonts[i];
- pango_cfont_ref (*cfont);
+ index = (*mask_table->charsets[i]->conv_func) (cache, mask_table->charsets[i]->id, input);
- *glyph = index;
+ glyph = PANGO_X_MAKE_GLYPH (mask_table->charset_ids[i], index);
- return TRUE;
- }
- }
+ if (pango_x_has_glyph (font, glyph))
+ return glyph;
}
- return FALSE;
+ return 0;
}
static void
-set_glyph (PangoGlyphString *glyphs, gint i, PangoCFont *cfont, PangoGlyphIndex glyph)
+set_glyph (PangoFont *font, PangoGlyphString *glyphs, gint i, PangoGlyphIndex glyph)
{
gint width;
- glyphs->glyphs[i].font = cfont;
glyphs->glyphs[i].glyph = glyph;
glyphs->geometry[i].x_offset = 0;
@@ -375,8 +288,8 @@ set_glyph (PangoGlyphString *glyphs, gint i, PangoCFont *cfont, PangoGlyphIndex
glyphs->log_clusters[i] = i;
- pango_x_glyph_extents (&glyphs->glyphs[i],
- NULL, NULL, &width, NULL, NULL, NULL, NULL);
+ pango_x_glyph_extents (font, glyphs->glyphs[i].glyph,
+ NULL, NULL, &width, NULL, NULL, NULL, NULL);
glyphs->geometry[i].width = width * 72;
}
@@ -488,17 +401,17 @@ swap_range (PangoGlyphString *glyphs, int start, int end)
}
static void
-basic_engine_shape (PangoFont *font,
- gchar *text,
- gint length,
- PangoAnalysis *analysis,
- PangoGlyphString *glyphs)
+basic_engine_shape (PangoFont *font,
+ gchar *text,
+ gint length,
+ PangoAnalysis *analysis,
+ PangoGlyphString *glyphs)
{
int n_chars;
int i;
char *p, *next;
- PangoCFont *fallback_font = NULL;
+ PangoXCharset fallback_charset = 0;
CharCache *cache;
g_return_if_fail (font != NULL);
@@ -511,7 +424,7 @@ basic_engine_shape (PangoFont *font,
{
cache = char_cache_new ();
pango_font_set_data (font, "basic-char-cache",
- cache, (GDestroyNotify)char_cache_free);
+ cache, (GDestroyNotify)char_cache_free);
}
n_chars = unicode_strlen (text, length);
@@ -522,7 +435,6 @@ basic_engine_shape (PangoFont *font,
{
GUChar4 wc;
FriBidiChar mirrored_ch;
- PangoCFont *cfont = NULL;
PangoGlyphIndex index;
_pango_utf8_iterate (p, &next, &wc);
@@ -531,12 +443,10 @@ basic_engine_shape (PangoFont *font,
if (fribidi_get_mirror_char (wc, &mirrored_ch))
wc = mirrored_ch;
- if (find_char (cache, font, wc, p, &cfont, &index))
+ index = find_char (cache, font, wc, p);
+ if (index)
{
- set_glyph (glyphs, i, cfont, index);
-
- if (i != 0 && glyphs->glyphs[i-1].font == cfont)
- pango_cfont_unref (cfont);
+ set_glyph (font, glyphs, i, index);
if (unicode_type (wc) == UNICODE_NON_SPACING_MARK)
{
@@ -551,13 +461,10 @@ basic_engine_shape (PangoFont *font,
}
else
{
- if (!fallback_font)
- fallback_font = pango_x_find_cfont (font, "iso8859-1");
+ if (!fallback_charset)
+ fallback_charset = pango_x_find_charset (font, "iso8859-1");
- if (i == 0 || glyphs->glyphs[i-1].font != fallback_font)
- pango_cfont_ref (fallback_font);
-
- set_glyph (glyphs, i, fallback_font, ' ');
+ set_glyph (font, glyphs, i, PANGO_X_MAKE_GLYPH (fallback_charset, ' '));
}
p = next;
@@ -584,9 +491,6 @@ basic_engine_shape (PangoFont *font,
start = end;
}
}
-
- if (fallback_font)
- pango_cfont_unref (fallback_font);
}
static PangoEngine *