X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Ffontset.c;h=6a8bca12ccc86a6706b60324dd6d61ae2621e58b;hb=d1f4e58c580e5422474bf1d8e1e5aa8ef0fe4035;hp=3f8e938ef11c8fc46931fb22229afdc29e7eb18d;hpb=054d6313e9301d08446565496324c4b8b18298f6;p=m17n%2Fm17n-lib.git diff --git a/src/fontset.c b/src/fontset.c index 3f8e938..6a8bca1 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -1,5 +1,5 @@ /* fontset.c -- fontset module. - Copyright (C) 2003, 2004 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H15PRO112 @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 02111-1307, USA. */ /***en @@ -39,16 +39,15 @@ @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ïʸ»ú¤«¤é¥Õ¥©¥ó¥È¤Ø¤ÎÂбþÉÕ¤±¤ò¹Ô¤¦¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë. - @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£M-text ¤ò - ɽ¼¨¤¹¤ëºÝ¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï M-text Ãæ¤Î¸Ä¡¹¤Îʸ»ú¤ËÂФ·¤Æ¤É¤Î¥Õ¥© - ¥ó¥È¤òÍѤ¤¤ë¤«¤Îµ¬Â§¤ò¡¢°Ê²¼¤Î¾ðÊó¤Ë½¾¤Ã¤ÆÍ¿¤¨¤ë¡£ + @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£M-text + ¤Îɽ¼¨¤ÎºÝ¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï°Ê²¼¤Î¾ðÊó¤òÍѤ¤¤Æ M-text + Ãæ¤Î¸Ä¡¹¤Îʸ»ú¤Ë¤É¤Î¥Õ¥©¥ó¥È¤òÍѤ¤¤ë¤«·è¤á¤ëµ¬Â§¤òÍ¿¤¨¤ë¡£ @li ʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "¥¹¥¯¥ê¥×¥È" @li ʸ»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ "¸À¸ì" @li ʸ»ú¤Î¥Æ¥­¥¹¥È¥×¥í¥Ñ¥Æ¥£ "ʸ»ú¥»¥Ã¥È" - ¤³¤ì¤é¤Î¾ðÊ󤬤ɤΤ褦¤ËÍѤ¤¤é¤ì¤ë¤«¤Ï mdraw_text () ¤ÎÀâÌÀ¤ò»²¾È - ¤Î¤³¤È¡£ + ¤³¤ì¤é¤Î¾ðÊ󤬤ɤΤ褦¤ËÍѤ¤¤é¤ì¤ë¤«¤Ï mdraw_text () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£ */ @@ -75,6 +74,10 @@ #include "font.h" #include "fontset.h" +static int mdebug_flag = MDEBUG_FONTSET; + +static M17NObjectArray fontset_table; + struct MFontset { M17NObject control; @@ -98,9 +101,6 @@ struct MFontset /* FONT-GROUP */ MPlist *fallback; - - /* Plist of Mt vs font specs. */ - MPlist *font_spec_list; }; static MFontset *default_fontset; @@ -115,8 +115,11 @@ struct MRealizedFontset /* Initialized to ->tick. */ unsigned tick; - /* Font spec extracted from a face. */ - MFont spec; + /* Font spec that must be satisfied, or NULL. */ + MFont *spec; + + /* Font spec requested by a face. */ + MFont request; /* The frame on which the realized fontset is realized. */ MFrame *frame; @@ -130,13 +133,13 @@ struct MRealizedFontset static MPlist * -load_font_group (MPlist *plist, MPlist *elt, MPlist *spec_list) +load_font_group (MPlist *plist, MPlist *elt) { MPLIST_DO (elt, elt) { - /* ELT ::= ( FONT-SPEC-LIST [ LAYOUTER ] ) ... */ - MPlist *elt2, *p; - MFont font, *spec = NULL; + /* ELT ::= ( FONT-SPEC [ LAYOUTER ] ) ... */ + MPlist *elt2; + MFont *font; MSymbol layouter_name; if (! MPLIST_PLIST_P (elt)) @@ -144,28 +147,15 @@ load_font_group (MPlist *plist, MPlist *elt, MPlist *spec_list) elt2 = MPLIST_PLIST (elt); if (! MPLIST_PLIST_P (elt2)) MWARNING (MERROR_FONTSET); - mfont__set_spec_from_plist (&font, MPLIST_PLIST (elt2)); - MPLIST_DO (p, spec_list) - { - if (! memcmp (MPLIST_VAL (p), &font, sizeof (MFont))) - { - spec = MPLIST_VAL (p); - break; - } - } - if (! spec) - { - MSTRUCT_MALLOC (spec, MERROR_FONTSET); - *spec = font; - mplist_add (spec_list, Mt, spec); - } + MSTRUCT_CALLOC (font, MERROR_FONTSET); + mfont__set_spec_from_plist (font, MPLIST_PLIST (elt2)); elt2 = MPLIST_NEXT (elt2); layouter_name = Mt; if (MPLIST_SYMBOL_P (elt2)) layouter_name = MPLIST_SYMBOL (elt2); if (layouter_name == Mnil) layouter_name = Mt; - plist = mplist_add (plist, layouter_name, spec); + plist = mplist_add (plist, layouter_name, font); continue; warning: /* ANSI-C requires some statement after a label. */ @@ -179,59 +169,53 @@ load_font_group (MPlist *plist, MPlist *elt, MPlist *spec_list) static void load_fontset_contents (MFontset *fontset) { - MPlist *per_script, *per_charset, *fallback, *spec_list, *font_group; - MSymbol script, lang; + MPlist *per_script, *per_charset, *font_group; MPlist *fontset_def, *plist; fontset->per_script = per_script = mplist (); fontset->per_charset = per_charset = mplist (); - fontset->fallback = fallback = mplist (); - fontset->font_spec_list = spec_list = mplist (); + fontset->fallback = mplist (); if (! (fontset_def = (MPlist *) mdatabase_load (fontset->mdb))) return; MPLIST_DO (plist, fontset_def) { - /* PLIST ::= ( SCRIPT ( LANGUAGE FONT-SPEC-ELT ... ) ... ) - | (CHARSET FONT-SPEC-ELT ...) - | FONT-SPEC-ELT */ + /* PLIST ::= ( SCRIPT ( LANGUAGE ( FONT-SPEC [LAYOUTER]) ... ) ... ) + | ( CHARSET ( FONT-SPEC [LAYOUTER] ) ...) + | ( nil ( FONT-SPEC [LAYOUTER] ) ...) + FONT-SPEC :: = ( ... ) */ MPlist *elt; + MSymbol sym; if (! MPLIST_PLIST_P (plist)) MWARNING (MERROR_FONTSET); elt = MPLIST_PLIST (plist); if (! MPLIST_SYMBOL_P (elt)) MWARNING (MERROR_FONTSET); - script = MPLIST_SYMBOL (elt); + sym = MPLIST_SYMBOL (elt); elt = MPLIST_NEXT (elt); if (! MPLIST_PLIST_P (elt)) MWARNING (MERROR_FONTSET); - if (script == Mnil) - fallback = load_font_group (fallback, elt, spec_list); + if (sym == Mnil) + load_font_group (fontset->fallback, elt); else if (MPLIST_PLIST_P (MPLIST_PLIST (elt))) { - font_group = mplist_find_by_key (fontset->per_charset, script); - if (! font_group) - { - font_group = mplist (); - per_charset = mplist_add (per_charset, script, font_group); - } - load_font_group (font_group, elt, spec_list); + /* SYM is a charset. */ + font_group = mplist (); + per_charset = mplist_add (per_charset, sym, font_group); + load_font_group (font_group, elt); } else { - MPlist *per_lang = mplist_find_by_key (fontset->per_script, script); - - if (! per_lang) - { - per_lang = mplist (); - per_script = mplist_add (per_script, script, per_lang); - } + /* SYM is a script */ + MPlist *per_lang = mplist (); + per_script = mplist_add (per_script, sym, per_lang); MPLIST_DO (elt, elt) { /* ELT ::= ( LANGUAGE FONT-DEF ...) ... */ MPlist *elt2; + MSymbol lang; if (! MPLIST_PLIST_P (elt)) MWARNING (MERROR_FONTSET); @@ -241,14 +225,10 @@ load_fontset_contents (MFontset *fontset) lang = MPLIST_SYMBOL (elt2); if (lang == Mnil) lang = Mt; - font_group = mplist_find_by_key (per_lang, lang); - if (! font_group) - { - font_group = mplist (); - mplist_add (per_lang, lang, font_group); - } + font_group = mplist (); + mplist_add (per_lang, lang, font_group); elt2 = MPLIST_NEXT (elt2); - load_font_group (font_group, elt2, spec_list); + load_font_group (font_group, elt2); } } continue; @@ -274,6 +254,8 @@ free_fontset (void *object) { MPLIST_DO (pl, MPLIST_PLIST (plist)) { + MPLIST_DO (p, MPLIST_PLIST (pl)) + free (MPLIST_VAL (p)); p = MPLIST_PLIST (pl); M17N_OBJECT_UNREF (p); } @@ -284,68 +266,45 @@ free_fontset (void *object) } if (fontset->per_charset) { - MPLIST_DO (plist, fontset->per_charset) + MPLIST_DO (pl, fontset->per_charset) { - pl = MPLIST_PLIST (plist); - M17N_OBJECT_UNREF (pl); + MPLIST_DO (p, MPLIST_PLIST (pl)) + free (MPLIST_VAL (p)); + p = MPLIST_PLIST (p); + M17N_OBJECT_UNREF (p); } M17N_OBJECT_UNREF (fontset->per_charset); } if (fontset->fallback) - M17N_OBJECT_UNREF (fontset->fallback); + { + MPLIST_DO (p, fontset->fallback) + free (MPLIST_VAL (p)); + M17N_OBJECT_UNREF (fontset->fallback); + } + plist = mplist_find_by_key (fontset_list, fontset->name); if (! plist) mdebug_hook (); mplist_pop (plist); - if (fontset->font_spec_list) + if (MPLIST_TAIL_P (fontset_list)) { - if (((M17NObject *) (fontset->font_spec_list))->ref_count == 1) - MPLIST_DO (plist, fontset->font_spec_list) - free (MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (fontset->font_spec_list); + M17N_OBJECT_UNREF (fontset_list); + fontset_list = NULL; } + M17N_OBJECT_UNREGISTER (fontset_table, fontset); free (object); } static void -realize_font_group (MFrame *frame, MFont *request, MPlist *font_group, - int size) +realize_fontset_elements (MFrame *frame, MRealizedFontset *realized) { - MPlist *plist = MPLIST_VAL (font_group), *pl, *p; - - mplist_set (font_group, Mnil, NULL); - MPLIST_DO (pl, plist) - { - MSymbol layouter = MPLIST_KEY (pl); - MFont this_request = *request; - MRealizedFont *rfont; - - mfont__resize (MPLIST_VAL (pl), &this_request); - rfont = mfont__select (frame, MPLIST_VAL (pl), &this_request, - size, layouter == Mt ? Mnil : layouter); - - if (rfont) - { - MPLIST_DO (p, font_group) - if (((MRealizedFont *) (MPLIST_VAL (p)))->score > rfont->score) - break; - mplist_push (p, Mt, rfont); - } - } -} - -static void -realize_fontset_elements (MFrame *frame, MRealizedFontset *realized, - MFontset *fontset, MFont *request) -{ - MPlist *per_script, *per_lang, *per_charset, *font_group; - MPlist *plist, *pl; + MFontset *fontset = realized->fontset; + MPlist *per_script, *per_charset, *font_group; + MPlist *plist, *pl, *p; - realized->fontset = fontset; - realized->tick = fontset->tick; - realized->spec = *request; - realized->frame = frame; realized->per_script = per_script = mplist (); + /* The actual elements of per_script are realized on demand. */ +#if 0 MPLIST_DO (plist, fontset->per_script) { per_lang = mplist (); @@ -353,29 +312,81 @@ realize_fontset_elements (MFrame *frame, MRealizedFontset *realized, MPLIST_DO (pl, MPLIST_PLIST (plist)) { font_group = mplist (); - mplist_add (font_group, Mplist, MPLIST_VAL (pl)); per_lang = mplist_add (per_lang, MPLIST_KEY (pl), font_group); + MPLIST_DO (p, MPLIST_PLIST (pl)) + font_group = mplist_add (font_group, + MPLIST_KEY (p), MPLIST_VAL (p)); } } +#endif realized->per_charset = per_charset = mplist (); - MPLIST_DO (plist, fontset->per_charset) + MPLIST_DO (pl, fontset->per_charset) { font_group = mplist (); - mplist_add (font_group, Mplist, MPLIST_VAL (plist)); per_charset = mplist_add (per_charset, MPLIST_KEY (plist), font_group); + MPLIST_DO (p, MPLIST_PLIST (pl)) + font_group = mplist_add (font_group, MPLIST_KEY (p), MPLIST_VAL (p)); } + realized->fallback = font_group = mplist (); + MPLIST_DO (p, fontset->fallback) + font_group = mplist_add (font_group, MPLIST_KEY (p), MPLIST_VAL (p)); +} + + +/* Return a plist of fonts for SCRIPT in FONTSET. The returned list + is acutally a plist of languages vs font groups (which is a plist). + If SCRIPT is nil, return a plist of fallback fonts. If FONTSET + doesn't record any fonts for SCRIPT, generate a proper font spec + lists for X backend and FreeType backend. */ + +MPlist * +get_per_script (MFontset *fontset, MSymbol script) +{ + MPlist *plist; + + if (script == Mnil) + return fontset->fallback; + plist = mplist_get (fontset->per_script, script); + if (! plist) + { + int len = MSYMBOL_NAMELEN (script); + char *cap = alloca (8 + len + 1); + MSymbol capability; + MFont *font; + MPlist *pl, *p; - realized->fallback = mplist (); - mplist_add (realized->fallback, Mplist, fontset->fallback); + sprintf (cap, ":script=%s", MSYMBOL_NAME (script)); + capability = msymbol (cap); + pl = mplist (); + MPLIST_DO (p, fontset->fallback) + { + font = mfont_copy (MPLIST_VAL (p)); + mfont_put_prop (font, Mregistry, Municode_bmp); + font->source = MFONT_SOURCE_FT; + font->capability = capability; + mplist_add (pl, Mt, font); + + font = mfont_copy (MPLIST_VAL (p)); + mfont_put_prop (font, Mregistry, Miso10646_1); + font->source = MFONT_SOURCE_X; + font->capability = capability; + mplist_add (pl, Mt, font); + } + plist = mplist (); + mplist_add (plist, Mt, pl); + mplist_add (fontset->per_script, script, plist); + } + return plist; } static void free_realized_fontset_elements (MRealizedFontset *realized) { MPlist *plist, *pl, *p; - MRealizedFont *rfont; + MFont *font; + MFontList *font_list; if (realized->per_script) { @@ -384,8 +395,18 @@ free_realized_fontset_elements (MRealizedFontset *realized) MPLIST_DO (pl, MPLIST_PLIST (plist)) { MPLIST_DO (p, MPLIST_PLIST (pl)) - if ((rfont = MPLIST_VAL (p)) && ! rfont->frame) - free (rfont); + { + font = MPLIST_VAL (p); + if (font->type == MFONT_TYPE_OBJECT) + { + font_list = (MFontList *) font; + free (font_list->fonts); + free (font_list); + } + /* This is to avoid freeing rfont again by the later + M17N_OBJECT_UNREF (p) */ + MPLIST_KEY (p) = Mt; + } p = MPLIST_PLIST (pl); M17N_OBJECT_UNREF (p); } @@ -399,8 +420,16 @@ free_realized_fontset_elements (MRealizedFontset *realized) MPLIST_DO (plist, realized->per_charset) { MPLIST_DO (pl, MPLIST_PLIST (plist)) - if ((rfont = MPLIST_VAL (pl)) && ! rfont->frame) - free (rfont); + { + font = MPLIST_VAL (pl); + if (font->type == MFONT_TYPE_OBJECT) + { + font_list = (MFontList *) font; + free (font_list->fonts); + free (font_list); + } + MPLIST_KEY (pl) = Mt; + } pl = MPLIST_PLIST (plist); M17N_OBJECT_UNREF (pl); } @@ -409,8 +438,16 @@ free_realized_fontset_elements (MRealizedFontset *realized) if (realized->fallback) { MPLIST_DO (plist, realized->fallback) - if ((rfont = MPLIST_VAL (plist)) && ! rfont->frame) - free (rfont); + { + font = MPLIST_VAL (plist); + if (font->type == MFONT_TYPE_OBJECT) + { + font_list = (MFontList *) font; + free (font_list->fonts); + free (font_list); + } + MPLIST_KEY (plist) = Mt; + } M17N_OBJECT_UNREF (realized->fallback); } } @@ -419,8 +456,7 @@ static void update_fontset_elements (MRealizedFontset *realized) { free_realized_fontset_elements (realized); - realize_fontset_elements (realized->frame, realized, realized->fontset, - &realized->spec); + realize_fontset_elements (realized->frame, realized); } @@ -431,6 +467,8 @@ update_fontset_elements (MRealizedFontset *realized) int mfont__fontset_init () { + M17N_OBJECT_ADD_ARRAY (fontset_table, "Fontset"); + Mfontset = msymbol ("fontset"); Mfontset->managing_key = 1; fontset_list = mplist (); @@ -454,15 +492,14 @@ mfont__fontset_init () void mfont__fontset_fini () { - while (! MPLIST_TAIL_P (fontset_list)) - free_fontset ((MFontset *) MPLIST_VAL (fontset_list)); - M17N_OBJECT_UNREF (fontset_list); - fontset_list = NULL; + M17N_OBJECT_UNREF (default_fontset); + default_fontset = NULL; } MRealizedFontset * -mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face) +mfont__realize_fontset (MFrame *frame, MFontset *fontset, + MFace *face, MFont *spec) { MRealizedFontset *realized; MFont request; @@ -471,22 +508,36 @@ mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face) if (fontset->mdb) load_fontset_contents (fontset); + MFONT_INIT (&request); mfont__set_spec_from_face (&request, face); - if (request.property[MFONT_SIZE] <= 0) + if (request.size <= 0) { mdebug_hook (); - request.property[MFONT_SIZE] = 120; + request.size = 120; } MPLIST_DO (plist, frame->realized_fontset_list) { realized = (MRealizedFontset *) MPLIST_VAL (plist); if (fontset->name == MPLIST_KEY (plist) - && ! memcmp (&request, &realized->spec, sizeof (request))) + && ! memcmp (&request, &realized->request, sizeof (MFont)) + && (realized->spec + ? (spec && ! memcmp (spec, &realized->spec, sizeof (MFont))) + : ! spec)) return realized; } - MSTRUCT_MALLOC (realized, MERROR_FONTSET); - realize_fontset_elements (frame, realized, fontset, &request); + MSTRUCT_CALLOC (realized, MERROR_FONTSET); + realized->fontset = fontset; + M17N_OBJECT_REF (fontset); + realized->tick = fontset->tick; + if (spec) + { + MSTRUCT_CALLOC (realized->spec, MERROR_FONTSET); + *realized->spec = *spec; + } + realized->request = request; + realized->frame = frame; + realize_fontset_elements (frame, realized); mplist_add (frame->realized_fontset_list, fontset->name, realized); return realized; } @@ -496,134 +547,429 @@ void mfont__free_realized_fontset (MRealizedFontset *realized) { free_realized_fontset_elements (realized); + M17N_OBJECT_UNREF (realized->fontset); + if (realized->spec) + free (realized->spec); free (realized); } +static MRealizedFont * +try_font_list (MFrame *frame, MFontList *font_list, MFont *request, + MSymbol layouter, MGlyph *g, int *num, int all, int exact) +{ + int i, j; + MFont *font; + MRealizedFont *rfont; + + for (i = 0; i < font_list->nfonts; i++) + { + if (font_list->fonts[i].font->type == MFONT_TYPE_SPEC) + MFATAL (MERROR_FONT); + if (exact) + { + if (font_list->fonts[i].score > 0) + break; + } + else + { + if (font_list->fonts[i].score == 0) + continue; + } + font = font_list->fonts[i].font; + if (font->type == MFONT_TYPE_FAILURE) + continue; + /* Check if this font can display all glyphs. */ + for (j = 0; j < *num; j++) + { + int c = g[j].type == GLYPH_CHAR ? g[j].g.c : ' '; + MFLT *flt; + MCharTable *coverage; + + if (layouter != Mt + ? ((flt = mflt_get (layouter)) + ? (coverage = mflt_coverage (flt), + ! mchartable_lookup (coverage, c)) + : 0) + : ! mfont__has_char (frame, font, &font_list->object, c)) + break; + } + if (j == 0 && *num > 0) + continue; + if (j == *num || !all) + { + MCharTable *coverage = NULL; + + /* We found a font that can display the requested range of + glyphs. */ + if (font->type == MFONT_TYPE_REALIZED) + rfont = (MRealizedFont *) font; + else + { + rfont = mfont__open (frame, font, &font_list->object); + if (! rfont) + continue; + font_list->fonts[i].font = (MFont *) rfont; + } + rfont->layouter = layouter == Mt ? Mnil : layouter; + if (rfont->layouter) + { + MFLT *flt = mflt_get (rfont->layouter); + + if (flt) + coverage = mflt_coverage (flt); + } + *num = j; + for (j = 0; j < *num; j++) + { + int c = g[j].type == GLYPH_CHAR ? g[j].g.c : ' '; + + g[j].g.code = (coverage + ? (unsigned ) mchartable_lookup (coverage, c) + : mfont__encode_char (frame, (MFont *) rfont, + &font_list->object, c)); + } + return rfont; + } + } + return NULL; +} + + +static MRealizedFont * +try_font_group (MRealizedFontset *realized, MFont *request, + MPlist *font_group, MGlyph *g, int *num, int size) +{ + MFrame *frame = realized->frame; + MFont *font; + MFontList *font_list; + MRealizedFont *rfont; + MPlist *plist; + MSymbol layouter; + int best_score = -1, worst_score; + + for (plist = font_group; ! MPLIST_TAIL_P (plist); ) + { + int this_score; + + layouter = MPLIST_KEY (plist); + font = MPLIST_VAL (plist); + if (font->type == MFONT_TYPE_SPEC) + { + /* We have not yet made this entry a MFontList. */ + if (realized->spec) + { + MFont this = *font; + + if (mfont__merge (&this, realized->spec, 1) < 0) + { + mplist_pop (plist); + continue; + } + font_list = mfont__list (frame, &this, &this, size); + } + else + font_list = mfont__list (frame, font, request, size); + if (! font_list) + { + /* As there's no font matching this spec, remove this + element from the font group. */ + mplist_pop (plist); + continue; + } + MPLIST_VAL (plist) = font_list; + } + else + font_list = (MFontList *) font; + + this_score = font_list->fonts[0].score; + if ((this_score == 0) + && (rfont = try_font_list (frame, font_list, request, + layouter, g, num, 1, 1))) + return rfont; + if (best_score < 0) + { + best_score = worst_score = this_score; + plist = MPLIST_NEXT (plist); + } + else if (this_score >= worst_score) + { + worst_score = this_score; + plist = MPLIST_NEXT (plist); + } + else + { + MPlist *pl; + + MPLIST_DO (pl, font_group) + if (this_score < ((MFontList *) MPLIST_VAL (pl))->fonts[0].score) + break; + mplist_pop (plist); + mplist_push (pl, layouter, font_list); + } + } + + /* We couldn't find an exact matching font that can display all + glyphs. Find one that can at least display all glyphs. */ + MPLIST_DO (plist, font_group) + { + rfont = try_font_list (frame, MPLIST_VAL (plist), request, + MPLIST_KEY (plist), g, num, 1, 0); + if (rfont) + return rfont; + } + + /* We couldn't find a font that can display all glyphs. Find an + exact matching font that can at least display the first + glyph. */ + MPLIST_DO (plist, font_group) + { + rfont = try_font_list (frame, MPLIST_VAL (plist), request, + MPLIST_KEY (plist), g, num, 0, 1); + if (rfont) + return rfont; + } + + /* Find any font that can at least display the first glyph. */ + MPLIST_DO (plist, font_group) + { + rfont = try_font_list (frame, MPLIST_VAL (plist), request, + MPLIST_KEY (plist), g, num, 0, 0); + if (rfont) + return rfont; + } + + return NULL; +} + MRealizedFont * mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num, MSymbol script, MSymbol language, MSymbol charset, - int size) + int size, int ignore_fallback) { - 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 (MDEBUG_FLAG ()) + { + int i; + + MDEBUG_PRINT1 (" [FONTSET] fontset looking up for %s:", + script ? script->name : "none"); + for (i = 0; i < *num; i++) + MDEBUG_PRINT1 (" U+%04X", g[i].g.c); + MDEBUG_PRINT ("\n"); + } 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; - if (script != Mnil - && ((per_script = mplist_find_by_key (realized->per_script, script)) - != NULL)) + && (per_charset = mplist_get (realized->per_charset, charset)) != NULL + && (rfont = try_font_group (realized, &realized->request, per_charset, + g, num, size))) + goto done; + + if (script != Mnil) { + MFont request = realized->request; + + if (script != Mlatin) + /* This is not appropriate for non-Latin scripts. */ + request.property[MFONT_REGISTRY] = 0; + + per_script = mplist_get (realized->per_script, script); + if (! per_script) + { + per_script = mplist_copy (get_per_script (realized->fontset, script)); + /* PER_SCRIPT ::= (LANGUAGE:(LAYOUTER:FONT-SPEC ...) ...) */ + MPLIST_DO (plist, per_script) + MPLIST_VAL (plist) = mplist_copy (MPLIST_VAL (plist)); + mplist_add (realized->per_script, script, per_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, &request, per_lang, + g, num, size))) + goto done; + + if (per_lang && *num > 1) + *num = 1; + 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, &request, + MPLIST_PLIST (plist), + g, num, size))) + goto done; } - 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, &request, per_lang, + g, num, size))) + goto done; + + if (per_lang && *num > 1) + *num = 1; + /* Then try the above (3) */ + MPLIST_DO (plist, per_script) + if (MPLIST_KEY (plist) != language + && MPLIST_KEY (plist) != Mt + && (rfont = try_font_group (realized, &request, + MPLIST_PLIST (plist), + g, num, size))) + goto done; } - 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); + if (ignore_fallback) + goto done; } - font_groups[n_font_group++] = realized->fallback; - if (n_font_group == 1) + if (language != Mnil) + /* Find a font group for this language from all scripts. */ + MPLIST_DO (plist, realized->per_script) + { + MFont request = realized->request; + + if (MPLIST_KEY (plist) != Mlatin) + request.property[MFONT_FOUNDRY] + = request.property[MFONT_FAMILY] + = request.property[MFONT_FAMILY] = 0; + if ((per_lang = mplist_get (MPLIST_PLIST (plist), language)) + && (rfont = try_font_group (realized, &request, per_lang, + g, num, size))) + goto done; + } + + /* Try fallback fonts. */ + rfont = try_font_group (realized, &realized->request, + realized->fallback, g, num, size); + done: + if (MDEBUG_FLAG ()) { - /* 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); + if (rfont) + { + MSymbol family = mfont_get_prop (rfont->font, Mfamily); + MDEBUG_PRINT1 (" [FONTSET] found %s\n", family->name); + } + else + MDEBUG_PRINT (" [FONTSET] not found\n"); } - 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); + return rfont; +} - 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; - } +MRealizedFont * +get_font_from_group (MFrame *frame, MPlist *plist, MFont *font) +{ + MRealizedFont *rfont; + + MPLIST_DO (plist, plist) + { + MFont spec = *(MFont *) MPLIST_VAL (plist); + if (mfont__merge (&spec, font, 1) < 0) + continue; + if (font->type == MFONT_TYPE_SPEC) + rfont = (MRealizedFont *) mfont_find (frame, &spec, NULL, 0); + else if (font->type == MFONT_TYPE_OBJECT) + rfont = mfont__open (frame, font, &spec); + else + rfont = (MRealizedFont *) font; + if (rfont + && (spec.capability == Mnil + || mfont__check_capability (rfont, spec.capability) == 0)) + { + rfont->layouter + = MPLIST_KEY (plist) == Mt ? Mnil : MPLIST_KEY (plist); + return rfont; } - if (! MPLIST_TAIL_P (plist)) - break; } + return NULL; +} - if (i < n_font_group) - return rfont; +MRealizedFont * +mfontset__get_font (MFrame *frame, MFontset *fontset, + MSymbol script, MSymbol language, MFont *font, + int *best) +{ + MPlist *per_script, *per_lang; + MRealizedFont *rfont; + + if (best) + *best = 0; - /* 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++) + if (language == Mnil) + language = Mt; + + if (script != Mnil) { - MPLIST_DO (plist, font_groups[i]) + per_script = get_per_script (fontset, script); + if ((per_lang = mplist_get (per_script, language)) + && (rfont = get_font_from_group (frame, per_lang, font))) { - 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 (best) + *best = 1; + return rfont; + } + if (best) + *best = per_lang ? 0 : 1; + if (language == Mt) + { + MPLIST_DO (per_script, per_script) + if (MPLIST_KEY (per_script) != language + && (rfont = get_font_from_group (frame, + MPLIST_PLIST (per_script), + font))) + return rfont; + } + else + { + if ((per_lang = mplist_get (per_script, Mt)) + && (rfont = get_font_from_group (frame, per_lang, font))) + return rfont; + if (best) + *best = 0; + MPLIST_DO (per_script, per_script) + if (MPLIST_KEY (per_script) != language + && MPLIST_KEY (per_script) != Mt + && (rfont = get_font_from_group (frame, + MPLIST_PLIST (per_script), + font))) + return rfont; } - if (! MPLIST_TAIL_P (plist)) - break; } - return (i < n_font_group ? rfont : NULL); + + if (language != Mt) + MPLIST_DO (per_script, fontset->per_script) + { + if ((per_lang = mplist_get (MPLIST_PLIST (per_script), language)) + && (rfont = get_font_from_group (frame, per_lang, font))) + { + if (best) + *best = 1; + return rfont; + } + } + + if (best) + *best = 0; + if ((rfont = get_font_from_group (frame, fontset->fallback, font))) + return rfont; + return NULL; } + /*** @} */ #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ @@ -657,18 +1003,16 @@ mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num, /***ja @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊÖ¤¹. - ´Ø¿ô mfontset () ¤Ï̾Á° $NAME ¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î - ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ $NAME ¤¬ @c NULL ¤Ê¤é¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È - ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ + ´Ø¿ô mfontset () ¤Ï̾Á° $NAME ¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ + $NAME ¤¬ @c NULL ¤Ê¤é¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ - $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¤¬¤Ê¤±¤ì¤Ð¡¢¿·¤·¤¤¤â¤Î¤¬ºî¤é¤ì - ¤ë¡£¤½¤ÎºÝ¡¢m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë \<@c fontset, $NAME\> ¤È¤¤¤¦¥Ç¡¼¥¿ - ¤¬¤¢¤ì¤Ð¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï¤½¤Î¥Ç¡¼¥¿¤Ë±è¤Ã¤Æ½é´ü²½¤µ¤ì¤ë¡£¤Ê¤±¤ì¤Ð¡¢ - ¶õ¤Î¤Þ¤Þ¤Ë¤µ¤ì¤ë¡£ + $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¤¬¤Ê¤±¤ì¤Ð¡¢¿·¤·¤¤¤â¤Î¤¬ºî¤é¤ì¤ë¡£¤½¤ÎºÝ¡¢ + m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë \<@c fontset, $NAME\> + ¤È¤¤¤¦¥Ç¡¼¥¿¤¬¤¢¤ì¤Ð¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï¤½¤Î¥Ç¡¼¥¿¤Ë±è¤Ã¤Æ½é´ü²½¤µ¤ì¤ë¡£ + ¤Ê¤±¤ì¤Ð¡¢¶õ¤Î¤Þ¤Þ¤Ë¤µ¤ì¤ë¡£ - ¥Þ¥¯¥í M17N_INIT () ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤òºî¤ë¡£¥¢¥×¥ê¥±¡¼ - ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï mframe () ¤ò½é¤á¤Æ¸Æ¤Ö¤Þ¤Ç¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È - ¥»¥Ã¥È¤òÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ + ¥Þ¥¯¥í M17N_INIT () ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤òºî¤ë¡£¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï + mframe () ¤ò½é¤á¤Æ¸Æ¤Ö¤Þ¤Ç¤Î´Ö¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£ @return ¤³¤Î´Ø¿ô¤Ï¸«¤Ä¤«¤Ã¤¿¡¢¤¢¤ë¤¤¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ @@ -681,14 +1025,20 @@ mfontset (char *name) MFontset *fontset; if (! name) - fontset = default_fontset; + { + fontset = default_fontset; + M17N_OBJECT_REF (fontset); + } else { sym = msymbol (name); fontset = mplist_get (fontset_list, sym); - if (! fontset) + if (fontset) + M17N_OBJECT_REF (fontset); + else { M17N_OBJECT (fontset, free_fontset, MERROR_FONTSET); + M17N_OBJECT_REGISTER (fontset_table, fontset); fontset->name = sym; fontset->mdb = mdatabase_find (Mfontset, sym, Mnil, Mnil); if (! fontset->mdb) @@ -700,7 +1050,6 @@ mfontset (char *name) mplist_put (fontset_list, sym, fontset); } } - M17N_OBJECT_REF (fontset); return fontset; } @@ -732,9 +1081,9 @@ mfontset_name (MFontset *fontset) /***ja @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥³¥Ô¡¼¤òºî¤ë. - ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢ - ̾Á° $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME ¤Ï´û¸¤Î - ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º + ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢Ì¾Á° + $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME + ¤Ï´û¸¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º¤Ë NULL ¤òÊÖ¤¹¡£ */ MFontset * @@ -742,40 +1091,62 @@ mfontset_copy (MFontset *fontset, char *name) { MSymbol sym = msymbol (name); MFontset *copy = mplist_get (fontset_list, sym); - MPlist *plist, *pl; + MPlist *plist, *pl, *p; if (copy) return NULL; M17N_OBJECT (copy, free_fontset, MERROR_FONTSET); + M17N_OBJECT_REGISTER (fontset_table, copy); copy->name = sym; + if (fontset->mdb) + load_fontset_contents (fontset); + if (fontset->per_script) { copy->per_script = mplist (); MPLIST_DO (plist, fontset->per_script) { - MPlist *new = mplist (); + MPlist *per_lang = mplist (); + mplist_add (copy->per_script, MPLIST_KEY (plist), per_lang); MPLIST_DO (pl, MPLIST_PLIST (plist)) - mplist_add (new, MPLIST_KEY (pl), mplist_copy (MPLIST_PLIST (pl))); - mplist_add (copy->per_script, MPLIST_KEY (plist), new); + { + MPlist *font_group = mplist (); + + per_lang = mplist_add (per_lang, MPLIST_KEY (pl), font_group); + MPLIST_DO (p, MPLIST_PLIST (pl)) + font_group = mplist_add (font_group, MPLIST_KEY (p), + mfont_copy (MPLIST_VAL (p))); + } } } if (fontset->per_charset) { - copy->per_charset = mplist (); - MPLIST_DO (plist, fontset->per_charset) - mplist_add (copy->per_charset, MPLIST_KEY (plist), - mplist_copy (MPLIST_PLIST (plist))); + MPlist *per_charset = mplist (); + + copy->per_charset = per_charset; + MPLIST_DO (pl, fontset->per_charset) + { + MPlist *font_group = mplist (); + + per_charset = mplist_add (per_charset, MPLIST_KEY (pl), font_group); + MPLIST_DO (p, MPLIST_PLIST (pl)) + font_group = mplist_add (font_group, MPLIST_KEY (p), + mfont_copy (MPLIST_VAL (p))); + } } if (fontset->fallback) - copy->fallback = mplist_copy (fontset->fallback); + { + MPlist *font_group = mplist (); - copy->font_spec_list = fontset->font_spec_list; - M17N_OBJECT_REF (copy->font_spec_list); + copy->fallback = font_group; + MPLIST_DO (p, fontset->fallback) + font_group = mplist_add (font_group, MPLIST_KEY (p), + mfont_copy (MPLIST_VAL (p))); + } mplist_put (fontset_list, sym, copy); - M17N_OBJECT_REF (copy); return copy; } @@ -816,10 +1187,10 @@ mfontset_copy (MFontset *fontset, char *name) only available font for the associated item; all the other fonts are removed from the group. - If $LAYOUTER_NAME is not @c Mnil, it must be a symbol - representing a @ref flt. In that case, if $FONT is selected for - drawing an M-text, that font layout table is used to generate a - glyph code sequence from a character sequence. + If $LAYOUTER_NAME is not @c Mnil, it must be a symbol representing + a @ref mdbFLT (font layout table). In that case, if $FONT is + selected for drawing an M-text, that font layout table is used to + generate a glyph code sequence from a character sequence. @return If the operation was successful, mfontset_modify_entry () returns 0. @@ -829,43 +1200,38 @@ mfontset_copy (MFontset *fontset, char *name) /***ja @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ÎÆâÍƤòÊѹ¹¤¹¤ë. - ´Ø¿ô mfontset_modify_entry () ¤Ï¡¢$LANGUAGE ¤È $SCRIPT ¤ÎÁȤ߹ç¤ï - ¤»¤Þ¤¿¤Ï $CHARSET ¤ËÂФ·¤Æ $FONT ¤Î¥³¥Ô¡¼¤ò»È¤¦¤è¤¦¤Ë¡¢¥Õ¥©¥ó¥È¥»¥Ã - ¥È $FONTSET ¤òÀßÄꤹ¤ë¡£ + ´Ø¿ô mfontset_modify_entry () ¤Ï¡¢$LANGUAGE ¤È $SCRIPT ¤ÎÁȤ߹ç¤ï¤»¡¢¤Þ¤¿¤Ï + $CHARSET ¤ËÂФ·¤Æ $FONT ¤Î¥³¥Ô¡¼¤ò»È¤¦¤è¤¦¤Ë¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤òÀßÄꤹ¤ë¡£ - ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î³Æ¥Õ¥©¥ó¥È¤Ï¡¢ÆÃÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤Î¥Ú¥¢¡¢ÆÃÄê¤Î - ʸ»ú¥»¥Ã¥È¡¢¥·¥ó¥Ü¥ë @c Mnil ¤Î¤¤¤º¤ì¤«¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¡£Æ±¤¸ - ¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤ò¹½À®¤¹¤ë¡£ + ¥Õ¥©¥ó¥È¥»¥Ã¥ÈÃæ¤Î³Æ¥Õ¥©¥ó¥È¤Ï¡¢ÆÃÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤Î¥Ú¥¢¡¢ÆÃÄê¤Îʸ»ú¥»¥Ã¥È¡¢¥·¥ó¥Ü¥ë + @c Mnil ¤Î¤¤¤º¤ì¤«¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¡£Æ±¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤ò¹½À®¤¹¤ë¡£ $SCRIPT ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥¹¥¯¥ê¥×¥È¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢$LANGUAGE ¤Ï¸À¸ì¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤« @c Mnil ¤Ç¤¢¤ê¡¢$FONT ¤Ïthe $SCRIPT / $LANGUAGE ¥Ú¥¢¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£ - $CHARSET ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢Ê¸»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¥·¥ó¥Ü¥ë - ¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï $FONT ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤È´ØÏ¢ÉÕ¤±¤é¤ì - ¤ë¡£ + $CHARSET ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢Ê¸»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ + ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï $FONT ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£ - $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï $FONT ¤Î¥³¥Ô¡¼ - ¤¬£²¤Äºî¤é¤ì¡¢¤½¤ì¤¾¤ì $SCRIPT / $LANGUAGE ¥Ú¥¢¤Èʸ»ú¥»¥Ã¥È¤Ë´ØÏ¢ - ÉÕ¤±¤é¤ì¤ë¡£ + $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï $FONT + ¤Î¥³¥Ô¡¼¤¬£²¤Äºî¤é¤ì¡¢¤½¤ì¤¾¤ì $SCRIPT / $LANGUAGE + ¥Ú¥¢¤Èʸ»ú¥»¥Ã¥È¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£ - $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ $FONT ¤Ï @c Mnil ¤È - ´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£¤³¤Î¼ï¤Î¥Õ¥©¥ó¥È¤Ï @e fallback @e font ¤È¸Æ¤Ð¤ì¤ë¡£ + $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ $FONT ¤Ï @c Mnil + ¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£¤³¤Î¼ï¤Î¥Õ¥©¥ó¥È¤Ï @e fallback @e font ¤È¸Æ¤Ð¤ì¤ë¡£ - °ú¿ô $HOW ¤Ï $FONT ¤ÎÍ¥ÀèÅÙ¤ò»ØÄꤹ¤ë¡£$HOW ¤¬Àµ¤Ê¤é¤Ð¡¢$FONT ¤ÏƱ - ¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥°¥ë¡¼¥×Ãæ¤ÇºÇ¹â¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬Éé¤Ê - ¤é¤Ð¡¢ºÇÄã¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬ 0 ¤Ê¤é¤Ð¡¢$FONT ¤Ï´ØÏ¢ÉÕ¤±¤é¤ì¤¿ - ¤â¤Î¤ËÂФ¹¤ëÍ£°ì¤ÎÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤È¤Ê¤ê¡¢Â¾¤Î¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥× - ¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£ + °ú¿ô $HOW ¤Ï $FONT ¤ÎÍ¥ÀèÅÙ¤ò»ØÄꤹ¤ë¡£$HOW ¤¬Àµ¤Ê¤é¤Ð¡¢$FONT + ¤ÏƱ¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥°¥ë¡¼¥×Ãæ¤ÇºÇ¹â¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW + ¤¬Éé¤Ê¤é¤Ð¡¢ºÇÄã¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬ 0 ¤Ê¤é¤Ð¡¢$FONT + ¤Ï´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤â¤Î¤ËÂФ¹¤ëÍ£°ì¤ÎÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤È¤Ê¤ê¡¢Â¾¤Î¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£ - $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref flt ¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ - ¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢$FONT ¤òÍѤ¤¤ÆM-text ¤òɽ¼¨¤¹¤ëºÝ¤Ë¤Ï¡¢¤½¤Î FONT - LAYOUT TABLE ¤ò»È¤Ã¤Æʸ»úÎ󤫤饰¥ê¥Õ¥³¡¼¥ÉÎó¤òÀ¸À®¤¹¤ë¡£ + $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref mdbFLT + ¡Ê¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¡Ë¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢$FONT ¤òÍѤ¤¤Æ + M-text ¤òɽ¼¨¤¹¤ëºÝ¤Ë¤Ï¡¢¤½¤Î¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤ò»È¤Ã¤Æʸ»úÎ󤫤饰¥ê¥Õ¥³¡¼¥ÉÎó¤òÀ¸À®¤¹¤ë¡£ @return ½èÍý¤¬À®¸ù¤·¤¿¤È¤­¡¢mfontset_modify_entry () ¤Ï 0 ¤òÊÖ¤¹¡£ - ¼ºÇÔ¤·¤¿¤È¤­¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò - ÀßÄꤹ¤ë¡£ */ + ¼ºÇÔ¤·¤¿¤È¤­¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */ /*** @errors @@ -877,31 +1243,13 @@ mfontset_modify_entry (MFontset *fontset, MFont *spec, MSymbol layouter_name, int how) { - MPlist *per_lang, *plist[3], *pl; + MPlist *per_lang, *plist[3]; MFont *font = NULL; int i; if (fontset->mdb) load_fontset_contents (fontset); - if (! fontset->font_spec_list) - fontset->font_spec_list = mplist (); - else - MPLIST_DO (pl, fontset->font_spec_list) - { - if (! memcmp (MPLIST_VAL (pl), spec, sizeof (MFont))) - { - font = MPLIST_VAL (pl); - break; - } - } - if (! font) - { - font = mfont (); - *font = *spec; - mplist_add (fontset->font_spec_list, Mt, font); - } - i = 0; if (script != Mnil) { @@ -931,12 +1279,18 @@ mfontset_modify_entry (MFontset *fontset, layouter_name = Mt; for (i--; i >= 0; i--) { + font = mfont_copy (spec); + font->type = MFONT_TYPE_SPEC; if (how == 1) mplist_push (plist[i], layouter_name, font); else if (how == -1) mplist_add (plist[i], layouter_name, font); else { + MPlist *pl; + + MPLIST_DO (pl, plist[i]) + free (MPLIST_VAL (pl)); mplist_set (plist[i], Mnil, NULL); mplist_add (plist[i], layouter_name, font); } @@ -958,37 +1312,78 @@ mfontset_modify_entry (MFontset *fontset, If $SCRIPT is @c Mt, keys of the returned plist are script name symbols for which some fonts are specified and values are NULL. - If $SCIRPT is a script symbol, the returned plist is decided by - $LANGUAGE. + If $SCRIPT is a script name symbol, the returned plist is decided + by $LANGUAGE. + + @li If $LANGUAGE is @c Mt, keys of the plist are language name + symbols for which some fonts are specified and values are NULL. A + key may be @c Mt which means some fallback fonts are specified for + the script. - If $LANGUAGE is @c Mt, keys of the plist are language name symbols - for which some fonts are specified and values are NULL. A key may - be @c Mt which means some fallback fonts are specified for the - script. + @li If $LANGUAGE is a language name symbol, the plist is a @c + FONT-GROUP for the specified script and language. @c FONT-GROUP + is a plist whose keys are FLT (FontLayoutTable) name symbols (@c + Mt if no FLT is associated with the font) and values are pointers + to #MFont. - If $LANGUAGE is a language name symbol, the plist is a @c - FONT-GROUP for the specified script and langauge. - - If $LANGAUGE is @c Mt, the plist is fallback @c FONT-GROUP for the - script. + @li If $LANGUAGE is @c Mnil, the plist is fallback @c FONT-GROUP + for the script. If $SCRIPT is @c Mnil, the returned plist is decided as below. - If $CHARSET is @c Mt, keys of the returned plist are charset name + @li If $CHARSET is @c Mt, keys of the returned plist are charset name symbols for which some fonts are specified and values are NULL. - If $CHARSET is a charset symbol, the plist is a @c FONT-GROUP for + @li If $CHARSET is a charset name symbol, the plist is a @c FONT-GROUP for the charset. - If $CHARSET is @c Mnil, the plist is a fallback @c FONT-GROUP. - - @c FONT-GROUP is a plist whose keys are FLT name symbols (@c Mt if - no FLT is associated with the font) and values are pointers to - #MFont. + @li If $CHARSET is @c Mnil, the plist is a fallback @c FONT-GROUP. @return It returns a plist describing the contents of a fontset. The plist should be freed by m17n_object_unref (). */ +/***ja + @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¸¡º÷¤¹¤ë. + + ´Ø¿ô mfontset_lookup () ¤Ï $FONTSET ¤ò¸¡º÷¤·¡¢$FONTSET + ¤ÎÆâÍƤΤ¦¤Á»ØÄꤷ¤¿¥¹¥¯¥ê¥×¥È¡¢¸À¸ì¡¢Ê¸»ú¥»¥Ã¥È¤ËÂбþ¤¹¤ëÉôʬ¤òɽ¤¹ + plist ¤òÊÖ¤¹¡£ + + $SCRIPT ¤¬ @c Mt ¤Ê¤é¤Ð¡¢ÊÖ¤¹ plist + ¤Î¥­¡¼¤Ï¥Õ¥©¥ó¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¥¹¥¯¥ê¥×¥È̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃÍ¤Ï + NULL ¤Ç¤¢¤ë¡£ + + $SCRIPT ¤¬¥¹¥¯¥ê¥×¥È̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢ÊÖ¤¹ + plist ¤Ï $LANGUAGE¤Ë¤è¤Ã¤ÆÄê¤Þ¤ë¡£ + + @li $LANGUAGE ¤¬ @c Mt ¤Ê¤é¤Ð¡¢plist + ¤Î¥­¡¼¤Ï¥Õ¥©¥ó¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¸À¸ì̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃÍ¤Ï + NULL ¤Ç¤¢¤ë¡£¥­¡¼¤Ï @c Mt + ¤Ç¤¢¤ë¤³¤È¤â¤¢¤ê¡¢¤½¤Î¾ì¹ç¤½¤Î¥¹¥¯¥ê¥×¥È¤Ë¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯¥Õ¥©¥ó¥È¤¬¤¢¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ + + @li $LANGUAGE ¤¬¸À¸ì̾¤Î¥·¥ó¥Ü¥ë¤Ê¤é¤Ð¡¢plist ¤Ï»ØÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤ËÂФ¹¤ë + @c FONT-GROUP ¤Ç¤¢¤ë¡£@c FONT-GROUP ¤È¤Ï¡¢¥­¡¼¤¬ FLT + (FontLayoutTable) ̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢Ãͤ¬ #MFont + ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê plist ¤Ç¤¢¤ë¡£¤¿¤À¤·¥Õ¥©¥ó¥È¤Ë FLT + ¤¬ÂбþÉÕ¤±¤é¤ì¤Æ¤¤¤Ê¤¤»þ¤Ë¤Ï¡¢¥­¡¼¤Ï @c Mt ¤Ë¤Ê¤ë¡£ + + @li $LANGUAGE ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢plist ¤Ï¤½¤Î¥¹¥¯¥ê¥×¥ÈÍѤΥե©¡¼¥ë¥Ð¥Ã¥¯ + @c FONT-GROUP ¤Ç¤¢¤ë¡£ + + $SCRIPT ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ÊÖ¤¹ plist ¤Ï°Ê²¼¤Î¤è¤¦¤ËÄê¤Þ¤ë¡£ + + @li $CHARSET ¤¬ @c Mt ¤Ê¤é¤Ð¡¢plist + ¤Î¥­¡¼¤Ï¥Õ¥©¥ó¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤ëʸ»ú¥»¥Ã¥È̾¤Î¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃÍ¤Ï + NULL ¤Ç¤¢¤ë¡£ + + @li $CHARSET ¤¬Ê¸»ú¥»¥Ã¥È̾¤Î¥·¥ó¥Ü¥ë¤Ê¤é¤Ð¡¢plist ¤Ï¤½¤Îʸ»ú¥»¥Ã¥ÈÍѤΠ+ @c FONT-GROUP ¤Ç¤¢¤ë¡£ + + @li $CHARSET ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢plist ¤Ï¥Õ¥©¡¼¥ë¥Ð¥Ã¥¯ @c FONT-GROUP ¤Ç¤¢¤ë¡£ + + @return + ¤³¤Î´Ø¿ô¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È¤ÎÆâÍƤòɽ¤¹ plist ¤òÊÖ¤¹¡£ + plist ¤Ï m17n_object_unref () ¤Ç²òÊü¤µ¤ì¤ë¤Ù¤­¤Ç¤¢¤ë¡£ */ MPlist * mfontset_lookup (MFontset *fontset, @@ -1009,10 +1404,8 @@ mfontset_lookup (MFontset *fontset, } if (script != Mnil) { - if (! fontset->per_script) - return plist; - pl = mplist_get (fontset->per_script, script); - if (! pl) + pl = get_per_script (fontset, script); + if (MPLIST_TAIL_P (pl)) return plist; if (language == Mt) { @@ -1064,9 +1457,8 @@ mfontset_lookup (MFontset *fontset, /***ja @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¥À¥ó¥×¤¹¤ë. - ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr ¤Ë¿Í - ´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ - ¤ë¡£ + ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr + ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£ @return ¤³¤Î´Ø¿ô¤Ï $FONTSET ¤òÊÖ¤¹¡£ */ @@ -1090,7 +1482,8 @@ mdebug_dump_fontset (MFontset *fontset, int indent) fprintf (stderr, "\n %s(%s", prefix, MPLIST_KEY (pl)->name); MPLIST_DO (p, MPLIST_PLIST (pl)) { - fprintf (stderr, "\n %s(%s ", prefix, + fprintf (stderr, "\n %s(0x%X %s ", prefix, + (unsigned) MPLIST_VAL (p), MPLIST_KEY (p)->name); mdebug_dump_font (MPLIST_VAL (p)); fprintf (stderr, ")");