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 () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
56 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
57 /*** @addtogroup m17nInternal
67 #include "m17n-misc.h"
71 #include "character.h"
73 #include "internal-gui.h"
81 /* Name of the fontset. */
84 /* Initialized to 0, and incremented by one each time the fontset is
88 /* Database from which to load the contents of the fontset. Once
89 loaded, this member is set to NULL. */
92 /* SCRIPT vs PER-LANGUAGE (which is a plist LANGUAGE vs FONT-GROUP) */
95 /* CHARSET vs FONT-GROUP */
101 /* Plist of Mt vs font specs. */
102 MPlist *font_spec_list;
105 static MFontset *default_fontset;
107 static MPlist *fontset_list;
109 struct MRealizedFontset
111 /* Fontset from which the realized fontset is realized. */
114 /* Initialized to <fontset>->tick. */
117 /* Font spec extracted from a face. */
120 /* The frame on which the realized fontset is realized. */
132 load_font_group (MPlist *plist, MPlist *elt, MPlist *spec_list)
136 /* ELT ::= ( FONT-SPEC-LIST [ LAYOUTER ] ) ... */
138 MFont font, *spec = NULL;
139 MSymbol layouter_name;
141 if (! MPLIST_PLIST_P (elt))
142 MWARNING (MERROR_FONTSET);
143 elt2 = MPLIST_PLIST (elt);
144 if (! MPLIST_PLIST_P (elt2))
145 MWARNING (MERROR_FONTSET);
146 mfont__set_spec_from_plist (&font, MPLIST_PLIST (elt2));
147 MPLIST_DO (p, spec_list)
149 if (! memcmp (MPLIST_VAL (p), &font, sizeof (MFont)))
151 spec = MPLIST_VAL (p);
157 MSTRUCT_MALLOC (spec, MERROR_FONTSET);
159 mplist_add (spec_list, Mt, spec);
161 elt2 = MPLIST_NEXT (elt2);
163 if (MPLIST_SYMBOL_P (elt2))
164 layouter_name = MPLIST_SYMBOL (elt2);
165 if (layouter_name == Mnil)
167 plist = mplist_add (plist, layouter_name, spec);
170 /* ANSI-C requires some statement after a label. */
176 /* Load FONTSET->per_script from the data in FONTSET->mdb. */
179 load_fontset_contents (MFontset *fontset)
181 MPlist *per_script, *per_charset, *fallback, *spec_list, *font_group;
182 MSymbol script, lang;
183 MPlist *fontset_def, *plist;
185 fontset->per_script = per_script = mplist ();
186 fontset->per_charset = per_charset = mplist ();
187 fontset->fallback = fallback = mplist ();
188 fontset->font_spec_list = spec_list = mplist ();
189 if (! (fontset_def = (MPlist *) mdatabase_load (fontset->mdb)))
192 MPLIST_DO (plist, fontset_def)
194 /* PLIST ::= ( SCRIPT ( LANGUAGE FONT-SPEC-ELT ... ) ... )
195 | (CHARSET FONT-SPEC-ELT ...)
199 if (! MPLIST_PLIST_P (plist))
200 MWARNING (MERROR_FONTSET);
201 elt = MPLIST_PLIST (plist);
202 if (! MPLIST_SYMBOL_P (elt))
203 MWARNING (MERROR_FONTSET);
204 script = MPLIST_SYMBOL (elt);
205 elt = MPLIST_NEXT (elt);
206 if (! MPLIST_PLIST_P (elt))
207 MWARNING (MERROR_FONTSET);
209 fallback = load_font_group (fallback, elt, spec_list);
210 else if (MPLIST_PLIST_P (MPLIST_PLIST (elt)))
212 font_group = mplist_find_by_key (fontset->per_charset, script);
215 font_group = mplist ();
216 per_charset = mplist_add (per_charset, script, font_group);
218 load_font_group (font_group, elt, spec_list);
222 MPlist *per_lang = mplist_find_by_key (fontset->per_script, script);
226 per_lang = mplist ();
227 per_script = mplist_add (per_script, script, per_lang);
232 /* ELT ::= ( LANGUAGE FONT-DEF ...) ... */
235 if (! MPLIST_PLIST_P (elt))
236 MWARNING (MERROR_FONTSET);
237 elt2 = MPLIST_PLIST (elt);
238 if (! MPLIST_SYMBOL_P (elt2))
239 MWARNING (MERROR_FONTSET);
240 lang = MPLIST_SYMBOL (elt2);
243 font_group = mplist_find_by_key (per_lang, lang);
246 font_group = mplist ();
247 mplist_add (per_lang, lang, font_group);
249 elt2 = MPLIST_NEXT (elt2);
250 load_font_group (font_group, elt2, spec_list);
256 /* ANSI-C requires some statement after a label. */
260 M17N_OBJECT_UNREF (fontset_def);
265 free_fontset (void *object)
267 MFontset *fontset = (MFontset *) object;
268 MPlist *plist, *pl, *p;
270 if (fontset->per_script)
272 MPLIST_DO (plist, fontset->per_script)
274 MPLIST_DO (pl, MPLIST_PLIST (plist))
276 p = MPLIST_PLIST (pl);
277 M17N_OBJECT_UNREF (p);
279 pl = MPLIST_PLIST (plist);
280 M17N_OBJECT_UNREF (pl);
282 M17N_OBJECT_UNREF (fontset->per_script);
284 if (fontset->per_charset)
286 MPLIST_DO (plist, fontset->per_charset)
288 pl = MPLIST_PLIST (plist);
289 M17N_OBJECT_UNREF (pl);
291 M17N_OBJECT_UNREF (fontset->per_charset);
293 if (fontset->fallback)
294 M17N_OBJECT_UNREF (fontset->fallback);
295 plist = mplist_find_by_key (fontset_list, fontset->name);
299 if (fontset->font_spec_list)
301 if (((M17NObject *) (fontset->font_spec_list))->ref_count == 1)
302 MPLIST_DO (plist, fontset->font_spec_list)
303 free (MPLIST_VAL (plist));
304 M17N_OBJECT_UNREF (fontset->font_spec_list);
310 realize_font_group (MFrame *frame, MFont *request, MPlist *font_group,
313 MPlist *plist = MPLIST_VAL (font_group), *pl, *p;
315 mplist_set (font_group, Mnil, NULL);
316 MPLIST_DO (pl, plist)
318 MSymbol layouter = MPLIST_KEY (pl);
319 MFont this_request = *request;
320 MRealizedFont *rfont;
322 mfont__resize (MPLIST_VAL (pl), &this_request);
323 rfont = mfont__select (frame, MPLIST_VAL (pl), &this_request,
324 size, layouter == Mt ? Mnil : layouter);
328 MPLIST_DO (p, font_group)
329 if (((MRealizedFont *) (MPLIST_VAL (p)))->score > rfont->score)
331 mplist_push (p, Mt, rfont);
337 realize_fontset_elements (MFrame *frame, MRealizedFontset *realized,
338 MFontset *fontset, MFont *request)
340 MPlist *per_script, *per_lang, *per_charset, *font_group;
343 realized->fontset = fontset;
344 realized->tick = fontset->tick;
345 realized->spec = *request;
346 realized->frame = frame;
347 realized->per_script = per_script = mplist ();
348 MPLIST_DO (plist, fontset->per_script)
350 per_lang = mplist ();
351 per_script = mplist_add (per_script, MPLIST_KEY (plist), per_lang);
352 MPLIST_DO (pl, MPLIST_PLIST (plist))
354 font_group = mplist ();
355 mplist_add (font_group, Mplist, MPLIST_VAL (pl));
356 per_lang = mplist_add (per_lang, MPLIST_KEY (pl), font_group);
360 realized->per_charset = per_charset = mplist ();
361 MPLIST_DO (plist, fontset->per_charset)
363 font_group = mplist ();
364 mplist_add (font_group, Mplist, MPLIST_VAL (plist));
365 per_charset = mplist_add (per_charset, MPLIST_KEY (plist), font_group);
368 realized->fallback = mplist ();
369 mplist_add (realized->fallback, Mplist, fontset->fallback);
374 free_realized_fontset_elements (MRealizedFontset *realized)
376 MPlist *plist, *pl, *p;
377 MRealizedFont *rfont;
379 if (realized->per_script)
381 MPLIST_DO (plist, realized->per_script)
383 MPLIST_DO (pl, MPLIST_PLIST (plist))
385 MPLIST_DO (p, MPLIST_PLIST (pl))
386 if ((rfont = MPLIST_VAL (p)) && ! rfont->frame)
388 p = MPLIST_PLIST (pl);
389 M17N_OBJECT_UNREF (p);
391 pl = MPLIST_PLIST (plist);
392 M17N_OBJECT_UNREF (pl);
394 M17N_OBJECT_UNREF (realized->per_script);
396 if (realized->per_charset)
398 MPLIST_DO (plist, realized->per_charset)
400 MPLIST_DO (pl, MPLIST_PLIST (plist))
401 if ((rfont = MPLIST_VAL (pl)) && ! rfont->frame)
403 pl = MPLIST_PLIST (plist);
404 M17N_OBJECT_UNREF (pl);
406 M17N_OBJECT_UNREF (realized->per_charset);
408 if (realized->fallback)
410 MPLIST_DO (plist, realized->fallback)
411 if ((rfont = MPLIST_VAL (plist)) && ! rfont->frame)
413 M17N_OBJECT_UNREF (realized->fallback);
418 update_fontset_elements (MRealizedFontset *realized)
420 free_realized_fontset_elements (realized);
421 realize_fontset_elements (realized->frame, realized, realized->fontset,
431 mfont__fontset_init ()
433 Mfontset = msymbol ("fontset");
434 Mfontset->managing_key = 1;
435 fontset_list = mplist ();
436 default_fontset = mfontset ("default");
437 if (! default_fontset->mdb)
442 mfont_put_prop (&font, Mregistry, msymbol ("iso8859-1"));
443 mfontset_modify_entry (default_fontset, Mnil, Mnil, Mnil,
445 mfont_put_prop (&font, Mregistry, msymbol ("iso10646-1"));
446 mfontset_modify_entry (default_fontset, Mnil, Mnil, Mnil,
454 mfont__fontset_fini ()
456 while (! MPLIST_TAIL_P (fontset_list))
457 free_fontset ((MFontset *) MPLIST_VAL (fontset_list));
458 M17N_OBJECT_UNREF (fontset_list);
464 mfont__realize_fontset (MFrame *frame, MFontset *fontset, MFace *face)
466 MRealizedFontset *realized;
471 load_fontset_contents (fontset);
473 mfont__set_spec_from_face (&request, face);
474 if (request.property[MFONT_SIZE] <= 0)
477 request.property[MFONT_SIZE] = 120;
479 MPLIST_DO (plist, frame->realized_fontset_list)
481 realized = (MRealizedFontset *) MPLIST_VAL (plist);
482 if (fontset->name == MPLIST_KEY (plist)
483 && ! memcmp (&request, &realized->spec, sizeof (request)))
487 MSTRUCT_MALLOC (realized, MERROR_FONTSET);
488 realize_fontset_elements (frame, realized, fontset, &request);
489 mplist_add (frame->realized_fontset_list, fontset->name, realized);
495 mfont__free_realized_fontset (MRealizedFontset *realized)
497 free_realized_fontset_elements (realized);
502 static MRealizedFont *
503 try_font_group (MRealizedFontset *realized,
504 MPlist *font_group, MGlyph *g, int *num, int size)
506 MFrame *frame = realized->frame;
507 MRealizedFont *rfont;
511 if (MPLIST_PLIST_P (font_group))
512 realize_font_group (frame, &realized->spec, font_group, size);
514 MPLIST_DO (plist, font_group)
516 rfont = (MRealizedFont *) MPLIST_VAL (plist);
517 if (rfont->status < 0)
519 /* Check if this font can display all glyphs. */
520 for (i = 0; i < *num; i++)
522 g[i].code = mfont__encode_char (rfont,
523 g[i].type == GLYPH_CHAR ? g[i].c
525 if (g[i].code == MCHAR_INVALID_CODE)
530 if (rfont->status > 0
531 || mfont__open (rfont) == 0)
532 /* We found a font that can display all glyphs. */
537 /* We couldn't find a font that can display all glyphs. Find one
538 that can display at least the first glyph. */
539 MPLIST_DO (plist, font_group)
541 rfont = (MRealizedFont *) MPLIST_VAL (plist);
542 if (rfont->status < 0)
544 g->code = mfont__encode_char (rfont,
545 g->type == GLYPH_CHAR ? g->c : ' ');
546 if (g->code != MCHAR_INVALID_CODE)
548 if (rfont->status > 0
549 || mfont__open (rfont) == 0)
551 /* Ok, let's use this font. Check how many more
552 characters it supports. */
555 for (i = 1; i < *num; i++)
557 g[i].code = mfont__encode_char (rfont,
558 g[i].type == GLYPH_CHAR
560 if (g[i].code == MCHAR_INVALID_CODE)
573 mfont__lookup_fontset (MRealizedFontset *realized, MGlyph *g, int *num,
574 MSymbol script, MSymbol language, MSymbol charset,
577 MCharset *preferred_charset = (charset == Mnil ? NULL : MCHARSET (charset));
578 MPlist *per_charset, *per_script, *per_lang;
580 MRealizedFont *rfont = NULL;
582 if (realized->tick != realized->fontset->tick)
583 update_fontset_elements (realized);
585 if (preferred_charset
586 && (per_charset = mplist_get (realized->per_charset, charset)) != NULL
587 && (rfont = try_font_group (realized, per_charset, g, num, size)))
591 && (per_script = mplist_get (realized->per_script, script)))
593 /* We prefer font groups in this order:
594 (1) group matching with LANGUAGE if LANGUAGE is not Mnil
595 (2) group for generic language
596 (3) group not matching with LANGUAGE */
597 if (language == Mnil)
599 if ((per_lang = mplist_get (per_script, language))
600 && (rfont = try_font_group (realized, per_lang, g, num, size)))
605 /* Try the above (3) */
606 MPLIST_DO (plist, per_script)
607 if (MPLIST_KEY (plist) != language
608 && (rfont = try_font_group (realized, MPLIST_PLIST (plist),
614 /* At first try the above (2) */
615 if ((per_lang = mplist_get (per_script, Mt))
616 && (rfont = try_font_group (realized, per_lang, g, num, size)))
619 /* Then try the above (3) */
620 MPLIST_DO (plist, per_script)
621 if (MPLIST_KEY (plist) != language
622 && MPLIST_KEY (plist) != Mt
623 && (rfont = try_font_group (realized, MPLIST_PLIST (plist),
629 if (language != Mnil)
630 /* Find a font group for this language from all scripts. */
631 MPLIST_DO (plist, realized->per_script)
632 if ((per_lang = mplist_get (MPLIST_PLIST (plist), language))
633 && (rfont = try_font_group (realized, per_lang, g, num, size)))
636 /* Try fallback fonts. */
637 if ((rfont = try_font_group (realized, realized->fallback, g, num, size)))
640 /* At last try all fonts. */
641 MPLIST_DO (per_script, realized->per_script)
643 MPLIST_DO (per_lang, MPLIST_PLIST (per_script))
644 if ((rfont = try_font_group (realized, MPLIST_PLIST (per_lang),
648 MPLIST_DO (per_charset, realized->per_charset)
649 if ((rfont = try_font_group (realized, MPLIST_PLIST (per_charset),
657 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
662 /*** @addtogroup m17nFontset */
667 @brief Return a fontset.
669 The mfontset () function returns a pointer to a fontset object of
670 name $NAME. If $NAME is @c NULL, it returns a pointer to the
673 If no fontset has the name $NAME, a new one is created. At that
674 time, if there exists a data \<@c fontset, $NAME\> in the m17n
675 database, the fontset contents are initialized according to the
676 data. If no such data exists, the fontset contents are left
679 The macro M17N_INIT () creates the default fontset. An
680 application program can modify it before the first call of
684 This function returns a pointer to the found or newly created
687 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊÖ¤¹.
689 ´Ø¿ô mfontset () ¤Ï̾Á° $NAME ¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
690 $NAME ¤¬ @c NULL ¤Ê¤é¤Ð¡¢¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
692 $NAME ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥Õ¥©¥ó¥È¥»¥Ã¥È¤¬¤Ê¤±¤ì¤Ð¡¢¿·¤·¤¤¤â¤Î¤¬ºî¤é¤ì¤ë¡£¤½¤ÎºÝ¡¢
693 m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë \<@c fontset, $NAME\>
694 ¤È¤¤¤¦¥Ç¡¼¥¿¤¬¤¢¤ì¤Ð¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ï¤½¤Î¥Ç¡¼¥¿¤Ë±è¤Ã¤Æ½é´ü²½¤µ¤ì¤ë¡£
695 ¤Ê¤±¤ì¤Ð¡¢¶õ¤Î¤Þ¤Þ¤Ë¤µ¤ì¤ë¡£
697 ¥Þ¥¯¥í M17N_INIT () ¤Ï¥Ç¥Õ¥©¥ë¥È¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤òºî¤ë¡£¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï
698 mframe () ¤ò½é¤á¤Æ¸Æ¤Ö¤Þ¤Ç¤Î´Ö¤Ï¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£
701 ¤³¤Î´Ø¿ô¤Ï¸«¤Ä¤«¤Ã¤¿¡¢¤¢¤ë¤¤¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
705 mfontset (char *name)
711 fontset = default_fontset;
714 sym = msymbol (name);
715 fontset = mplist_get (fontset_list, sym);
718 M17N_OBJECT (fontset, free_fontset, MERROR_FONTSET);
720 fontset->mdb = mdatabase_find (Mfontset, sym, Mnil, Mnil);
723 fontset->per_script = mplist ();
724 fontset->per_charset = mplist ();
725 fontset->fallback = mplist ();
726 fontset->font_spec_list = mplist ();
728 mplist_put (fontset_list, sym, fontset);
731 M17N_OBJECT_REF (fontset);
738 @brief Return the name of a fontset.
740 The mfontset_name () function returns the name of fontset $FONTSET. */
742 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤òÊÖ¤¹.
744 ´Ø¿ô mfontset_name () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î̾Á°¤òÊÖ¤¹¡£ */
746 mfontset_name (MFontset *fontset)
748 return fontset->name;
754 @brief Make a copy of a fontset.
756 The mfontset_copy () function makes a copy of fontset $FONTSET, gives it a
757 name $NAME, and returns a pointer to the created copy. $NAME must
758 not be a name of existing fontset. In such case, this function
759 returns NULL without making a copy. */
761 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
763 ´Ø¿ô mfontset_copy () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¡¢Ì¾Á°
764 $NAME ¤òÍ¿¤¨¡¢¤½¤Î¥³¥Ô¡¼¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME
765 ¤Ï´û¸¤Î¥Õ¥©¥ó¥È¥»¥Ã¥È¤Î̾Á°¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤½¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¥³¥Ô¡¼¤òºî¤é¤º¤Ë
769 mfontset_copy (MFontset *fontset, char *name)
771 MSymbol sym = msymbol (name);
772 MFontset *copy = mplist_get (fontset_list, sym);
777 M17N_OBJECT (copy, free_fontset, MERROR_FONTSET);
781 load_fontset_contents (fontset);
783 if (fontset->per_script)
785 copy->per_script = mplist ();
786 MPLIST_DO (plist, fontset->per_script)
788 MPlist *new = mplist ();
790 MPLIST_DO (pl, MPLIST_PLIST (plist))
791 mplist_add (new, MPLIST_KEY (pl), mplist_copy (MPLIST_PLIST (pl)));
792 mplist_add (copy->per_script, MPLIST_KEY (plist), new);
795 if (fontset->per_charset)
797 copy->per_charset = mplist ();
798 MPLIST_DO (plist, fontset->per_charset)
799 mplist_add (copy->per_charset, MPLIST_KEY (plist),
800 mplist_copy (MPLIST_PLIST (plist)));
802 if (fontset->fallback)
803 copy->fallback = mplist_copy (fontset->fallback);
805 copy->font_spec_list = fontset->font_spec_list;
806 M17N_OBJECT_REF (copy->font_spec_list);
808 mplist_put (fontset_list, sym, copy);
809 M17N_OBJECT_REF (copy);
816 @brief Modify the contents of a fontset.
818 The mfontset_modify_entry () function associates, in fontset
819 $FONTSET, a copy of $FONT with the $SCRIPT / $LANGUAGE pair or
822 Each font in a fontset is associated with a particular
823 script/language pair, with a particular charset, or with the
824 symbol @c Mnil. The fonts that are associated with the same item
827 If $SCRIPT is not @c Mnil, it must be a symbol identifying a
828 script. In this case, $LANGUAGE is either a symbol identifying a
829 language or @c Mnil, and $FONT is associated with the $SCRIPT /
832 If $CHARSET is not @c Mnil, it must be a symbol representing a
833 charset object. In this case, $FONT is associated with that
836 If both $SCRIPT and $CHARSET are not @c Mnil, two copies of $FONT
837 are created. Then one is associated with the $SCRIPT / $LANGUAGE
838 pair and the other with that charset.
840 If both $SCRIPT and $CHARSET are @c Mnil, $FONT is associated with
841 @c Mnil. This kind of fonts are called @e fallback @e fonts.
843 The argument $HOW specifies the priority of $FONT. If $HOW is
844 positive, $FONT has the highest priority in the group of fonts
845 that are associated with the same item. If $HOW is negative,
846 $FONT has the lowest priority. If $HOW is zero, $FONT becomes the
847 only available font for the associated item; all the other fonts
848 are removed from the group.
850 If $LAYOUTER_NAME is not @c Mnil, it must be a symbol representing
851 a @ref flt (font layout table). In that case, if $FONT is
852 selected for drawing an M-text, that font layout table is used to
853 generate a glyph code sequence from a character sequence.
856 If the operation was successful, mfontset_modify_entry () returns 0.
857 Otherwise it returns -1 and assigns an error code to the external
858 variable #merror_code. */
861 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ÎÆâÍƤòÊѹ¹¤¹¤ë.
863 ´Ø¿ô mfontset_modify_entry () ¤Ï¡¢$LANGUAGE ¤È $SCRIPT ¤ÎÁȤ߹ç¤ï¤»¡¢¤Þ¤¿¤Ï
864 $CHARSET ¤ËÂФ·¤Æ $FONT ¤Î¥³¥Ô¡¼¤ò»È¤¦¤è¤¦¤Ë¡¢¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤òÀßÄꤹ¤ë¡£
866 ¥Õ¥©¥ó¥È¥»¥Ã¥ÈÃæ¤Î³Æ¥Õ¥©¥ó¥È¤Ï¡¢ÆÃÄê¤Î¥¹¥¯¥ê¥×¥È¤È¸À¸ì¤Î¥Ú¥¢¡¢ÆÃÄê¤Îʸ»ú¥»¥Ã¥È¡¢¥·¥ó¥Ü¥ë
867 @c Mnil ¤Î¤¤¤º¤ì¤«¤È´ØÏ¢ÉÕ¤±¤é¤ì¤Æ¤¤¤ë¡£Æ±¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤ò¹½À®¤¹¤ë¡£
869 $SCRIPT ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥¹¥¯¥ê¥×¥È¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
870 ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢$LANGUAGE ¤Ï¸À¸ì¤òÆÃÄꤹ¤ë¥·¥ó¥Ü¥ë¤« @c
871 Mnil ¤Ç¤¢¤ê¡¢$FONT ¤Ïthe $SCRIPT / $LANGUAGE ¥Ú¥¢¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
873 $CHARSET ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢Ê¸»ú¥»¥Ã¥È¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
874 ¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï $FONT ¤Ï¤½¤Îʸ»ú¥»¥Ã¥È¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
876 $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ç¤Ê¤¤¾ì¹ç¤Ë¤Ï $FONT
877 ¤Î¥³¥Ô¡¼¤¬£²¤Äºî¤é¤ì¡¢¤½¤ì¤¾¤ì $SCRIPT / $LANGUAGE
878 ¥Ú¥¢¤Èʸ»ú¥»¥Ã¥È¤Ë´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£
880 $SCRIPT ¤È $CHARSET ¤ÎÁÐÊý¤¬ @c Mnil ¤Ê¤é¤Ð¡¢ $FONT ¤Ï @c Mnil
881 ¤È´ØÏ¢ÉÕ¤±¤é¤ì¤ë¡£¤³¤Î¼ï¤Î¥Õ¥©¥ó¥È¤Ï @e fallback @e font ¤È¸Æ¤Ð¤ì¤ë¡£
883 °ú¿ô $HOW ¤Ï $FONT ¤ÎÍ¥ÀèÅÙ¤ò»ØÄꤹ¤ë¡£$HOW ¤¬Àµ¤Ê¤é¤Ð¡¢$FONT
884 ¤ÏƱ¤¸¤â¤Î¤È´ØÏ¢ÉÕ¤±¤é¤ì¤¿¥°¥ë¡¼¥×Ãæ¤ÇºÇ¹â¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW
885 ¤¬Éé¤Ê¤é¤Ð¡¢ºÇÄã¤ÎÍ¥ÀèÅÙ¤ò»ý¤Ä¡£$HOW ¤¬ 0 ¤Ê¤é¤Ð¡¢$FONT
886 ¤Ï´ØÏ¢ÉÕ¤±¤é¤ì¤¿¤â¤Î¤ËÂФ¹¤ëÍ£°ì¤ÎÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤È¤Ê¤ê¡¢Â¾¤Î¥Õ¥©¥ó¥È¤Ï¥°¥ë¡¼¥×¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£
888 $LAYOUTER_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢@ref flt
889 ¡Ê¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¡Ë¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¥·¥ó¥Ü¥ë¤Ç¤¢¤ì¤Ð¡¢$FONT ¤òÍѤ¤¤Æ
890 M-text ¤òɽ¼¨¤¹¤ëºÝ¤Ë¤Ï¡¢¤½¤Î¥Õ¥©¥ó¥È¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤ò»È¤Ã¤Æʸ»úÎ󤫤饰¥ê¥Õ¥³¡¼¥ÉÎó¤òÀ¸À®¤¹¤ë¡£
893 ½èÍý¤¬À®¸ù¤·¤¿¤È¤¡¢mfontset_modify_entry () ¤Ï 0 ¤òÊÖ¤¹¡£
894 ¼ºÇÔ¤·¤¿¤È¤¤Ï -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£ */
901 mfontset_modify_entry (MFontset *fontset,
902 MSymbol script, MSymbol language, MSymbol charset,
903 MFont *spec, MSymbol layouter_name,
906 MPlist *per_lang, *plist[3], *pl;
911 load_fontset_contents (fontset);
913 if (! fontset->font_spec_list)
914 fontset->font_spec_list = mplist ();
916 MPLIST_DO (pl, fontset->font_spec_list)
918 if (! memcmp (MPLIST_VAL (pl), spec, sizeof (MFont)))
920 font = MPLIST_VAL (pl);
928 mplist_add (fontset->font_spec_list, Mt, font);
934 if (language == Mnil)
936 per_lang = mplist_get (fontset->per_script, script);
938 mplist_add (fontset->per_script, script, per_lang = mplist ());
939 plist[i] = mplist_get (per_lang, language);
941 mplist_add (per_lang, language, plist[i] = mplist ());
946 plist[i] = mplist_get (fontset->per_charset, charset);
948 mplist_add (fontset->per_charset, charset, plist[i] = mplist ());
951 if (script == Mnil && charset == Mnil)
953 plist[i++] = fontset->fallback;
956 if (layouter_name == Mnil)
958 for (i--; i >= 0; i--)
961 mplist_push (plist[i], layouter_name, font);
963 mplist_add (plist[i], layouter_name, font);
966 mplist_set (plist[i], Mnil, NULL);
967 mplist_add (plist[i], layouter_name, font);
978 @brief Lookup a fontset.
980 The mfontset_lookup () function lookups $FONTSET and returns a
981 plist that describes the contents of $FONTSET corresponding to the
982 specified script, language, and charset.
984 If $SCRIPT is @c Mt, keys of the returned plist are script name
985 symbols for which some fonts are specified and values are NULL.
987 If $SCRIPT is a script symbol, the returned plist is decided by
990 If $LANGUAGE is @c Mt, keys of the plist are language name symbols
991 for which some fonts are specified and values are NULL. A key may
992 be @c Mt which means some fallback fonts are specified for the
995 If $LANGUAGE is a language name symbol, the plist is a @c
996 FONT-GROUP for the specified script and language.
998 If $LANGUAGE is @c Mt, the plist is fallback @c FONT-GROUP for the
999 script. @c FONT-GROUP is a plist whose keys are FLT
1000 (FontLayoutTable)name symbols (@c Mt if no FLT is associated with
1001 the font) and values are pointers to #MFont.
1003 If $SCRIPT is @c Mnil, the returned plist is decided as below.
1005 If $CHARSET is @c Mt, keys of the returned plist are charset name
1006 symbols for which some fonts are specified and values are NULL.
1008 If $CHARSET is a charset symbol, the plist is a @c FONT-GROUP for
1011 If $CHARSET is @c Mnil, the plist is a fallback @c FONT-GROUP.
1015 It returns a plist describing the contents of a fontset. The
1016 plist should be freed by m17n_object_unref (). */
1019 mfontset_lookup (MFontset *fontset,
1020 MSymbol script, MSymbol language, MSymbol charset)
1022 MPlist *plist = mplist (), *pl, *p;
1025 load_fontset_contents (fontset);
1028 if (! fontset->per_script)
1031 MPLIST_DO (pl, fontset->per_script)
1032 p = mplist_add (p, MPLIST_KEY (pl), NULL);
1037 if (! fontset->per_script)
1039 pl = mplist_get (fontset->per_script, script);
1046 p = mplist_add (p, MPLIST_KEY (pl), NULL);
1049 if (language == Mnil)
1051 pl = mplist_get (pl, language);
1053 else if (charset != Mnil)
1055 if (! fontset->per_charset)
1060 MPLIST_DO (pl, fontset->per_charset)
1061 p = mplist_add (p, MPLIST_KEY (pl), NULL);
1064 pl = mplist_get (fontset->per_charset, charset);
1067 pl = fontset->fallback;
1070 return mplist_copy (pl);
1076 /*** @addtogroup m17nDebug */
1081 @brief Dump a fontset.
1083 The mdebug_dump_fontset () function prints fontset $FONTSET in a human readable
1084 way to the stderr. $INDENT specifies how many columns to indent
1085 the lines but the first one.
1088 This function returns $FONTSET. */
1090 @brief ¥Õ¥©¥ó¥È¥»¥Ã¥È¤ò¥À¥ó¥×¤¹¤ë.
1092 ´Ø¿ô mdebug_dump_face () ¤Ï¥Õ¥©¥ó¥È¥»¥Ã¥È $FONTSET ¤ò stderr
1093 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
1096 ¤³¤Î´Ø¿ô¤Ï $FONTSET ¤òÊÖ¤¹¡£ */
1099 mdebug_dump_fontset (MFontset *fontset, int indent)
1101 char *prefix = (char *) alloca (indent + 1);
1102 MPlist *plist, *pl, *p;
1104 memset (prefix, 32, indent);
1107 fprintf (stderr, "(fontset %s", fontset->name->name);
1108 if (fontset->per_script)
1109 MPLIST_DO (plist, fontset->per_script)
1111 fprintf (stderr, "\n %s(%s", prefix, MPLIST_KEY (plist)->name);
1112 MPLIST_DO (pl, MPLIST_PLIST (plist))
1114 fprintf (stderr, "\n %s(%s", prefix, MPLIST_KEY (pl)->name);
1115 MPLIST_DO (p, MPLIST_PLIST (pl))
1117 fprintf (stderr, "\n %s(%s ", prefix,
1118 MPLIST_KEY (p)->name);
1119 mdebug_dump_font (MPLIST_VAL (p));
1120 fprintf (stderr, ")");
1122 fprintf (stderr, ")");
1124 fprintf (stderr, ")");
1126 if (fontset->per_charset)
1127 MPLIST_DO (pl, fontset->per_charset)
1129 fprintf (stderr, "\n %s(%s", prefix, MPLIST_KEY (pl)->name);
1130 MPLIST_DO (p, MPLIST_PLIST (pl))
1132 fprintf (stderr, "\n %s(%s ", prefix, MPLIST_KEY (p)->name);
1133 mdebug_dump_font (MPLIST_VAL (p));
1134 fprintf (stderr, ")");
1136 fprintf (stderr, ")");
1139 if (fontset->fallback)
1140 MPLIST_DO (p, fontset->fallback)
1142 fprintf (stderr, "\n %s(%s ", prefix, MPLIST_KEY (p)->name);
1143 mdebug_dump_font (MPLIST_VAL (p));
1144 fprintf (stderr, ")");
1147 fprintf (stderr, ")");