From 423b58031d400ccad0a3e40f59dd85253a74685b Mon Sep 17 00:00:00 2001 From: handa Date: Mon, 13 Sep 2004 01:55:39 +0000 Subject: [PATCH] (try_font_group): New function. (mfont__lookup_fontset): Use try_font_group. --- src/fontset.c | 218 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 124 insertions(+), 94 deletions(-) diff --git a/src/fontset.c b/src/fontset.c index 6feef43..016c556 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -500,128 +500,158 @@ mfont__free_realized_fontset (MRealizedFontset *realized) } +static MRealizedFont * +try_font_group (MRealizedFontset *realized, + MPlist *font_group, MGlyph *g, int *num, int size) +{ + MFrame *frame = realized->frame; + MRealizedFont *rfont; + MPlist *plist; + int i; + + if (MPLIST_PLIST_P (font_group)) + realize_font_group (frame, &realized->spec, font_group, size); + + MPLIST_DO (plist, font_group) + { + rfont = (MRealizedFont *) MPLIST_VAL (plist); + if (rfont->status < 0) + continue; + /* Check if this font can display all glyphs. */ + for (i = 0; i < *num; i++) + { + g[i].code = mfont__encode_char (rfont, + g[i].type == GLYPH_CHAR ? g[i].c + : ' '); + if (g[i].code == MCHAR_INVALID_CODE) + break; + } + if (i == *num) + { + if (rfont->status > 0 + || mfont__open (rfont) == 0) + /* We found a font that can display all glyphs. */ + return rfont; + } + } + + /* We couldn't find a font that can display all glyphs. Find one + that can display at least the first glyph. */ + MPLIST_DO (plist, font_group) + { + rfont = (MRealizedFont *) MPLIST_VAL (plist); + if (rfont->status < 0) + continue; + g->code = mfont__encode_char (rfont, + g->type == GLYPH_CHAR ? g->c : ' '); + if (g->code != MCHAR_INVALID_CODE) + { + if (rfont->status > 0 + || mfont__open (rfont) == 0) + { + /* Ok, let's use this font. Check how many more + characters it supports. */ + int i; + + for (i = 1; i < *num; i++) + { + g[i].code = mfont__encode_char (rfont, + g[i].type == GLYPH_CHAR + ? g[i].c : ' '); + if (g[i].code == MCHAR_INVALID_CODE) + break; + } + *num = i; + return rfont; + } + } + } + + return NULL; +} + MRealizedFont * mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num, MSymbol script, MSymbol language, MSymbol charset, int size) { - MFrame *frame = realized->frame; MCharset *preferred_charset = (charset == Mnil ? NULL : MCHARSET (charset)); MPlist *per_charset, *per_script, *per_lang; - MPlist *font_groups[256], *plist; - int n_font_group = 0; - MRealizedFont *rfont; - int i; + MPlist *plist; + MRealizedFont *rfont = NULL; if (realized->tick != realized->fontset->tick) update_fontset_elements (realized); if (preferred_charset - && (per_charset = mplist_get (realized->per_charset, charset)) != NULL) - font_groups[n_font_group++] = per_charset; + && (per_charset = mplist_get (realized->per_charset, charset)) != NULL + && (rfont = try_font_group (realized, per_charset, g, num, size))) + return rfont; + if (script != Mnil - && ((per_script = mplist_find_by_key (realized->per_script, script)) - != NULL)) + && (per_script = mplist_get (realized->per_script, script))) { /* We prefer font groups in this order: - (1) group matching LANGUAGE - (2) group for generic LANGUAGE - (3) group non-matching LANGUAGE */ + (1) group matching with LANGUAGE if LANGUAGE is not Mnil + (2) group for generic language + (3) group not matching with LANGUAGE */ if (language == Mnil) language = Mt; - per_lang = mplist_find_by_key (MPLIST_PLIST (per_script), language); - if (per_lang) + if ((per_lang = mplist_get (per_script, language)) + && (rfont = try_font_group (realized, per_lang, g, num, size))) + return rfont; + + if (language == Mt) { - font_groups[n_font_group++] = MPLIST_PLIST (per_lang); - if (language == Mt) - { - MPLIST_DO (per_lang, MPLIST_PLIST (per_script)) - if (MPLIST_KEY (per_lang) != language) - font_groups[n_font_group++] = MPLIST_PLIST (per_lang); - } + /* Try the above (3) */ + MPLIST_DO (plist, per_script) + if (MPLIST_KEY (plist) != language + && (rfont = try_font_group (realized, MPLIST_PLIST (plist), + g, num, size))) + return rfont; } - if (language != Mt) + else { - plist = mplist_get (MPLIST_PLIST (per_script), Mt); - if (plist) - font_groups[n_font_group++] = plist; + /* At first try the above (2) */ + if ((per_lang = mplist_get (per_script, Mt)) + && (rfont = try_font_group (realized, per_lang, g, num, size))) + return rfont; + + /* Then try the above (3) */ + MPLIST_DO (plist, per_script) + if (MPLIST_KEY (plist) != language + && MPLIST_KEY (plist) != Mt + && (rfont = try_font_group (realized, MPLIST_PLIST (plist), + g, num, size))) + return rfont; } - MPLIST_DO (per_lang, MPLIST_PLIST (per_script)) - if (MPLIST_KEY (per_lang) != language - && MPLIST_KEY (per_lang) != Mt) - font_groups[n_font_group++] = MPLIST_PLIST (per_lang); } - font_groups[n_font_group++] = realized->fallback; - - if (n_font_group == 1) - { - /* As we only have a fallback font group, try all the other - fonts too. */ - MPLIST_DO (per_script, realized->per_script) - MPLIST_DO (per_lang, MPLIST_PLIST (per_script)) - font_groups[n_font_group++] = MPLIST_PLIST (per_lang); - MPLIST_DO (per_charset, realized->per_charset) - font_groups[n_font_group++] = MPLIST_PLIST (per_charset); - } - - for (i = 0; i < n_font_group; i++) - { - int j; - - if (MPLIST_PLIST_P (font_groups[i])) - realize_font_group (frame, &realized->spec, font_groups[i], size); - MPLIST_DO (plist, font_groups[i]) - { - rfont = (MRealizedFont *) MPLIST_VAL (plist); - if (rfont->status < 0) - continue; - /* Check if this font can display all glyphs. */ - for (j = 0; j < *num; j++) - { - g[j].code = mfont__encode_char (rfont, - g[j].type == GLYPH_CHAR ? g[j].c - : ' '); - if (g[j].code == MCHAR_INVALID_CODE) - break; - } - if (j == *num) - { - if (rfont->status > 0 - || mfont__open (rfont) == 0) - /* We found a font that can display all glyphs. */ - break; - } - } - if (! MPLIST_TAIL_P (plist)) - break; - } + if (language != Mnil) + /* Find a font group for this language from all scripts. */ + MPLIST_DO (plist, realized->per_script) + if ((per_lang = mplist_get (MPLIST_PLIST (plist), language)) + && (rfont = try_font_group (realized, per_lang, g, num, size))) + return rfont; - if (i < n_font_group) + /* Try fallback fonts. */ + if ((rfont = try_font_group (realized, realized->fallback, g, num, size))) return rfont; - /* We couldn't find a font that can display all glyphs. Find one - that can display at least the first glyph. */ - for (i = 0; i < n_font_group; i++) + /* At last try all fonts. */ + MPLIST_DO (per_script, realized->per_script) { - MPLIST_DO (plist, font_groups[i]) - { - rfont = (MRealizedFont *) MPLIST_VAL (plist); - if (rfont->status < 0) - continue; - g->code = mfont__encode_char (rfont, - g->type == GLYPH_CHAR ? g->c : ' '); - if (g->code != MCHAR_INVALID_CODE) - { - if (rfont->status > 0 - || mfont__open (rfont) == 0) - break; - } - } - if (! MPLIST_TAIL_P (plist)) - break; + MPLIST_DO (per_lang, MPLIST_PLIST (per_script)) + if ((rfont = try_font_group (realized, MPLIST_PLIST (per_lang), + g, num, size))) + return rfont; } - return (i < n_font_group ? rfont : NULL); + MPLIST_DO (per_charset, realized->per_charset) + if ((rfont = try_font_group (realized, MPLIST_PLIST (per_charset), + g, num, size))) + return rfont; + + return NULL; } /*** @} */ -- 1.7.10.4