diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-0 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-10 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-2 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-4 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-6 | 25 | ||||
-rw-r--r-- | ChangeLog.pre-1-8 | 25 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | examples/HELLO.utf8 | 2 | ||||
-rw-r--r-- | examples/Makefile.am | 2 | ||||
-rw-r--r-- | examples/pango.modules | 4 | ||||
-rw-r--r-- | examples/viewer.c | 10 | ||||
-rw-r--r-- | fonts/.cvsignore | 2 | ||||
-rw-r--r-- | fonts/Makefile.am | 4 | ||||
-rw-r--r-- | modules/Makefile.am | 2 | ||||
-rw-r--r-- | modules/basic/basic-x.c | 218 | ||||
-rw-r--r-- | modules/basic/basic.c | 218 | ||||
-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 |
23 files changed, 663 insertions, 899 deletions
@@ -1,3 +1,28 @@ +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. + +Fri Jan 14 12:08:43 2000 Owen Taylor <otaylor@redhat.com> + + * examples/HELLO.utf8: Add Pango properly spelled. + + * **/Makefile.am: make dist fixes. + Thu Jan 13 17:49:45 2000 Owen Taylor <otaylor@redhat.com> * TODO: Updated. diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0 index 04ac995c..bf398ac7 100644 --- a/ChangeLog.pre-1-0 +++ b/ChangeLog.pre-1-0 @@ -1,3 +1,28 @@ +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. + +Fri Jan 14 12:08:43 2000 Owen Taylor <otaylor@redhat.com> + + * examples/HELLO.utf8: Add Pango properly spelled. + + * **/Makefile.am: make dist fixes. + Thu Jan 13 17:49:45 2000 Owen Taylor <otaylor@redhat.com> * TODO: Updated. diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index 04ac995c..bf398ac7 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,28 @@ +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. + +Fri Jan 14 12:08:43 2000 Owen Taylor <otaylor@redhat.com> + + * examples/HELLO.utf8: Add Pango properly spelled. + + * **/Makefile.am: make dist fixes. + Thu Jan 13 17:49:45 2000 Owen Taylor <otaylor@redhat.com> * TODO: Updated. diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2 index 04ac995c..bf398ac7 100644 --- a/ChangeLog.pre-1-2 +++ b/ChangeLog.pre-1-2 @@ -1,3 +1,28 @@ +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. + +Fri Jan 14 12:08:43 2000 Owen Taylor <otaylor@redhat.com> + + * examples/HELLO.utf8: Add Pango properly spelled. + + * **/Makefile.am: make dist fixes. + Thu Jan 13 17:49:45 2000 Owen Taylor <otaylor@redhat.com> * TODO: Updated. diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index 04ac995c..bf398ac7 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,28 @@ +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. + +Fri Jan 14 12:08:43 2000 Owen Taylor <otaylor@redhat.com> + + * examples/HELLO.utf8: Add Pango properly spelled. + + * **/Makefile.am: make dist fixes. + Thu Jan 13 17:49:45 2000 Owen Taylor <otaylor@redhat.com> * TODO: Updated. diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index 04ac995c..bf398ac7 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,28 @@ +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. + +Fri Jan 14 12:08:43 2000 Owen Taylor <otaylor@redhat.com> + + * examples/HELLO.utf8: Add Pango properly spelled. + + * **/Makefile.am: make dist fixes. + Thu Jan 13 17:49:45 2000 Owen Taylor <otaylor@redhat.com> * TODO: Updated. diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index 04ac995c..bf398ac7 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,28 @@ +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. + +Fri Jan 14 12:08:43 2000 Owen Taylor <otaylor@redhat.com> + + * examples/HELLO.utf8: Add Pango properly spelled. + + * **/Makefile.am: make dist fixes. + Thu Jan 13 17:49:45 2000 Owen Taylor <otaylor@redhat.com> * TODO: Updated. diff --git a/Makefile.am b/Makefile.am index 048ef5fc..b4176aa5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,3 @@ ## Process this file with automake to create Makefile.in. -SUBDIRS=libpango modules examples docs tools
\ No newline at end of file +SUBDIRS=libpango modules examples docs tools fonts
\ No newline at end of file diff --git a/configure.in b/configure.in index 2737485f..1d9f68fb 100644 --- a/configure.in +++ b/configure.in @@ -48,4 +48,5 @@ modules/tamil/Makefile examples/Makefile docs/Makefile tools/Makefile +fonts/Makefile ]) diff --git a/examples/HELLO.utf8 b/examples/HELLO.utf8 index e8ae856c..f7dc6b15 100644 --- a/examples/HELLO.utf8 +++ b/examples/HELLO.utf8 @@ -1,3 +1,5 @@ +Παν語 + This is a list of ways to say hello in various languages. Its purpose is to illustrate a number of scripts. (Converted into UTF-8) diff --git a/examples/Makefile.am b/examples/Makefile.am index 4356480b..dc6591cf 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -14,4 +14,4 @@ pango.modules: ( cd ../modules && \ ../libpango/pango-querymodules `find . -name '*.so'` > ../examples/pango.modules ) -EXTRA_DIST=HELLO.utf8
\ No newline at end of file +EXTRA_DIST=HELLO.utf8 muru.utf
\ No newline at end of file diff --git a/examples/pango.modules b/examples/pango.modules index e945bf29..28d2cb73 100644 --- a/examples/pango.modules +++ b/examples/pango.modules @@ -1,6 +1,2 @@ /home/otaylor/devel/pango/modules/./basic/.libs/pango-basic.so BasicScriptEngineLang PangoEngineLang PangoRenderNone 0-687:* 688-767: 896-1423:* 1425-1641:* 7680-8191:* 8192-40959:* 44032-55203:kr 63744-64011:kr 65280-65507:* /home/otaylor/devel/pango/modules/./basic/.libs/pango-basic.so BasicScriptEngineX PangoEngineShape PangoRenderX 0-687:* 688-767: 896-1423:* 1425-1641:* 7680-8191:* 8192-40959:* 44032-55203:kr 63744-64011:kr 65280-65507:* -/home/otaylor/devel/pango/modules/./hangul/.libs/pango-hangul.so HangulScriptEngineLang PangoEngineLang PangoRenderNone 4352-4607:* 44032-55203:* -/home/otaylor/devel/pango/modules/./hangul/.libs/pango-hangul.so HangulScriptEngineX PangoEngineShape PangoRenderX 4352-4607:* 44032-55203:* -/home/otaylor/devel/pango/modules/./tamil/.libs/pango-tamil.so TamilScriptEngineLang PangoEngineLang PangoRenderNone 2944-3071:* -/home/otaylor/devel/pango/modules/./tamil/.libs/pango-tamil.so TamilScriptEngineX PangoEngineShape PangoRenderX 2944-3071:* diff --git a/examples/viewer.c b/examples/viewer.c index 4404631f..82da2d4a 100644 --- a/examples/viewer.c +++ b/examples/viewer.c @@ -214,7 +214,7 @@ break_run (char *text, buf = pango_glyph_string_new(); pango_shape (font, text + item->offset, item->length, &item->analysis, buf); - pango_x_extents (buf, NULL, NULL, &width, NULL, NULL, logical_ascent, logical_descent); + pango_x_extents (font, buf, NULL, NULL, &width, NULL, NULL, logical_ascent, logical_descent); result = FALSE; *new_item = NULL; @@ -407,7 +407,7 @@ runs_x_to_cp (char *text, GList *runs, int x, int *offset) PangoItem *item = runs->data; pango_shape (font, text + item->offset, item->length, &item->analysis, buf); - pango_x_extents (buf, NULL, NULL, &width, NULL, NULL, NULL, NULL); + pango_x_extents (font, buf, NULL, NULL, &width, NULL, NULL, NULL, NULL); if (x >= pixels && x < pixels + width) { @@ -502,7 +502,7 @@ runs_char_bounds (char *text, GList *runs, int offset, int *x, int *width) PangoItem *item = runs->data; pango_shape (font, text + item->offset, item->length, &item->analysis, buf); - pango_x_extents (buf, NULL, NULL, &run_width, NULL, NULL, NULL, NULL); + pango_x_extents (font, buf, NULL, NULL, &run_width, NULL, NULL, NULL, NULL); if (offset >= item->offset && offset < item->offset + item->length) @@ -661,14 +661,14 @@ expose_paragraph (Paragraph *para, GdkDrawable *drawable, /* Render the glyphs to the screen */ pango_x_render (GDK_DISPLAY(), GDK_WINDOW_XWINDOW (drawable), - GDK_GC_XGC (gc), buf, x + x_off, + GDK_GC_XGC (gc), font, buf, x + x_off, y + line->ascent); /* Advance to next x position */ if (run_list->next) { - pango_x_extents (buf, NULL, NULL, &width, NULL, NULL, NULL, NULL); + pango_x_extents (font, buf, NULL, NULL, &width, NULL, NULL, NULL, NULL); x_off += width; } diff --git a/fonts/.cvsignore b/fonts/.cvsignore new file mode 100644 index 00000000..c038ed78 --- /dev/null +++ b/fonts/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in
\ No newline at end of file diff --git a/fonts/Makefile.am b/fonts/Makefile.am new file mode 100644 index 00000000..11d9f3ef --- /dev/null +++ b/fonts/Makefile.am @@ -0,0 +1,4 @@ +## Process this file with automake to create Makefile.in. + +EXTRA_DIST= \ + tscakaram.pcf 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 * 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 */ |