/* 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
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
@brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ïʸ»ú¤«¤é¥Õ¥©¥ó¥È¤Ø¤ÎÂбþÉÕ¤±¤ò¹Ô¤¦¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë.
- @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£M-text ¤ò
- ɽ¼¨¤¹¤ëºÝ¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï M-text Ãæ¤Î¸Ä¡¹¤Îʸ»ú¤ËÂФ·¤Æ¤É¤Î¥Õ¥©
- ¥ó¥È¤òÍѤ¤¤ë¤«¤Îµ¬Â§¤ò¡¢°Ê²¼¤Î¾ðÊó¤Ë½¾¤Ã¤ÆÍ¿¤¨¤ë¡£
+ @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£M-text
+ ¤Îɽ¼¨¤ÎºÝ¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï°Ê²¼¤Î¾ðÊó¤òÍѤ¤¤Æ M-text
+ Ãæ¤Î¸Ä¡¹¤Îʸ»ú¤Ë¤É¤Î¥Õ¥©¥ó¥È¤òÍѤ¤¤ë¤«·è¤á¤ëµ¬Â§¤òÍ¿¤¨¤ë¡£
@li ʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "¥¹¥¯¥ê¥×¥È"
@li ʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£ "¸À¸ì"
@li ʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£ "ʸ»ú¥»¥Ã¥È"
- ¤³¤ì¤é¤Î¾ðÊ󤬤ɤΤ褦¤ËÍѤ¤¤é¤ì¤ë¤«¤Ï mdraw_text () ¤ÎÀâÌÀ¤ò»²¾È
- ¤Î¤³¤È¡£
+ ¤³¤ì¤é¤Î¾ðÊ󤬤ɤΤ褦¤ËÍѤ¤¤é¤ì¤ë¤«¤Ï mdraw_text () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
*/
#include <string.h>
#include <ctype.h>
+#include "config.h"
#include "m17n-gui.h"
#include "m17n-misc.h"
#include "internal.h"
#include "font.h"
#include "fontset.h"
+static int mdebug_flag = MDEBUG_FONTSET;
+
+static M17NObjectArray fontset_table;
+
struct MFontset
{
M17NObject control;
/* FONT-GROUP */
MPlist *fallback;
-
- /* Plist of Mt vs font specs. */
- MPlist *font_spec_list;
};
static MFontset *default_fontset;
/* Initialized to <fontset>->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;
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))
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. */
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);
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;
{
MPLIST_DO (pl, MPLIST_PLIST (plist))
{
+ MPLIST_DO (p, MPLIST_PLIST (pl))
+ free (MPLIST_VAL (p));
p = MPLIST_PLIST (pl);
M17N_OBJECT_UNREF (p);
}
}
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;
+ MFontset *fontset = realized->fontset;
+ MPlist *per_script, *per_charset, *font_group;
+ MPlist *plist, *p;
- 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;
-
- 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)
{
+ MPlist *pl;
+
per_lang = mplist ();
per_script = mplist_add (per_script, MPLIST_KEY (plist), per_lang);
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)
{
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 (plist))
+ 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)
{
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);
}
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);
}
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);
}
}
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);
}
int
mfont__fontset_init ()
{
+ M17N_OBJECT_ADD_ARRAY (fontset_table, "Fontset");
+
Mfontset = msymbol ("fontset");
Mfontset->managing_key = 1;
fontset_list = mplist ();
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;
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;
}
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].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->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 */
/***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
¤³¤Î´Ø¿ô¤Ï¸«¤Ä¤«¤Ã¤¿¡¢¤¢¤ë¤¤¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
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)
mplist_put (fontset_list, sym, fontset);
}
}
- M17N_OBJECT_REF (fontset);
return fontset;
}
/***ja
@brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
- ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢
- ̾Á° $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME ¤Ï´û¸¤Î
- ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º
+ ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢Ì¾Á°
+ $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME
+ ¤Ï´û¸¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º¤Ë
NULL ¤òÊÖ¤¹¡£ */
MFontset *
{
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;
}
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.
/***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
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)
{
layouter_name = Mt;
for (i--; i >= 0; i--)
{
- if (how == -1)
+ font = mfont_copy (spec);
+ font->type = MFONT_TYPE_SPEC;
+ if (how == 1)
mplist_push (plist[i], layouter_name, font);
- else if (how == 1)
+ 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);
}
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,
}
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)
{
/***ja
@brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¥À¥ó¥×¤¹¤ë.
- ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr ¤Ë¿Í
- ´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ
- ¤ë¡£
+ ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr
+ ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
@return
¤³¤Î´Ø¿ô¤Ï $FONTSET ¤òÊÖ¤¹¡£ */
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, ")");