diff options
Diffstat (limited to 'pango')
-rw-r--r-- | pango/fonts.c | 42 | ||||
-rw-r--r-- | pango/modules.c | 28 | ||||
-rw-r--r-- | pango/modules.h | 8 | ||||
-rw-r--r-- | pango/pango-coverage.c | 18 | ||||
-rw-r--r-- | pango/pango-font.h | 10 | ||||
-rw-r--r-- | pango/pangox.c | 196 | ||||
-rw-r--r-- | pango/pangox.h | 15 | ||||
-rw-r--r-- | pango/utils.c | 64 | ||||
-rw-r--r-- | pango/utils.h | 12 |
9 files changed, 331 insertions, 62 deletions
diff --git a/pango/fonts.c b/pango/fonts.c index 421fcf4b..a519daee 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -175,6 +175,47 @@ pango_font_get_data (PangoFont *font, return g_datalist_get_data (&font->data, key); } +/** + * pango_font_get_coverage: + * @font: a #PangoFont + * @lang: the language tag (in the form of "en_US") + * + * Compute the coverage map for a given font and language tag. + * + * Return value: a newly allocated #PangoContext object. + **/ +PangoCoverage * +pango_font_get_coverage (PangoFont *font, + const char *lang) +{ + g_return_val_if_fail (font != NULL, NULL); + g_return_val_if_fail (lang != NULL, NULL); + + return font->klass->get_coverage (font, lang); +} + +/** + * pango_font_find_shaper: + * @font: a #PangoFont + * @lang: the language tag (in the form of "en_US") + * @ch: the ISO-10646 character code. + * + * Find the best matching shaper for a font for a particular + * language tag and character point. + * + * Return value: the best matching shaper. + **/ +PangoEngineShape * +pango_font_find_shaper (PangoFont *font, + const char *lang, + guint32 ch) +{ + g_return_val_if_fail (font != NULL, NULL); + g_return_val_if_fail (lang != NULL, NULL); + + return font->klass->find_shaper (font, lang, ch); +} + /** * pango_font_map_init: @@ -265,3 +306,4 @@ pango_font_map_list_fonts (PangoFontMap *fontmap, fontmap->klass->list_fonts (fontmap, descs, n_descs); } + diff --git a/pango/modules.c b/pango/modules.c index 0016df1f..91dce07d 100644 --- a/pango/modules.c +++ b/pango/modules.c @@ -48,15 +48,15 @@ struct _PangoEnginePair GList *engines; static PangoMap *build_map (PangoMapInfo *info); -static void read_modules (void); -static guint map_info_hash (const PangoMapInfo *map); -static gboolean map_info_equal (const PangoMapInfo *map_a, - const PangoMapInfo *map_b); +static void read_modules (void); +static guint map_info_hash (const PangoMapInfo *map); +static gboolean map_info_equal (const PangoMapInfo *map_a, + const PangoMapInfo *map_b); PangoMap * -_pango_find_map (gchar *lang, - gchar *engine_type, - gchar *render_type) +_pango_find_map (const char *lang, + const char *engine_type, + const char *render_type) { PangoMapInfo map_info; PangoMap *map; @@ -67,16 +67,18 @@ _pango_find_map (gchar *lang, map_hash = g_hash_table_new ((GHashFunc)map_info_hash, (GCompareFunc)map_info_equal); - map_info.lang = lang; - map_info.engine_type = engine_type; - map_info.render_type = render_type; + map_info.lang = (char *)lang; + map_info.engine_type = (char *)engine_type; + map_info.render_type = (char *)render_type; map = g_hash_table_lookup (map_hash, &map_info); if (!map) { PangoMapInfo *new_info = g_new (PangoMapInfo, 1); - *new_info = map_info; - + new_info->lang = g_strdup (lang); + new_info->engine_type = g_strdup (engine_type); + new_info->render_type = g_strdup (render_type); + map = build_map (new_info); g_hash_table_insert (map_hash, new_info, map); } @@ -85,7 +87,7 @@ _pango_find_map (gchar *lang, } PangoEngine * -_pango_load_engine (gchar *id) +_pango_load_engine (const char *id) { GList *tmp_list; diff --git a/pango/modules.h b/pango/modules.h index f6003d57..111baf8e 100644 --- a/pango/modules.h +++ b/pango/modules.h @@ -49,9 +49,9 @@ struct _PangoMap PangoSubmap submaps[256]; }; -PangoMap *_pango_find_map (gchar *lang, - gchar *engine_type, - gchar *render_type); -PangoEngine *_pango_load_engine (gchar *id); +PangoMap *_pango_find_map (const char *lang, + const char *engine_type, + const char *render_type); +PangoEngine *_pango_load_engine (const char *id); #endif /* __MODULES_H__ */ diff --git a/pango/pango-coverage.c b/pango/pango-coverage.c index 38bc62ca..d6ce8812 100644 --- a/pango/pango-coverage.c +++ b/pango/pango-coverage.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +#include <string.h> + #include <pango-coverage.h> typedef struct _PangoBlockInfo PangoBlockInfo; @@ -176,7 +178,7 @@ void pango_coverage_set (PangoCoverage *coverage, guchar *data; g_return_if_fail (coverage != NULL); - g_return_if_fail (level < 0 || level > 3); + g_return_if_fail (level >= 0 || level <= 3); block_index = index / 256; @@ -189,15 +191,25 @@ void pango_coverage_set (PangoCoverage *coverage, data = coverage->blocks[block_index].data; if (!data) { + guchar byte; + if (level == coverage->blocks[block_index].level) return; - data = g_new0 (guchar, 64); + data = g_new (guchar, 64); coverage->blocks[block_index].data = data; + + byte = coverage->blocks[block_index].level | + (coverage->blocks[block_index].level << 2) | + (coverage->blocks[block_index].level << 4) | + (coverage->blocks[block_index].level << 6); + + for (i=0; i<64; i++) + memset (data, byte, 64); } i = index % 256; - data[i] |= level << ((i % 4) * 2); + data[i/4] |= level << ((i % 4) * 2); } /** diff --git a/pango/pango-font.h b/pango/pango-font.h index 45d90e75..a2d618ab 100644 --- a/pango/pango-font.h +++ b/pango/pango-font.h @@ -92,9 +92,10 @@ struct _PangoFontClass { void (*destroy) (PangoFont *font); PangoFontDescription *(*describe) (PangoFont *font); - PangoCoverage * (*get_coverage) (PangoFont *font); + PangoCoverage * (*get_coverage) (PangoFont *font, + const char *lang); PangoEngineShape * (*find_shaper) (PangoFont *font, - const gchar *lang, + const char *lang, guint32 ch); }; @@ -109,9 +110,10 @@ void pango_font_set_data (PangoFont *font, GDestroyNotify destroy_func); PangoFontDescription *pango_font_describe (PangoFont *font); -PangoCoverage * pango_font_get_coverage (PangoFont *font); +PangoCoverage * pango_font_get_coverage (PangoFont *font, + const char *lang); PangoEngineShape * pango_font_find_shaper (PangoFont *font, - const gchar *lang, + const char *lang, guint32 ch); /* diff --git a/pango/pangox.c b/pango/pangox.c index 94b70297..773c7d03 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -20,6 +20,7 @@ */ #include <X11/Xlib.h> +#include "modules.h" #include "pangox.h" #include <ctype.h> #include <math.h> @@ -149,12 +150,19 @@ static void pango_x_font_map_list_fonts (PangoFontMap *fontmap, PangoFontDescription ***descs, int *n_descs); +static void pango_x_font_destroy (PangoFont *font); +static PangoFontDescription *pango_x_font_describe (PangoFont *font); +static PangoCoverage * pango_x_font_get_coverage (PangoFont *font, + const char *lang); +static PangoEngineShape * pango_x_font_find_shaper (PangoFont *font, + const char *lang, + guint32 ch); + static PangoXSubfontInfo * pango_x_find_subfont (PangoFont *font, PangoXSubfont subfont_index); static XCharStruct * pango_x_get_per_char (PangoFont *font, PangoXSubfontInfo *subfont, guint16 char_index); -static void pango_x_font_destroy (PangoFont *font); static gboolean pango_x_find_glyph (PangoFont *font, PangoGlyph glyph, PangoXSubfontInfo **subfont_return, @@ -172,7 +180,10 @@ static void pango_x_insert_font (PangoXFontMap *fontmap, static GList *fontmaps; PangoFontClass pango_x_font_class = { - pango_x_font_destroy + pango_x_font_destroy, + pango_x_font_describe, + pango_x_font_get_coverage, + pango_x_font_find_shaper }; PangoFontMapClass pango_x_font_map_class = { @@ -873,6 +884,30 @@ name_for_charset (char *xlfd, char *charset) return result; } +static PangoXSubfont +pango_x_insert_subfont (PangoFont *font, const char *xlfd) +{ + PangoXFont *xfont = (PangoXFont *)font; + PangoXSubfontInfo *info; + + info = g_new (PangoXSubfontInfo, 1); + + info->xlfd = g_strdup (xlfd); + info->font_struct = NULL; + + xfont->n_subfonts++; + + if (xfont->n_subfonts > xfont->max_subfonts) + { + xfont->max_subfonts *= 2; + xfont->subfonts = g_renew (PangoXSubfontInfo *, xfont->subfonts, xfont->max_subfonts); + } + + xfont->subfonts[xfont->n_subfonts - 1] = info; + + return xfont->n_subfonts; +} + /** * pango_x_list_subfonts: * @font: a PangoFont @@ -911,7 +946,7 @@ pango_x_list_subfonts (PangoFont *font, for (i = 0; i < xfont->n_fonts; i++) { - PangoXSubfontInfo *info = NULL; + PangoXSubfont subfont = 0; char *xlfd = name_for_charset (xfont->fonts[i], charsets[j]); if (xlfd) @@ -919,31 +954,13 @@ pango_x_list_subfonts (PangoFont *font, int count; char **names = XListFonts (xfont->display, xlfd, 1, &count); if (count > 0) - { - info = g_new (PangoXSubfontInfo, 1); - - info->xlfd = g_strdup (names[0]); - info->font_struct = NULL; - } - + subfont = pango_x_insert_subfont (font, names[0]); + + XFreeFontNames (names); g_free (xlfd); } - if (info) - { - xfont->n_subfonts++; - - if (xfont->n_subfonts > xfont->max_subfonts) - { - xfont->max_subfonts *= 2; - xfont->subfonts = g_renew (PangoXSubfontInfo *, xfont->subfonts, xfont->max_subfonts); - } - - xfont->subfonts[xfont->n_subfonts - 1] = info; - subfont_lists[j][i] = xfont->n_subfonts; - } - else - subfont_lists[j][i] = 0; + subfont_lists[j][i] = subfont; } g_hash_table_insert (xfont->subfonts_by_charset, g_strdup (charsets[j]), subfont_lists[j]); @@ -1015,6 +1032,93 @@ pango_x_font_destroy (PangoFont *font) g_free (font); } +static PangoFontDescription * +pango_x_font_describe (PangoFont *font) +{ + /* FIXME: implement */ + return NULL; +} + +static void +free_coverages_foreach (gpointer key, + gpointer value, + gpointer data) +{ + pango_coverage_destroy (value); +} + +static PangoCoverage * +pango_x_font_get_coverage (PangoFont *font, + const char *lang) +{ + guint32 ch; + PangoMap *shape_map; + PangoSubmap *submap; + PangoMapEntry *entry; + PangoCoverage *coverage; + PangoCoverage *result; + PangoCoverageLevel font_level; + GHashTable *coverage_hash; + + result = pango_coverage_new (); + + coverage_hash = g_hash_table_new (g_str_hash, g_str_equal); + + shape_map = _pango_find_map (lang, PANGO_ENGINE_TYPE_SHAPE, + PANGO_RENDER_TYPE_X); + + for (ch = 0; ch < 65536; ch++) + { + submap = &shape_map->submaps[ch / 256]; + entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[ch % 256]; + + if (entry->info) + { + coverage = g_hash_table_lookup (coverage_hash, entry->info->id); + if (!coverage) + { + PangoEngineShape *engine = (PangoEngineShape *)_pango_load_engine (entry->info->id); + coverage = engine->get_coverage (font, lang); + g_hash_table_insert (coverage_hash, entry->info->id, coverage); + } + + font_level = pango_coverage_get (coverage, ch); + if (font_level == PANGO_COVERAGE_EXACT && !entry->is_exact) + font_level = PANGO_COVERAGE_APPROXIMATE; + + if (font_level != PANGO_COVERAGE_NONE) + pango_coverage_set (result, ch, font_level); + } + } + + g_hash_table_foreach (coverage_hash, free_coverages_foreach, NULL); + g_hash_table_destroy (coverage_hash); + + return result; +} + +static PangoEngineShape * +pango_x_font_find_shaper (PangoFont *font, + const gchar *lang, + guint32 ch) +{ + PangoMap *shape_map = NULL; + PangoSubmap *submap; + PangoMapEntry *entry; + + shape_map = _pango_find_map (lang, PANGO_ENGINE_TYPE_SHAPE, + PANGO_RENDER_TYPE_X); + + submap = &shape_map->submaps[ch / 256]; + entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[ch % 256]; + + /* FIXME: check entry->is_exact */ + if (entry->info) + return (PangoEngineShape *)_pango_load_engine (entry->info->id); + else + return NULL; +} + /* Utility functions */ static XFontStruct * @@ -1120,3 +1224,45 @@ pango_x_find_glyph (PangoFont *font, else return FALSE; } + +/** + * pango_x_get_unknown_glyph: + * @font: a #PangoFont + * + * Return the index of a glyph suitable for drawing unknown characters. + * + * Return value: a glyph index into @font + **/ +PangoGlyph +pango_x_get_unknown_glyph (PangoFont *font) +{ + PangoXFont *xfont = (PangoXFont *)font; + + /* The strategy here is to find _a_ X font, any X font in the fontset, and + * then get the unknown glyph for that font. + */ + + g_return_val_if_fail (font != 0, 0); + g_return_val_if_fail (xfont->n_fonts != 0, 0); + + if (xfont->n_subfonts == 0) + { + int count; + char **names = XListFonts (xfont->display, xfont->fonts[0], 1, &count); + + if (count > 0) + pango_x_insert_subfont (font, names[0]); + + XFreeFontNames (names); + } + + if (xfont->n_subfonts > 0) + { + XFontStruct *font_struct = pango_x_get_font_struct (font, xfont->subfonts[0]); + + if (font_struct) + return PANGO_X_MAKE_GLYPH (1,font_struct->default_char); + } + + return 0; +} diff --git a/pango/pangox.h b/pango/pangox.h index b567aa46..e24c6d0d 100644 --- a/pango/pangox.h +++ b/pango/pangox.h @@ -73,13 +73,14 @@ typedef guint16 PangoXSubfont; #define PANGO_X_GLYPH_SUBFONT(glyph) (glyph>>16) #define PANGO_X_GLYPH_INDEX(glyph) (glyph & 0xffff) -int pango_x_list_subfonts (PangoFont *font, - char **charsets, - int n_charsets, - PangoXSubfont **subfont_ids, - int **subfont_charsets); -gboolean pango_x_has_glyph (PangoFont *font, - PangoGlyph glyph); +int pango_x_list_subfonts (PangoFont *font, + char **charsets, + int n_charsets, + PangoXSubfont **subfont_ids, + int **subfont_charsets); +gboolean pango_x_has_glyph (PangoFont *font, + PangoGlyph glyph); +PangoGlyph pango_x_get_unknown_glyph (PangoFont *font); #ifdef __cplusplus } diff --git a/pango/utils.c b/pango/utils.c index 6790113d..7eacff35 100644 --- a/pango/utils.c +++ b/pango/utils.c @@ -27,8 +27,8 @@ gboolean _pango_utf8_iterate (const char *cur, const char **next, GUChar4 *wc_out) { - const char *p = cur; - char c = *p; + const guchar *p = (guchar *)cur; + guchar c = *p; GUChar4 wc; gint length; @@ -78,7 +78,7 @@ _pango_utf8_iterate (const char *cur, const char **next, GUChar4 *wc_out) if (wc_out) *wc_out = wc; if (next) - *next = p; + *next = (const char *)p; return TRUE; } @@ -150,4 +150,62 @@ _pango_utf8_to_ucs2 (const char *str, int len) iconv_close (cd); return (GUChar2 *)result; + +} + +/** + * _pango_guchar4_to_utf8: + * @ch: a ISO10646 character code + * @out: output buffer, must have at least 6 bytes of space. + * + * Convert a single character to utf8 + * + * Return value: number of bytes written + **/ +int +_pango_guchar4_to_utf8 (GUChar4 c, char *outbuf) +{ + size_t len = 0; + int first; + int i; + + if (c < 0x80) + { + first = 0; + len = 1; + } + else if (c < 0x800) + { + first = 0xc0; + len = 2; + } + else if (c < 0x10000) + { + first = 0xe0; + len = 3; + } + else if (c < 0x200000) + { + first = 0xf0; + len = 4; + } + else if (c < 0x4000000) + { + first = 0xf8; + len = 5; + } + else + { + first = 0xfc; + len = 6; + } + + for (i = len - 1; i > 0; --i) + { + outbuf[i] = (c & 0x3f) | 0x80; + c >>= 6; + } + outbuf[0] = c | first; + + return len; } diff --git a/pango/utils.h b/pango/utils.h index cfb82d0a..d46d44ba 100644 --- a/pango/utils.h +++ b/pango/utils.h @@ -27,8 +27,14 @@ typedef guint16 GUChar2; typedef guint32 GUChar4; -gboolean _pango_utf8_iterate (const char *cur, const char **next, GUChar4 *wc_out); -GUChar2 *_pango_utf8_to_ucs2 (const char *str, gint len); -int _pango_utf8_len (const char *str, gint limit); +gboolean _pango_utf8_iterate (const char *cur, + const char **next, + GUChar4 *wc_out); +GUChar2 *_pango_utf8_to_ucs2 (const char *str, + gint len); +int _pango_guchar4_to_utf8 (GUChar4 c, + char *outbuf); +int _pango_utf8_len (const char *str, + gint limit); #endif /* __UTILS_H__ */ |