1 /* fontset.c -- fontset module.
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nFontset
25 @brief A fontset is an object that maps a character to fonts.
27 A @e fontset is an object of the type @c MFontset. When drawing an
28 M-text, a fontset provides rules to select a font for each
29 character in the M-text according to the following information.
31 @li The script character property of a character.
32 @li The language text property of a character.
33 @li The charset text property of a character.
35 The documentation of mdraw_text () describes how that information is
38 /***ja @addtogroup m17nFontset
40 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ïʸ»ú¤«¤é¥Õ¥©¥ó¥È¤Ø¤ÎÂбþÉÕ¤±¤ò¹Ô¤¦¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë.
42 @e ¥Õ¥©¥ó¥È¥»¥Ã¥È ¤Ï @c MFontset ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£M-text ¤ò
43 ɽ¼¨¤¹¤ëºÝ¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï M-text Ãæ¤Î¸Ä¡¹¤Îʸ»ú¤ËÂФ·¤Æ¤É¤Î¥Õ¥©
44 ¥ó¥È¤òÍѤ¤¤ë¤«¤Îµ¬Â§¤ò¡¢°Ê²¼¤Î¾ðÊó¤Ë½¾¤Ã¤ÆÍ¿¤¨¤ë¡£
46 @li ʸ»ú¤Îʸ»ú¥×¥í¥Ñ¥Æ¥£ "¥¹¥¯¥ê¥×¥È"
47 @li ʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£ "¸À¸ì"
48 @li ʸ»ú¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£ "ʸ»ú¥»¥Ã¥È"
50 ¤³¤ì¤é¤Î¾ðÊ󤬤ɤΤ褦¤ËÍѤ¤¤é¤ì¤ë¤«¤Ï mdraw_text () ¤ÎÀâÌÀ¤ò»²¾È
57 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
58 /*** @addtogroup m17nInternal
68 #include "m17n-misc.h"
72 #include "character.h"
74 #include "internal-gui.h"
82 /* Name of the fontset. */
85 /* Initialized to 0, and incremented by one each time the fontset is
89 /* Database from which to load the contents of the fontset. Once
90 loaded, this member is set to NULL. */
93 /* SCRIPT vs PER-LANGUAGE (which is a plist LANGUAGE vs FONT-GROUP) */
96 /* CHARSET vs FONT-GROUP */
102 /* Plist of Mt vs font specs. */
103 MPlist *font_spec_list;
106 static MFontset *default_fontset;
108 static MPlist *fontset_list;
110 struct MRealizedFontset
112 /* Fontset from which the realized fontset is realized. */
115 /* Initialized to <fontset>->tick. */
118 /* Font spec extracted from a face. */
121 /* The frame on which the realized fontset is realized. */
133 load_font_group (MPlist *plist, MPlist *elt, MPlist *spec_list)
137 /* ELT ::= ( FONT-SPEC-LIST [ LAYOUTER ] ) ... */
139 MFont font, *spec = NULL;
140 MSymbol layouter_name;
142 if (! MPLIST_PLIST_P (elt))
143 MWARNING (MERROR_FONTSET);
144 elt2 = MPLIST_PLIST (elt);
145 if (! MPLIST_PLIST_P (elt2))
146 MWARNING (MERROR_FONTSET);
147 mfont__set_spec_from_plist (&font, MPLIST_PLIST (elt2));
148 MPLIST_DO (p, spec_list)
150 if (! memcmp (MPLIST_VAL (p), &font, sizeof (MFont)))
152 spec = MPLIST_VAL (p);
158 MSTRUCT_MALLOC (spec, MERROR_FONTSET);
160 mplist_add (spec_list, Mt, spec);
162 elt2 = MPLIST_NEXT (elt2);
164 if (MPLIST_SYMBOL_P (elt2))
165 layouter_name = MPLIST_SYMBOL (elt2);
166 if (layouter_name == Mnil)
168 plist = mplist_add (plist, layouter_name, spec);
171 /* ANSI-C requires some statement after a label. */
177 /* Load FONTSET->per_script from the data in FONTSET->mdb. */
180 load_fontset_contents (MFontset *fontset)
182 MPlist *per_script, *per_charset, *fallback, *spec_list, *font_group;
183 MSymbol script, lang;
184 MPlist *fontset_def, *plist;
186 fontset->per_script = per_script = mplist ();
187 fontset->per_charset = per_charset = mplist ();
188 fontset->fallback = fallback = mplist ();
189 fontset->font_spec_list = spec_list = mplist ();
190 if (! (fontset_def = (MPlist *) mdatabase_load (fontset->mdb)))
193 MPLIST_DO (plist, fontset_def)
195 /* PLIST ::= ( SCRIPT ( LANGUAGE FONT-SPEC-ELT ... ) ... )
196 | (CHARSET FONT-SPEC-ELT ...)
200 if (! MPLIST_PLIST_P (plist))
201 MWARNING (MERROR_FONTSET);
202 elt = MPLIST_PLIST (plist);
203 if (! MPLIST_SYMBOL_P (elt))
204 MWARNING (MERROR_FONTSET);
205 script = MPLIST_SYMBOL (elt);
206 elt = MPLIST_NEXT (elt);
207 if (! MPLIST_PLIST_P (elt))
208 MWARNING (MERROR_FONTSET);
210 fallback = load_font_group (fallback, elt, spec_list);
211 else if (MPLIST_PLIST_P (MPLIST_PLIST (elt)))
213 font_group = mplist_find_by_key (fontset->per_charset, script);
216 font_group = mplist ();
217 per_charset = mplist_add (per_charset, script, font_group);
219 load_font_group (font_group, elt, spec_list);
223 MPlist *per_lang = mplist_find_by_key (fontset->per_script, script);
227 per_lang = mplist ();
228 per_script = mplist_add (per_script, script, per_lang);
233 /* ELT ::= ( LANGUAGE FONT-DEF ...) ... */
236 if (! MPLIST_PLIST_P (elt))
237 MWARNING (MERROR_FONTSET);
238 elt2 = MPLIST_PLIST (elt);
239 if (! MPLIST_SYMBOL_P (elt2))
240 MWARNING (MERROR_FONTSET);
241 lang = MPLIST_SYMBOL (elt2);
244 font_group = mplist_find_by_key (per_lang, lang);
247 font_group = mplist ();
248 mplist_add (per_lang, lang, font_group);
250 elt2 = MPLIST_NEXT (elt2);
251 load_font_group (font_group, elt2, spec_list);
257 /* ANSI-C requires some statement after a label. */
261 M17N_OBJECT_UNREF (fontset_def);
266 free_fontset (void *object)
268 MFontset *fontset = (MFontset *) object;
269 MPlist *plist, *pl, *p;
271 if (fontset->per_script)
273 MPLIST_DO (plist, fontset->per_script)
275 MPLIST_DO (pl, MPLIST_PLIST (plist))
277 p = MPLIST_PLIST (pl);
278 M17N_OBJECT_UNREF (p);
280 pl = MPLIST_PLIST (plist);
281 M17N_OBJECT_UNREF (pl);
283 M17N_OBJECT_UNREF (fontset->per_script);
285 if (fontset->per_charset)
287 MPLIST_DO (plist, fontset->per_charset)
289 pl = MPLIST_PLIST (plist);
290 M17N_OBJECT_UNREF (pl);
292 M17N_OBJECT_UNREF (fontset->per_charset);
294 if (fontset->fallback)
295 M17N_OBJECT_UNREF (fontset->fallback);
296 plist = mplist_find_by_key (fontset_list, fontset->name);
300 if (fontset->font_spec_list)
302 if (((M17NObject *) (fontset->font_spec_list))->ref_count == 1)
303 MPLIST_DO (plist, fontset->font_spec_list)
304 free (MPLIST_VAL (plist));
305 M17N_OBJECT_UNREF (fontset->font_spec_list);
311 realize_font_group (MFrame *frame, MFont *request, MPlist *font_group,
314 MPlist *plist = MPLIST_VAL (font_group), *pl, *p;
316 mplist_set (font_group, Mnil, NULL);
317 MPLIST_DO (pl, plist)
319 MSymbol layouter = MPLIST_KEY (pl);
320 MFont this_request = *request;
321 MRealizedFont *rfont;
323 mfont__resize (MPLIST_VAL (pl), &this_request);
324 rfont = mfont__select (frame, MPLIST_VAL (pl), &this_request,
325 size, layouter == Mt ? Mnil : layouter);
329 MPLIST_DO (p, font_group)
330 if (((MRealizedFont *) (MPLIST_VAL (p)))->score > rfont->score)
332 mplist_push (p, Mt, rfont);
338 realize_fontset_elements (MFrame *frame, MRealizedFontset *realized,
339 MFontset *fontset, MFont *request)
341 MPlist *per_script, *per_lang, *per_charset, *font_group;
344 realized->fontset = fontset;
345 realized->tick = fontset->tick;
346 realized->spec = *request;
347 realized->frame = frame;
348 realized->per_script = per_script = mplist ();
349 MPLIST_DO (plist, fontset->per_script)
351 per_lang = mplist ();
352 per_script = mplist_add (per_script, MPLIST_KEY (plist), per_lang);
353 MPLIST_DO (pl, MPLIST_PLIST (plist))
355 font_group = mplist ();
356 mplist_add (font_group, Mplist, MPLIST_VAL (pl));
357 per_lang = mplist_add (per_lang, MPLIST_KEY (pl), font_group);
361 realized->per_charset = per_charset = mplist ();
362 MPLIST_DO (plist, fontset->per_charset)
364 font_group = mplist ();
365 mplist_add (font_group, Mplist, MPLIST_VAL (plist));
366 per_charset = mplist_add (per_charset, MPLIST_KEY (plist), font_group);
369 realized->fallback = mplist ();
370 mplist_add (realized->fallback, Mplist, fontset->fallback);
375 free_realized_fontset_elements (MRealizedFontset *realized)
377 MPlist *plist, *pl, *p;
378 MRealizedFont *rfont;
380 if (realized->per_script)
382 MPLIST_DO (plist, realized->per_script)
384 MPLIST_DO (pl, MPLIST_PLIST (plist))
386 MPLIST_DO (p, MPLIST_PLIST (pl))
387 if ((rfont = MPLIST_VAL (p)) && ! rfont->frame)
389 p = MPLIST_PLIST (pl);
390 M17N_OBJECT_UNREF (p);
392 pl = MPLIST_PLIST (plist);
393 M17N_OBJECT_UNREF (pl);
395 M17N_OBJECT_UNREF (realized->per_script);
397 if (realized->per_charset)
399 MPLIST_DO (plist, realized->per_charset)
401 MPLIST_DO (pl, MPLIST_PLIST (plist))
402 if ((rfont = MPLIST_VAL (pl)) && ! rfont->frame)
404 pl = MPLIST_PLIST (plist);
405 M17N_OBJECT_UNREF (pl);
407 M17N_OBJECT_UNREF (realized->per_charset);
409 if (realized->fallback)
411 MPLIST_DO (plist, realized->fallback)
412 if ((rfont = MPLIST_VAL (plist)) && ! rfont->frame)
414 M17N_OBJECT_UNREF (realized->fallback);
419 update_fontset_elements (MRealizedFontset *realized)
421 free_realized_fontset_elements (realized);
422 realize_fontset_elements (realized->frame, realized, realized->fontset,
432 mfont__fontset_init ()
434 Mfontset = msymbol ("fontset");
435 Mfontset->managing_key = 1;
436 fontset_list = mplist ();
437 default_fontset = mfontset ("default");
438 if (! default_fontset->mdb)
443 mfont_put_prop (&font, Mregistry, msymbol ("iso8859-1"));
444 mfontset_modify_entry (default_fontset, Mnil, Mnil, Mnil,
446 mfont_put_prop (&font, Mregistry, msymbol ("iso10646-1"));
447 mfontset_modify_entry (default_fontset, Mnil, Mnil, Mnil,
455 mfont__fontset_fini ()
457 while (! MPLIST_TAIL_P (fontset_list))
458 free_fontset ((MFontset *) MPLIST_VAL (fontset_list));
459 M17N_OBJECT_UNREF (fontset_list);
465 mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face)
467 MRealizedFontset *realized;
472 load_fontset_contents (fontset);
474 mfont__set_spec_from_face (&request, face);
475 if (request.property[MFONT_SIZE] <= 0)
478 request.property[MFONT_SIZE] = 120;
480 MPLIST_DO (plist, frame->realized_fontset_list)
482 realized = (MRealizedFontset *) MPLIST_VAL (plist);
483 if (fontset->name == MPLIST_KEY (plist)
484 && ! memcmp (&request, &realized->spec, sizeof (request)))
488 MSTRUCT_MALLOC (realized, MERROR_FONTSET);
489 realize_fontset_elements (frame, realized, fontset, &request);
490 mplist_add (frame->realized_fontset_list, fontset->name, realized);
496 mfont__free_realized_fontset (MRealizedFontset *realized)
498 free_realized_fontset_elements (realized);
503 static MRealizedFont *
504 try_font_group (MRealizedFontset *realized,
505 MPlist *font_group, MGlyph *g, int *num, int size)
507 MFrame *frame = realized->frame;
508 MRealizedFont *rfont;
512 if (MPLIST_PLIST_P (font_group))
513 realize_font_group (frame, &realized->spec, font_group, size);
515 MPLIST_DO (plist, font_group)
517 rfont = (MRealizedFont *) MPLIST_VAL (plist);
518 if (rfont->status < 0)
520 /* Check if this font can display all glyphs. */
521 for (i = 0; i < *num; i++)
523 g[i].code = mfont__encode_char (rfont,
524 g[i].type == GLYPH_CHAR ? g[i].c
526 if (g[i].code == MCHAR_INVALID_CODE)
531 if (rfont->status > 0
532 || mfont__open (rfont) == 0)
533 /* We found a font that can display all glyphs. */
538 /* We couldn't find a font that can display all glyphs. Find one
539 that can display at least the first glyph. */
540 MPLIST_DO (plist, font_group)
542 rfont = (MRealizedFont *) MPLIST_VAL (plist);
543 if (rfont->status < 0)
545 g->code = mfont__encode_char (rfont,
546 g->type == GLYPH_CHAR ? g->c : ' ');
547 if (g->code != MCHAR_INVALID_CODE)
549 if (rfont->status > 0
550 || mfont__open (rfont) == 0)
552 /* Ok, let's use this font. Check how many more
553 characters it supports. */
556 for (i = 1; i < *num; i++)
558 g[i].code = mfont__encode_char (rfont,
559 g[i].type == GLYPH_CHAR
561 if (g[i].code == MCHAR_INVALID_CODE)
574 mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
575 MSymbol script, MSymbol language, MSymbol charset,
578 MCharset *preferred_charset = (charset == Mnil ? NULL : MCHARSET (charset));
579 MPlist *per_charset, *per_script, *per_lang;
581 MRealizedFont *rfont = NULL;
583 if (realized->tick != realized->fontset->tick)
584 update_fontset_elements (realized);
586 if (preferred_charset
587 && (per_charset = mplist_get (realized->per_charset, charset)) != NULL
588 && (rfont = try_font_group (realized, per_charset, g, num, size)))
592 && (per_script = mplist_get (realized->per_script, script)))
594 /* We prefer font groups in this order:
595 (1) group matching with LANGUAGE if LANGUAGE is not Mnil
596 (2) group for generic language
597 (3) group not matching with LANGUAGE */
598 if (language == Mnil)
600 if ((per_lang = mplist_get (per_script, language))
601 && (rfont = try_font_group (realized, per_lang, g, num, size)))
606 /* Try the above (3) */
607 MPLIST_DO (plist, per_script)
608 if (MPLIST_KEY (plist) != language
609 && (rfont = try_font_group (realized, MPLIST_PLIST (plist),
615 /* At first try the above (2) */
616 if ((per_lang = mplist_get (per_script, Mt))
617 && (rfont = try_font_group (realized, per_lang, g, num, size)))
620 /* Then try the above (3) */
621 MPLIST_DO (plist, per_script)
622 if (MPLIST_KEY (plist) != language
623 && MPLIST_KEY (plist) != Mt
624 && (rfont = try_font_group (realized, MPLIST_PLIST (plist),
630 if (language != Mnil)
631 /* Find a font group for this language from all scripts. */
632 MPLIST_DO (plist, realized->per_script)
633 if ((per_lang = mplist_get (MPLIST_PLIST (plist), language))
634 && (rfont = try_font_group (realized, per_lang, g, num, size)))
637 /* Try fallback fonts. */
638 if ((rfont = try_font_group (realized, realized->fallback, g, num, size)))
641 /* At last try all fonts. */
642 MPLIST_DO (per_script, realized->per_script)
644 MPLIST_DO (per_lang, MPLIST_PLIST (per_script))
645 if ((rfont = try_font_group (realized, MPLIST_PLIST (per_lang),
649 MPLIST_DO (per_charset, realized->per_charset)
650 if ((rfont = try_font_group (realized, MPLIST_PLIST (per_charset),
658 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
663 /*** @addtogroup m17nFontset */
668 @brief Return a fontset.
670 The mfontset () function returns a pointer to a fontset object of
671 name $NAME. If $NAME is @c NULL, it returns a pointer to the
674 If no fontset has the name $NAME, a new one is created. At that
675 time, if there exists a data \<@c fontset, $NAME\> in the m17n
676 database, the fontset contents are initialized according to the
677 data. If no such data exists, the fontset contents are left
680 The macro M17N_INIT () creates the default fontset. An
681 application program can modify it before the first call of
685 This function returns a pointer to the found or newly created
688 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊÖ¤¹.
690 ´Ø¿ô mfontset () ¤Ï̾Á° $NAME ¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î
691 ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£ $NAME ¤¬ @c NULL ¤Ê¤é¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È
694 $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¤¬¤Ê¤±¤ì¤Ð¡¢¿·¤·¤¤¤â¤Î¤¬ºî¤é¤ì
695 ¤ë¡£¤½¤ÎºÝ¡¢m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë \<@c fontset, $NAME\> ¤È¤¤¤¦¥Ç¡¼¥¿
696 ¤¬¤¢¤ì¤Ð¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï¤½¤Î¥Ç¡¼¥¿¤Ë±è¤Ã¤Æ½é´ü²½¤µ¤ì¤ë¡£¤Ê¤±¤ì¤Ð¡¢
699 ¥Þ¥¯¥í M17N_INIT () ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤òºî¤ë¡£¥¢¥×¥ê¥±¡¼
700 ¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï mframe () ¤ò½é¤á¤Æ¸Æ¤Ö¤Þ¤Ç¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È
701 ¥»¥Ã¥È¤òÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£
704 ¤³¤Î´Ø¿ô¤Ï¸«¤Ä¤«¤Ã¤¿¡¢¤¢¤ë¤¤¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
708 mfontset (char *name)
714 fontset = default_fontset;
717 sym = msymbol (name);
718 fontset = mplist_get (fontset_list, sym);
721 M17N_OBJECT (fontset, free_fontset, MERROR_FONTSET);
723 fontset->mdb = mdatabase_find (Mfontset, sym, Mnil, Mnil);
726 fontset->per_script = mplist ();
727 fontset->per_charset = mplist ();
728 fontset->fallback = mplist ();
729 fontset->font_spec_list = mplist ();
731 mplist_put (fontset_list, sym, fontset);
734 M17N_OBJECT_REF (fontset);
741 @brief Return the name of a fontset.
743 The mfontset_name () function returns the name of fontset $FONTSET. */
745 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤òÊÖ¤¹.
747 ´Ø¿ô mfontset_name () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î̾Á°¤òÊÖ¤¹¡£ */
749 mfontset_name (MFontset *fontset)
751 return fontset->name;
757 @brief Make a copy of a fontset.
759 The mfontset_copy () function makes a copy of fontset $FONTSET, gives it a
760 name $NAME, and returns a pointer to the created copy. $NAME must
761 not be a name of existing fontset. In such case, this function
762 returns NULL without making a copy. */
764 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
766 ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢
767 ̾Á° $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME ¤Ï´û¸¤Î
768 ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º
772 mfontset_copy (MFontset *fontset, char *name)
774 MSymbol sym = msymbol (name);
775 MFontset *copy = mplist_get (fontset_list, sym);
780 M17N_OBJECT (copy, free_fontset, MERROR_FONTSET);
784 load_fontset_contents (fontset);
786 if (fontset->per_script)
788 copy->per_script = mplist ();
789 MPLIST_DO (plist, fontset->per_script)
791 MPlist *new = mplist ();
793 MPLIST_DO (pl, MPLIST_PLIST (plist))
794 mplist_add (new, MPLIST_KEY (pl), mplist_copy (MPLIST_PLIST (pl)));
795 mplist_add (copy->per_script, MPLIST_KEY (plist), new);
798 if (fontset->per_charset)
800 copy->per_charset = mplist ();
801 MPLIST_DO (plist, fontset->per_charset)
802 mplist_add (copy->per_charset, MPLIST_KEY (plist),
803 mplist_copy (MPLIST_PLIST (plist)));
805 if (fontset->fallback)
806 copy->fallback = mplist_copy (fontset->fallback);
808 copy->font_spec_list = fontset->font_spec_list;
809 M17N_OBJECT_REF (copy->font_spec_list);
811 mplist_put (fontset_list, sym, copy);
812 M17N_OBJECT_REF (copy);
819 @brief Modify the contents of a fontset.
821 The mfontset_modify_entry () function associates, in fontset
822 $FONTSET, a copy of $FONT with the $SCRIPT / $LANGUAGE pair or
825 Each font in a fontset is associated with a particular
826 script/language pair, with a particular charset, or with the
827 symbol @c Mnil. The fonts that are associated with the same item
830 If $SCRIPT is not @c Mnil, it must be a symbol identifying a
831 script. In this case, $LANGUAGE is either a symbol identifying a
832 language or @c Mnil, and $FONT is associated with the $SCRIPT /
835 If $CHARSET is not @c Mnil, it must be a symbol representing a
836 charset object. In this case, $FONT is associated with that
839 If both $SCRIPT and $CHARSET are not @c Mnil, two copies of $FONT
840 are created. Then one is associated with the $SCRIPT / $LANGUAGE
841 pair and the other with that charset.
843 If both $SCRIPT and $CHARSET are @c Mnil, $FONT is associated with
844 @c Mnil. This kind of fonts are called @e fallback @e fonts.
846 The argument $HOW specifies the priority of $FONT. If $HOW is
847 positive, $FONT has the highest priority in the group of fonts
848 that are associated with the same item. If $HOW is negative,
849 $FONT has the lowest priority. If $HOW is zero, $FONT becomes the
850 only available font for the associated item; all the other fonts
851 are removed from the group.
853 If $LAYOUTER_NAME is not @c Mnil, it must be a symbol
854 representing a @ref flt. In that case, if $FONT is selected for
855 drawing an M-text, that font layout table is used to generate a
856 glyph code sequence from a character sequence.
859 If the operation was successful, mfontset_modify_entry () returns 0.
860 Otherwise it returns -1 and assigns an error code to the external
861 variable #merror_code. */
864 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ÎÆâÍƤòÊѹ¹¤¹¤ë.
866 ´Ø¿ô mfontset_modify_entry () ¤Ï¡¢$LANGUAGE ¤È $SCRIPT ¤ÎÁȤ߹ç¤ï
867 ¤»¤Þ¤¿¤Ï $CHARSET ¤ËÂФ·¤Æ $FONT ¤Î¥³¥Ô¡¼¤ò»È¤¦¤è¤¦¤Ë¡¢¥Õ¥©¥ó¥È¥»¥Ã
868 ¥È $FONTSET ¤òÀßÄꤹ¤ë¡£
870 ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î³Æ¥Õ¥©¥ó¥È¤Ï¡¢ÆÃÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤Î¥Ú¥¢¡¢ÆÃÄê¤Î
871 ʸ»ú¥»¥Ã¥È¡¢¥·¥ó¥Ü¥ë @c Mnil ¤Î¤¤¤º¤ì¤«¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¡£Æ±¤¸
872 ¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤ò¹½À®¤¹¤ë¡£
874 $SCRIPT ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥¹¥¯¥ê¥×¥È¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
875 ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢$LANGUAGE ¤Ï¸À¸ì¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤« @c
876 Mnil ¤Ç¤¢¤ê¡¢$FONT ¤Ïthe $SCRIPT / $LANGUAGE ¥Ú¥¢¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
878 $CHARSET ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢Ê¸»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¥·¥ó¥Ü¥ë
879 ¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï $FONT ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤È´ØÏ¢ÉÕ¤±¤é¤ì
882 $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï $FONT ¤Î¥³¥Ô¡¼
883 ¤¬£²¤Äºî¤é¤ì¡¢¤½¤ì¤¾¤ì $SCRIPT / $LANGUAGE ¥Ú¥¢¤Èʸ»ú¥»¥Ã¥È¤Ë´ØÏ¢
886 $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ $FONT ¤Ï @c Mnil ¤È
887 ´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£¤³¤Î¼ï¤Î¥Õ¥©¥ó¥È¤Ï @e fallback @e font ¤È¸Æ¤Ð¤ì¤ë¡£
889 °ú¿ô $HOW ¤Ï $FONT ¤ÎÍ¥ÀèÅÙ¤ò»ØÄꤹ¤ë¡£$HOW ¤¬Àµ¤Ê¤é¤Ð¡¢$FONT ¤ÏƱ
890 ¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥°¥ë¡¼¥×Ãæ¤ÇºÇ¹â¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬Éé¤Ê
891 ¤é¤Ð¡¢ºÇÄã¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬ 0 ¤Ê¤é¤Ð¡¢$FONT ¤Ï´ØÏ¢ÉÕ¤±¤é¤ì¤¿
892 ¤â¤Î¤ËÂФ¹¤ëÍ£°ì¤ÎÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤È¤Ê¤ê¡¢Â¾¤Î¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×
895 $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref flt ¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
896 ¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢$FONT ¤òÍѤ¤¤ÆM-text ¤òɽ¼¨¤¹¤ëºÝ¤Ë¤Ï¡¢¤½¤Î FONT
897 LAYOUT TABLE ¤ò»È¤Ã¤Æʸ»úÎ󤫤饰¥ê¥Õ¥³¡¼¥ÉÎó¤òÀ¸À®¤¹¤ë¡£
900 ½èÍý¤¬À®¸ù¤·¤¿¤È¤¡¢mfontset_modify_entry () ¤Ï 0 ¤òÊÖ¤¹¡£
901 ¼ºÇÔ¤·¤¿¤È¤¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤ò
909 mfontset_modify_entry (MFontset *fontset,
910 MSymbol script, MSymbol language, MSymbol charset,
911 MFont *spec, MSymbol layouter_name,
914 MPlist *per_lang, *plist[3], *pl;
919 load_fontset_contents (fontset);
921 if (! fontset->font_spec_list)
922 fontset->font_spec_list = mplist ();
924 MPLIST_DO (pl, fontset->font_spec_list)
926 if (! memcmp (MPLIST_VAL (pl), spec, sizeof (MFont)))
928 font = MPLIST_VAL (pl);
936 mplist_add (fontset->font_spec_list, Mt, font);
942 if (language == Mnil)
944 per_lang = mplist_get (fontset->per_script, script);
946 mplist_add (fontset->per_script, script, per_lang = mplist ());
947 plist[i] = mplist_get (per_lang, language);
949 mplist_add (per_lang, language, plist[i] = mplist ());
954 plist[i] = mplist_get (fontset->per_charset, charset);
956 mplist_add (fontset->per_charset, charset, plist[i] = mplist ());
959 if (script == Mnil && charset == Mnil)
961 plist[i++] = fontset->fallback;
964 if (layouter_name == Mnil)
966 for (i--; i >= 0; i--)
969 mplist_push (plist[i], layouter_name, font);
971 mplist_add (plist[i], layouter_name, font);
974 mplist_set (plist[i], Mnil, NULL);
975 mplist_add (plist[i], layouter_name, font);
986 @brief Lookup a fontset.
988 The mfontset_lookup () function lookups $FONTSET and returns a
989 plist that describes the contents of $FONTSET corresponding to the
990 specified script, language, and charset.
992 If $SCRIPT is @c Mt, keys of the returned plist are script name
993 symbols for which some fonts are specified and values are NULL.
995 If $SCIRPT is a script symbol, the returned plist is decided by
998 If $LANGUAGE is @c Mt, keys of the plist are language name symbols
999 for which some fonts are specified and values are NULL. A key may
1000 be @c Mt which means some fallback fonts are specified for the
1003 If $LANGUAGE is a language name symbol, the plist is a @c
1004 FONT-GROUP for the specified script and langauge.
1006 If $LANGAUGE is @c Mt, the plist is fallback @c FONT-GROUP for the
1009 If $SCRIPT is @c Mnil, the returned plist is decided as below.
1011 If $CHARSET is @c Mt, keys of the returned plist are charset name
1012 symbols for which some fonts are specified and values are NULL.
1014 If $CHARSET is a charset symbol, the plist is a @c FONT-GROUP for
1017 If $CHARSET is @c Mnil, the plist is a fallback @c FONT-GROUP.
1019 @c FONT-GROUP is a plist whose keys are FLT name symbols (@c Mt if
1020 no FLT is associated with the font) and values are pointers to
1024 It returns a plist describing the contents of a fontset. The
1025 plist should be freed by m17n_object_unref (). */
1028 mfontset_lookup (MFontset *fontset,
1029 MSymbol script, MSymbol language, MSymbol charset)
1031 MPlist *plist = mplist (), *pl, *p;
1034 load_fontset_contents (fontset);
1037 if (! fontset->per_script)
1040 MPLIST_DO (pl, fontset->per_script)
1041 p = mplist_add (p, MPLIST_KEY (pl), NULL);
1046 if (! fontset->per_script)
1048 pl = mplist_get (fontset->per_script, script);
1055 p = mplist_add (p, MPLIST_KEY (pl), NULL);
1058 if (language == Mnil)
1060 pl = mplist_get (pl, language);
1062 else if (charset != Mnil)
1064 if (! fontset->per_charset)
1069 MPLIST_DO (pl, fontset->per_charset)
1070 p = mplist_add (p, MPLIST_KEY (pl), NULL);
1073 pl = mplist_get (fontset->per_charset, charset);
1076 pl = fontset->fallback;
1079 return mplist_copy (pl);
1085 /*** @addtogroup m17nDebug */
1090 @brief Dump a fontset.
1092 The mdebug_dump_fontset () function prints fontset $FONTSET in a human readable
1093 way to the stderr. $INDENT specifies how many columns to indent
1094 the lines but the first one.
1097 This function returns $FONTSET. */
1099 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¥À¥ó¥×¤¹¤ë.
1101 ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr ¤Ë¿Í
1102 ´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ
1106 ¤³¤Î´Ø¿ô¤Ï $FONTSET ¤òÊÖ¤¹¡£ */
1109 mdebug_dump_fontset (MFontset *fontset, int indent)
1111 char *prefix = (char *) alloca (indent + 1);
1112 MPlist *plist, *pl, *p;
1114 memset (prefix, 32, indent);
1117 fprintf (stderr, "(fontset %s", fontset->name->name);
1118 if (fontset->per_script)
1119 MPLIST_DO (plist, fontset->per_script)
1121 fprintf (stderr, "\n %s(%s", prefix, MPLIST_KEY (plist)->name);
1122 MPLIST_DO (pl, MPLIST_PLIST (plist))
1124 fprintf (stderr, "\n %s(%s", prefix, MPLIST_KEY (pl)->name);
1125 MPLIST_DO (p, MPLIST_PLIST (pl))
1127 fprintf (stderr, "\n %s(%s ", prefix,
1128 MPLIST_KEY (p)->name);
1129 mdebug_dump_font (MPLIST_VAL (p));
1130 fprintf (stderr, ")");
1132 fprintf (stderr, ")");
1134 fprintf (stderr, ")");
1136 if (fontset->per_charset)
1137 MPLIST_DO (pl, fontset->per_charset)
1139 fprintf (stderr, "\n %s(%s", prefix, MPLIST_KEY (pl)->name);
1140 MPLIST_DO (p, MPLIST_PLIST (pl))
1142 fprintf (stderr, "\n %s(%s ", prefix, MPLIST_KEY (p)->name);
1143 mdebug_dump_font (MPLIST_VAL (p));
1144 fprintf (stderr, ")");
1146 fprintf (stderr, ")");
1149 if (fontset->fallback)
1150 MPLIST_DO (p, fontset->fallback)
1152 fprintf (stderr, "\n %s(%s ", prefix, MPLIST_KEY (p)->name);
1153 mdebug_dump_font (MPLIST_VAL (p));
1154 fprintf (stderr, ")");
1157 fprintf (stderr, ")");