(mfont__select): Print score the a font for debugging.
[m17n/m17n-lib.git] / src / font.c
1 /* font.c -- font module.
2    Copyright (C) 2003, 2004
3      National Institute of Advanced Industrial Science and Technology (AIST)
4      Registration Number H15PRO112
5
6    This file is part of the m17n library.
7
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.
12
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.
17
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
21    02111-1307, USA.  */
22
23 /***en
24     @addtogroup m17nFont
25     @brief Font object.
26
27     The m17n GUI API represents a font by an object of the type @c
28     MFont.  A font can have @e font @e properties.  Like other types
29     of properties, a font property consists of a key and a value.  The
30     key of a font property must be one of the following symbols:
31
32     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
33     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
34
35     When the key of a font property is @c Msize or @c Mresolution, its
36     value is an integer.  Otherwise the value is a symbol.  "The font
37     property that belongs to font F and whose key is @c Mxxx" may be
38     shortened to "the xxx property of F".
39
40     The value of a foundry property is a symbol representing font
41     foundry information, e.g. adobe, misc, etc.
42
43     The value of a family property is a symbol representing font family
44     information, e.g. times, helvetica, etc.
45
46     The value of a weight property is a symbol representing weight
47     information, e.g. normal, bold, etc.
48
49     The value of a style property is a symbol representing slant
50     information, e.g. normal, italic, etc.
51
52     The value of a stretch property is a symbol representing width
53     information, e.g. normal, semicondensed, etc.
54
55     The value of an adstyle property is a symbol representing abstract
56     font family information, e.g. serif, sans-serif, etc.
57
58     The value of a registry property is a symbol representing registry
59     information, e.g. iso10646-1, iso8895-1, etc.
60
61     The value of a size property is an integer representing design
62     size in the unit of 1/10 point.
63
64     The value of a resolution property is an integer representing
65     assumed device resolution in the unit of dots per inch (dpi)
66
67     The m17n library uses font objects for two purposes: to receive
68     font specification from an application program, and to present
69     available fonts to an application program.  When the m17n library
70     presents an available font to an application program, all font
71     properties have a concrete value.
72
73     The m17n library supports three kinds of fonts: Window system fonts,
74     FreeType fonts, and OpenType fonts.
75
76     <ul>
77
78     <li> Window system fonts
79
80     The m17n-X library supports all fonts handled by an X server and
81     an X font server.  The correspondence between XLFD fields and font
82     properties are shown below.
83
84 @verbatim
85     XLFD field                                  property
86     ---------------                             --------
87     FOUNDRY                                     foundry
88     FAMILY_NAME                                 family
89     WEIGHT_NAME                                 weight
90     SLANT                                       style
91     SETWIDTH_NAME                               stretch
92     ADD_STYLE_NAME                              adstyle
93     POINT_SIZE                                  size
94     RESOLUTION_Y                                resolution
95     CHARSET_REGISTRY-CHARSET_ENCODING           registry
96 @endverbatim
97
98     XLFD fields not listed in the above table are ignored.
99
100     <li> FreeType fonts
101
102     The m17n library, if configured to use the FreeType library,
103     supports all fonts that can be handled by the FreeType library.
104     The variable #mfont_freetype_path is initialized properly according
105     to the configuration of the m17n library and the environment
106     variable @c M17NDIR.  See the documentation of the variable for
107     details.
108
109     If the m17n library is configured to use the fontconfig librray,
110     in addition to #mfont_freetype_path, all fonts available via
111     fontconfig are supported.
112
113     The family name of a FreeType font corresponds to the family
114     property.  Style names of FreeType fonts correspond to the weight,
115     style, and stretch properties as below.
116
117 @verbatim
118     style name          weight  style   stretch
119     ----------          ------  -----   -------
120     Regular             medium  r       normal
121     Italic              medium  i       normal
122     Bold                bold    r       normal
123     Bold Italic         bold    i       normal
124     Narrow              medium  r       condensed
125     Narrow Italic       medium  i       condensed
126     Narrow Bold         bold    r       condensed
127     Narrow Bold Italic  bold    i       condensed
128     Black               black   r       normal
129     Black Italic        black   i       normal
130     Oblique             medium  o       normal
131     BoldOblique         bold    o       normal
132 @endverbatim
133
134     Style names not listed in the above table are treated as
135     "Regular".
136
137     Combination of a platform ID and an encoding ID corresponds to the
138     registry property.  For example, if a font has the combination (1
139     1), the registry property is 1-1.  Some frequent combinations have
140     a predefined registry property as below.
141
142 @verbatim
143     platform ID         encoding ID     registry property
144     -----------         -----------     -----------------
145     0                   3               unicode-bmp
146     0                   4               unicode-full
147     1                   0               apple-roman
148     3                   1               unicode-bmp
149     3                   1               unicode-full
150 @endverbatim
151
152     Thus, a font that has two combinations (1 0) and (3 1) corresponds
153     to four font objects whose registries are 1-0, apple-roman, 3-1,
154     and unicode-bmp.
155
156     <li> OpenType fonts 
157
158     The m17n library, if configured to use both the FreeType library
159     and the OTF library, supports any OpenType fonts.  The list of
160     actually available fonts is created in the same way as in the case
161     of FreeType fonts.  If a fontset instructs to use an OpenType font
162     via an FLT (Font Layout Table), and the FLT has an OTF-related
163     command (e.g. otf:deva), the OTF library converts a character
164     sequence to a glyph code sequence according to the OpenType layout
165     tables of the font, and the FreeType library gives a bitmap image
166     for each glyph.
167
168     </ul>
169
170   */
171
172 /***ja
173     @addtogroup m17nFont
174     @brief ¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È.
175
176     m17n GUI API ¤Ï¥Õ¥©¥ó¥È¤ò @c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æɽ¸½¤¹¤ë¡£
177     ¥Õ¥©¥ó¥È¤Ï @e ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£Â¾¤Î¥¿¥¤¥×¤Î
178     ¥×¥í¥Ñ¥Æ¥£Æ±ÍÍ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ë¡£¥­¡¼¤Ï°Ê²¼¤Î¥·
179     ¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
180
181     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
182     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution
183
184     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¡¢
185     ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¡Ö¥Õ¥©
186     ¥ó¥È F ¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È
187     ¤ò´Êñ¤Ë¡ÖF ¤Î xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
188
189     foundry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢adobe, misc Åù¤Î¥Õ¥©¥ó¥È¤Î³«È¯¸µ¾ðÊó¤ò¼¨
190     ¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
191
192     family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò
193     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
194
195     weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·
196     ¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
197
198     style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic Åù¤Î¥¹¥¿¥¤¥ë¤Ë´Ø¤¹¤ë¾ðÊó¤ò
199     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
200
201     stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë
202     ¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
203
204     adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È¥Õ¥¡
205     ¥ß¥ê¡¼¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
206
207     registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1 Åù¤Î¥ì¥¸¥¹¥È¥ê¾ðÊó¤ò
208     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
209
210     size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹À°¿ôÃͤǤ¢
211     ¤ê¡¢Ã±°Ì¤Ï 1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£
212
213     resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤òɽ¤ï
214     ¤¹À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ï dots per inch (dpi) ¤Ç¤¢¤ë¡£  
215
216     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢
217     ¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê
218     ¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×
219     ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£
220     ¤Ï¤¹¤Ù¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
221
222     m17n ¥é¥¤¥Ö¥é¥ê¤Ï Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢
223     OpenType¥Õ¥©¥ó¥È¤Î£³¼ïÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£
224
225     <ul>
226
227     <li> Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È
228
229     m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤È X ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©
230     ¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ
231     ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
232
233 @verbatim
234     XLFD ¥Õ¥£¡¼¥ë¥É                             ¥×¥í¥Ñ¥Æ¥£
235     ---------------                             --------
236     FOUNDRY                                     foundry
237     FAMILY_NAME                                 family
238     WEIGHT_NAME                                 weight
239     SLANT                                       style
240     SETWIDTH_NAME                               stretch
241     ADD_STYLE_NAME                              adstyle
242     POINT_SIZE                                  size
243     RESOLUTION_Y                                resolution
244     CHARSET_REGISTRY-CHARSET_ENCODING           registry
245 @endverbatim
246
247     <li> FreeType fonts
248
249     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë
250     ¤Ï¡¢FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
251     #mfont_freetype_path ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤ÎÀßÄê¤È´Ä¶­ÊÑ¿ô @c M17NDIR 
252     ¤Ë±þ¤¸¤Æ½é´ü²½¤µ¤ì¤ë¡£¾ÜºÙ¤ÏÊÑ¿ô¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
253
254     ¤â¤· m17n ¥é¥¤¥Ö¥é¥ê¤¬ fontconfig ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿
255     ¾ì¹ç¤Ë¤Ï¡¢#mfont_freetype_path ¤Ë²Ã¤¨¤Æ¡¢ fontconfig ¤Ç»ÈÍѲÄǽ¤Ê¥Õ¥©
256     ¥ó¥È¤â¤¹¤Ù¤Æ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¡£
257
258     FreeType ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤Ï family ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
259     FreeType ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾¤Ï¡¢²¼¤Îɽ¤Î¤è¤¦¤Ë weight, style,
260     stretch ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
261
262 @verbatim
263     ¥¹¥¿¥¤¥ë̾          weight  style   stretch
264     ----------          ------  -----   -------
265     Regular             medium  r       normal
266     Italic              medium  i       normal
267     Bold                bold    r       normal
268     Bold Italic         bold    i       normal
269     Narrow              medium  r       condensed
270     Narrow Italic       medium  i       condensed
271     Narrow Bold         bold    r       condensed
272     Narrow Bold Italic  bold    i       condensed
273     Black               black   r       normal
274     Black Italic        black   i       normal
275     Oblique             medium  o       normal
276     BoldOblique         bold    o       normal
277 @endverbatim
278
279     ¾å¤Îɽ¤Ë¸½¤ï¤ì¤Ê¤¤¥¹¥¿¥¤¥ë̾¤Ï "Regular" ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
280
281     platform ID ¤È encoding ID ¤ÎÁȤ߹ç¤ï¤»¤Ï registry ¥×¥í¥Ñ¥Æ¥£¤ËÂÐ
282     ±þ¤¹¤ë¡£¤¿¤È¤¨¤Ð¤¢¤ë¥Õ¥©¥ó¥È¤¬ (1 1) ¤È¤¤¤¦ ID ¤ÎÁȹ礻¤ò»ý¤Æ¤Ð¡¢
283     registry ¥×¥í¥Ñ¥Æ¥£¤Ï 1-1 ¤È¤Ê¤ë¡£ÉÑÈˤˤ¢¤é¤ï¤ì¤ëÁȹ礻¤Ë¤Ï°Ê²¼¤Î
284     ¤è¤¦¤ÊÄêµÁºÑ¤ß registry ¥×¥í¥Ñ¥Æ¥£ ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ë¡£
285
286 @verbatim
287     platform ID         encoding ID     registry ¥×¥í¥Ñ¥Æ¥£
288     -----------         -----------     -----------------
289     0                   3               unicode-bmp
290     0                   4               unicode-full
291     1                   0               apple-roman
292     3                   1               unicode-bmp
293     3                   1               unicode-full
294 @endverbatim
295
296     ¤·¤¿¤¬¤Ã¤Æ¡¢Æó¤Ä¤ÎÁȹ礻 (1 0) ¡¢(3 1) ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤Ï¡¢¤½¤ì¤¾¤ì
297     registry ¥×¥í¥Ñ¥Æ¥£¤¬ 1-0, apple-roman, 3-1, unicode-bmp ¤Ç¤¢¤ë£´¤Ä
298     ¤Î¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ËÂбþ¤¹¤ë¡£
299
300     <li> OpenType ¥Õ¥©¥ó¥È
301
302     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤È OTF ¥é¥¤¥Ö¥é¥ê¤ò»ÈÍѤ¹¤ë¤è
303     ¤¦¤ËÀßÄꤹ¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î OpenType ¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£¼ÂºÝ¤ËÍø
304     ÍѤǤ­¤ë¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤Ï FreeType ¥Õ¥©¥ó¥È¤Î¾ì¹ç¤ÈƱÍͤ˺î¤é¤ì¤ë¡£
305     OpenType ¥Õ¥©¥ó¥È¤ò FLT (Font Layout Table) ·Ðͳ¤Ç»ÈÍѤ¹¤ë¤è¤¦¥Õ¥©
306     ¥ó¥È¥»¥Ã¥È¤Ë»ØÄꤵ¤ì¤Æ¤ª¤ê¡¢FLT ¤Ë OTF ´ØÏ¢¤Î¥³¥Þ¥ó¥É (¤¿¤È¤¨¤Ð
307     otf:deva) ¤¬¤¢¤ì¤Ð¡¢OTF ¥é¥¤¥Ö¥é¥ê¤¬¥Õ¥©¥ó¥È¤Î OpenType ¥ì¥¤¥¢¥¦¥È
308     ¥Æ¡¼¥Ö¥ë¤Ë½¾¤Ã¤Æʸ»úÎó¤ò¥°¥ê¥Õ¥³¡¼¥ÉÎó¤ËÊÑ´¹¤·¡¢FreeType ¥é¥¤¥Ö¥é¥ê
309     ¤¬³Æ¥°¥ê¥Õ¤Î¥Ó¥Ã¥È¥Þ¥Ã¥×¥¤¥á¡¼¥¸¤òÄ󶡤¹¤ë¡£
310
311     </ul>
312
313 */
314
315 /*=*/
316
317 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
318 /*** @addtogroup m17nInternal
319      @{ */
320
321 #include "config.h"
322
323 #include <stdio.h>
324 #include <stdlib.h>
325 #include <string.h>
326
327 #include "m17n-gui.h"
328 #include "m17n-misc.h"
329 #include "internal.h"
330 #include "mtext.h"
331 #include "symbol.h"
332 #include "plist.h"
333 #include "charset.h"
334 #include "internal-gui.h"
335 #include "font.h"
336 #include "face.h"
337
338 MPlist *mfont__driver_list;
339
340 /** Indices to font properties sorted by their priority.  */
341 static int font_score_priority[] =
342   { MFONT_SIZE,
343     MFONT_ADSTYLE,
344     MFONT_FAMILY,
345     MFONT_WEIGHT,
346     MFONT_STYLE,
347     MFONT_STRETCH,
348     MFONT_FOUNDRY
349   };
350
351 #define FONT_SCORE_PRIORITY_SIZE        \
352   (sizeof font_score_priority / sizeof font_score_priority[0])
353
354 /* Indexed by a font property MFONT_XXX, and the value is how many
355    bits to shift the difference of property values.  */
356 static int font_score_shift_bits[MFONT_PROPERTY_MAX];
357
358 /** Predefined symbols for each font property.  The order is important
359     because the function score_font () decides how well a font matches
360     with a spec by checking how close the index is.  */
361
362 static char *common_foundry[] =
363   { "misc",
364     "adobe" };
365 static char *common_family[] =
366   { "fixed",
367     "courier",
368     "helvetica",
369     "times" };
370 static char *common_weight[] =
371   { "ultralight",
372     "extralight",
373     "light",
374     "demilight",
375     "book",
376     "normal",
377     "medium",
378     "regular",
379     "demibold",
380     "bold",
381     "extrabold",
382     "ultrabold",
383     "black" };
384 static char *common_style[] =
385   { "o",
386     "i",
387     "r",
388     "ri",
389     "ro" };
390 static char *common_stretch[] =
391   { "condensed",
392     "narrow",
393     "semicondensed",
394     "normal",
395     "semiexpanded",
396     "expanded" };
397 static char *common_adstyle[] =
398   { "serif",
399     "",
400     "sans" };
401 static char *common_registry[] =
402   { "iso8859-1" };
403
404 /* Table containing all the data above.  */
405
406 struct MFontCommonNames
407 {
408   int num;
409   char **names;
410 };
411
412 static struct MFontCommonNames font_common_names[] =
413   {
414     { sizeof (common_foundry) / sizeof (char *), common_foundry},
415     { sizeof (common_family) / sizeof (char *), common_family},
416     { sizeof (common_weight) / sizeof (char *), common_weight},
417     { sizeof (common_style) / sizeof (char *), common_style},
418     { sizeof (common_stretch) / sizeof (char *), common_stretch},
419     { sizeof (common_adstyle) / sizeof (char *), common_adstyle},
420     { sizeof (common_registry) / sizeof (char *), common_registry}
421   };
422
423
424 /** Table of available font property names.  */
425
426 MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
427
428
429 /** Return the numeric value of SYMBOL as the Nth font property.  */
430
431 #define FONT_PROPERTY_NUMERIC(symbol, n)        \
432   ((symbol) == Mnil                             \
433    ? 0                                          \
434    : ((int) msymbol_get ((symbol), mfont__property_table[(n)].property)))
435
436
437 /** Set the numeric value of SYMBOL as the Nth font property to NUMERIC.  */
438
439 #define SET_FONT_PROPERTY_NUMERIC(symbol, n, numeric)           \
440   msymbol_put((symbol), mfont__property_table[(n)].property,    \
441               (void *) (numeric))
442
443 static char *
444 gen_font_name (char *buf, MFont *font)
445 {
446   char size[16];
447   int i;
448
449   buf[0] = '\0';
450   for (i = 0; i <= MFONT_REGISTRY; i++)
451     if (FONT_PROPERTY (font, i) != Mnil)
452       {
453         char *name = msymbol_name (FONT_PROPERTY (font, i));
454
455         if (name[0])
456           {
457             if (i > 0)
458               strcat (buf, ",");
459             strcat (buf, name);
460           }
461       }
462   sprintf (size, ",%d", font->property[MFONT_SIZE] / 10);
463   strcat (buf, size);
464   return buf;
465 }
466
467
468 \f
469 /* Font selector.  */
470
471 struct MFontEncoding {
472   MFont spec;
473   MSymbol encoding_name;
474   MCharset *encoding_charset;
475   MSymbol repertory_name;
476   MCharset *repertory_charset;
477 };
478
479 static MPlist *font_encoding_list;
480 static MFontEncoding default_encoding;
481
482 /** Load font encoding table from the data <font encoding>.
483     The data has this form:
484         (FONT-SPEC ENCODING) ...
485     where FONT-SPEC has this form:
486         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
487     All elements are symbols.  */
488
489 static int
490 load_font_encoding_table ()
491 {
492   MDatabase *mdb;
493   MPlist *encoding_list, *plist, *pl, *elt;
494
495   font_encoding_list = pl = mplist ();
496
497   mdb = mdatabase_find (Mfont, msymbol ("encoding"), Mnil, Mnil);
498   if (! mdb
499       || ! (encoding_list = (MPlist *) mdatabase_load (mdb)))
500     MERROR (MERROR_FONT, -1);
501
502   MPLIST_DO (plist, encoding_list)
503     {
504       MFontEncoding *encoding;
505       MSymbol registry;
506
507       MSTRUCT_CALLOC (encoding, MERROR_FONT);
508
509       if (! MPLIST_PLIST_P (plist)
510           || (elt = MPLIST_PLIST (plist), mplist_length (elt) < 2)
511           || ! MPLIST_PLIST_P (elt))
512         MWARNING (MERROR_FONT);
513       registry = mfont__set_spec_from_plist (&encoding->spec,
514                                              MPLIST_PLIST (elt));
515       elt = MPLIST_NEXT (elt);
516       if (! MPLIST_SYMBOL_P (elt))
517         MWARNING (MERROR_FONT);
518       encoding->encoding_name = MPLIST_SYMBOL (elt);
519       elt = MPLIST_NEXT (elt);
520       if (MPLIST_TAIL_P (elt))
521         encoding->repertory_name = encoding->encoding_name;
522       else if (! MPLIST_SYMBOL_P (elt))
523         MWARNING (MERROR_FONT);
524       else
525         encoding->repertory_name = MPLIST_SYMBOL (elt);
526
527       if (registry == Mnil)
528         registry = Mt;
529       pl = mplist_add (pl, registry, encoding);
530       continue;
531
532     warning:
533       free (encoding);
534     }
535
536   M17N_OBJECT_UNREF (encoding_list);
537   return 0;
538 }
539
540 typedef struct {
541   MFont spec;
542   int resize;
543 } MFontResize;
544
545 static MPlist *font_resize_list;
546
547 /** Load font size table from the data <font size>.
548     The data has this form:
549         (FONT-SPEC RESIZE-FACTOR) ...
550     where FONT-SPEC has this form:
551         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
552     All elements of FONT-SPEC are symbols.  */
553
554 static int
555 load_font_resize_table ()
556 {
557   MDatabase *mdb;
558   MPlist *size_adjust_list, *plist, *pl, *elt;
559
560   font_resize_list = pl = mplist ();
561
562   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
563   if (! mdb)
564     return -1;
565   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
566     MERROR (MERROR_FONT, -1);
567
568   MPLIST_DO (plist, size_adjust_list)
569     {
570       MFontResize *resize;
571       MSymbol registry;
572
573       MSTRUCT_CALLOC (resize, MERROR_FONT);
574
575       if (! MPLIST_PLIST_P (plist)
576           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
577           || ! MPLIST_PLIST_P (elt))
578         MWARNING (MERROR_FONT);
579       registry = mfont__set_spec_from_plist (&resize->spec,
580                                              MPLIST_PLIST (elt));
581       elt = MPLIST_NEXT (elt);
582       if (! MPLIST_INTEGER_P (elt))
583         MWARNING (MERROR_FONT);
584       resize->resize = MPLIST_INTEGER (elt);
585
586       if (registry == Mnil)
587         registry = Mt;
588       pl = mplist_add (pl, registry, resize);
589       continue;
590
591     warning:
592       free (resize);
593     }
594
595   M17N_OBJECT_UNREF (size_adjust_list);
596   return 0;
597 }
598
599 /** Return a font encoding (and repertory) of FONT.  */
600
601 static MFontEncoding *
602 find_encoding (MFont *font)
603 {
604   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
605   MFontEncoding *encoding = NULL;
606   MPlist *plist;
607
608   if (! font_encoding_list)
609     load_font_encoding_table ();
610   if (! MPLIST_TAIL_P (font_encoding_list))
611     while (1)
612       {
613         plist = font_encoding_list;
614         while (registry ? (plist = mplist_find_by_key (plist, registry))
615                : plist)
616           {
617             encoding = (MFontEncoding *) MPLIST_VAL (plist);
618             if (mfont__match_p (font, &encoding->spec, MFONT_ADSTYLE))
619               {
620                 if (! encoding->encoding_charset)
621                   encoding->encoding_charset
622                     = MCHARSET (encoding->encoding_name);
623                 if (! encoding->encoding_charset)
624                   {
625                     mplist_pop (plist);
626                     continue;
627                   }
628                 if (encoding->repertory_name == encoding->encoding_name)
629                   encoding->repertory_charset = encoding->encoding_charset;
630                 else if (encoding->repertory_name != Mnil)
631                   {
632                     encoding->repertory_charset
633                       = MCHARSET (encoding->repertory_name);
634                     if (! encoding->repertory_charset)
635                       {
636                         mplist_pop (plist);
637                         continue;
638                       }
639                   }
640                 return encoding;
641               }
642             else
643               plist = MPLIST_NEXT (plist);
644           }
645         if (registry == Mnil || registry == Mt)
646           break;
647         registry = Mt;
648       }
649   return &default_encoding;
650 }
651
652
653 \f
654 /* Internal API */
655
656 int
657 mfont__init ()
658 {
659   int i, shift;
660
661   Mfoundry = msymbol ("foundry");
662   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
663   Mfamily = msymbol ("family");
664   mfont__property_table[MFONT_FAMILY].property = Mfamily;
665   Mweight = msymbol ("weight");
666   mfont__property_table[MFONT_WEIGHT].property = Mweight;
667   Mstyle = msymbol ("style");
668   mfont__property_table[MFONT_STYLE].property = Mstyle;
669   Mstretch = msymbol ("stretch");
670   mfont__property_table[MFONT_STRETCH].property = Mstretch;
671   Madstyle = msymbol ("adstyle");
672   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
673   Mregistry = msymbol ("registry");
674   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
675
676   Msize = msymbol ("size");
677   Mresolution = msymbol ("resolution");
678
679   /* The first entry of each mfont__property_table must be Mnil so
680      that actual properties get positive numeric numbers.  */
681   for (i = 0; i <= MFONT_REGISTRY; i++)
682     {
683       MLIST_INIT1 (&mfont__property_table[i], names, 8);
684       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
685     }
686
687   /* Register predefined font property names.  */
688   for (i = 0; i <= MFONT_REGISTRY; i++)
689     {
690       int j;
691
692       for (j = 0; j < font_common_names[i].num; j++)
693         {
694           MSymbol sym = msymbol (font_common_names[i].names[j]);
695
696           if (sym == Mnil)
697             return -1;
698           if (msymbol_put(sym, mfont__property_table[i].property,
699                           (void *) (j + 1)) < 0)
700             return -1;
701           MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
702         }
703     }
704
705   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
706      of a score is a flag for a scalable font (see the documentation
707      of mfont_score).  */
708   i = FONT_SCORE_PRIORITY_SIZE - 1;
709   for (shift = 1; i >= 0; i--)
710     {
711       font_score_shift_bits[font_score_priority[i]] = shift;
712       if (font_score_priority[i] == MFONT_SIZE)
713         shift += 16;
714       else
715         shift += 2;
716     }
717
718   MFONT_INIT (&default_encoding.spec);
719   default_encoding.encoding_name = Mnil;
720   default_encoding.encoding_charset = NULL;
721   default_encoding.repertory_name = Mnil;
722   default_encoding.repertory_charset = NULL;
723   {
724     char *path, *buf;
725     int bufsize;
726
727     mfont_freetype_path = mplist ();
728     bufsize = strlen (M17NDIR) + 7;
729     buf = alloca (bufsize);
730     sprintf (buf, "%s/fonts", M17NDIR);
731     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
732     path = getenv ("M17NDIR");
733     if (path)
734       {
735         i = strlen (path) + 7;
736         if (i > bufsize)
737           buf = alloca (i);
738         sprintf (buf, "%s/fonts", path);
739         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
740       }
741   }
742
743 #ifdef HAVE_FREETYPE
744   if (mfont__ft_init () < 0)
745     return -1;
746 #endif /* HAVE_FREETYPE */
747   if (mfont__flt_init () < 0)
748     return -1;
749
750   return 0;
751 }
752
753 void
754 mfont__fini ()
755 {
756   MPlist *plist;
757   int i;
758
759   mfont__flt_fini ();
760 #ifdef HAVE_FREETYPE
761   mfont__ft_fini ();
762 #endif /* HAVE_FREETYPE */
763
764   MPLIST_DO (plist, mfont_freetype_path)
765     free (MPLIST_VAL (plist));
766   M17N_OBJECT_UNREF (mfont_freetype_path);
767
768   if (font_resize_list)
769     {
770       MPLIST_DO (plist, font_resize_list)
771         free (MPLIST_VAL (plist));
772       M17N_OBJECT_UNREF (font_resize_list);
773       font_resize_list = NULL;
774     }
775   if (font_encoding_list)
776     {
777       MPLIST_DO (plist, font_encoding_list)
778         free (MPLIST_VAL (plist));
779       M17N_OBJECT_UNREF (font_encoding_list);
780       font_encoding_list = NULL;
781     }
782   for (i = 0; i <= MFONT_REGISTRY; i++)
783     MLIST_FREE1 (&mfont__property_table[i], names);
784 }
785
786 void
787 mfont__free_realized (MRealizedFont *rfont)
788 {
789   if (rfont->info)
790     M17N_OBJECT_UNREF (rfont->info);
791   free (rfont);
792 }
793
794
795 /* Compare FONT with REQUEST and return how much they differs.  If
796    FONT does not match with SPEC, return -1.  */
797
798 int
799 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
800 {
801   int score = 0;
802   int i = FONT_SCORE_PRIORITY_SIZE;
803
804   while (--i >= 0)
805     {
806       enum MFontProperty prop = font_score_priority[i];
807
808       if (request->property[prop] != 0)
809         {
810           int val = 0;
811
812           if (spec->property[prop] && font->property[prop]
813               && font->property[prop] != spec->property[prop])
814             return -1;
815           if (font->property[prop])
816             val = abs (font->property[prop] - request->property[prop]);
817           if (prop == MFONT_SIZE)
818             {
819               if (font->property[MFONT_RESY] == 0)
820                 /* This is a scalable font.  We prefer a bitmap font
821                    if the size matches exactly.  */
822                 score |= 1;
823               else
824                 score |= (val << font_score_shift_bits[MFONT_SIZE]
825                           | ((limited_size && val > 0) ? 0x400000 : 0));
826             }
827           else
828             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
829         }
830     }
831   return score;
832 }
833
834
835 /** Return 1 iff FONT matches SPEC.  */
836
837 int
838 mfont__match_p (MFont *font, MFont *spec, int prop)
839 {
840   for (; prop >= 0; prop--)
841     if (spec->property[prop] && font->property[prop]
842         && font->property[prop] != spec->property[prop])
843       return 0;
844   return 1;
845 }
846
847
848 void
849 mfont__set_spec_from_face (MFont *spec, MFace *face)
850 {
851   int i;
852
853   for (i = 0; i <= MFONT_ADSTYLE; i++)
854     mfont__set_property (spec, i, face->property[i]);
855   /* The value 1 is "iso8859-1".  */
856   spec->property[MFONT_REGISTRY] = 1;
857   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
858   spec->property[MFONT_RESY] = 0;
859 }
860
861
862 extern MSymbol
863 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
864 {
865   int i;
866   MSymbol spec_list[MFONT_REGISTRY + 1];
867   MSymbol registry;
868
869   MFONT_INIT (spec);
870   memset (spec_list, 0, sizeof spec_list);
871   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
872     {
873       if (! MPLIST_SYMBOL_P (plist))
874         MERROR (MERROR_FONT, Mnil);     
875       spec_list[i] = MPLIST_SYMBOL (plist);
876     }
877   registry = spec_list[i - 1];
878   mfont__set_property (spec, MFONT_REGISTRY, registry);
879   for (i -= 2; i >= 0; i--)
880     mfont__set_property (spec, i, spec_list[i]);
881   return registry;
882 }
883
884 MRealizedFont *
885 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
886                MSymbol layouter)
887 {
888   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
889   MPlist *plist;
890   MRealizedFont *best;
891   int i;
892   int mdebug_mask = MDEBUG_FONT;
893
894   if (registry == Mnil)
895     registry = Mt;
896
897   MPLIST_DO (plist, frame->realized_font_list)
898     {
899       best = MPLIST_VAL (plist);
900       if (MPLIST_KEY (plist) == registry
901           && ! memcmp (&best->spec, spec, sizeof (MFont))
902           && ! memcmp (&best->request, request, sizeof (MFont)))
903         {
904           if (best->layouter != layouter)
905             {
906               MRealizedFont *copy;
907
908               MSTRUCT_MALLOC (copy, MERROR_FONT);
909               *copy = *best;
910               copy->layouter = layouter;
911               if (copy->info)
912                 M17N_OBJECT_REF (copy->info);
913               mplist_add (frame->realized_font_list, registry, copy);
914               best = copy;
915             }
916           return best;
917         }
918     }
919
920   MDEBUG_PUSH_TIME ();
921   best = NULL;
922   MPLIST_DO (plist, frame->font_driver_list)
923     {
924       MFontDriver *driver = MPLIST_VAL (plist);
925       MRealizedFont *this
926         = (driver->select) (frame, spec, request, limited_size);
927
928       if (this)
929         {
930           this->driver = driver;
931           if (! best
932               || best->score < this->score)
933             {
934               if (best)
935                 mfont__free_realized (best);
936               best = this;
937               if (this->score == 0)
938                 break;
939             }
940         }
941     }
942
943   if (mdebug__flag & mdebug_mask)
944     {
945       char buf1[256], buf2[256];
946       MFont font = *spec;
947
948       for (i = 0; i < MFONT_PROPERTY_MAX; i++)
949         if (! font.property[i])
950           font.property[i] = request->property[i];
951       gen_font_name (buf2, &font);
952
953       if (best)
954         MDEBUG_PRINT_TIME ("FONT", 
955                            (stderr, " to select <%s> (%x)from <%s>.",
956                             gen_font_name (buf1, &best->font),
957                             best->score,
958                             buf2));
959       else
960         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
961       MDEBUG_POP_TIME ();
962     }
963
964   if (! best)
965     return NULL;
966   best->layouter = layouter;
967   mplist_add (frame->realized_font_list, registry, best);
968   return best;
969 }
970
971
972 /** Open a font specified in RFONT.  Return 0 if successfully
973     opened, otherwise return -1.  */
974
975 int
976 mfont__open (MRealizedFont *rfont)
977 {
978   MPlist *realized_font_list;
979   MSymbol registry = FONT_PROPERTY (&rfont->font, MFONT_REGISTRY);
980
981   if (rfont->status)
982     mdebug_hook ();
983
984   MPLIST_DO (realized_font_list, rfont->frame->realized_font_list)
985     {
986       MRealizedFont *this_rfont = MPLIST_VAL (realized_font_list);
987
988       if (this_rfont->status != 0
989           && MPLIST_KEY (realized_font_list) == registry
990           && ! memcmp (&this_rfont->font, &rfont->font, sizeof (MFont)))
991         {
992           if (rfont->info)
993             M17N_OBJECT_UNREF (rfont->info);
994           rfont->info = this_rfont->info;
995           M17N_OBJECT_REF (this_rfont->info);
996           rfont->status = this_rfont->status;
997           return (this_rfont->status > 0 ? 0 : -1);
998         }
999     }
1000
1001   return (rfont->driver->open) (rfont);
1002 }
1003
1004 void
1005 mfont__resize (MFont *spec, MFont *request)
1006 {
1007   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1008   MFontResize *resize;
1009   MPlist *plist;
1010
1011   if (! font_resize_list)
1012     load_font_resize_table ();
1013   if (! MPLIST_TAIL_P (font_resize_list))
1014     while (1)
1015       {
1016         plist = font_resize_list;
1017         while (registry ? (plist = mplist_find_by_key (plist, registry))
1018                : plist)
1019           {
1020             resize = (MFontResize *) MPLIST_VAL (plist);
1021             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1022               {
1023                 request->property[MFONT_SIZE]
1024                   = request->property[MFONT_SIZE] * resize->resize / 100;
1025                 return;
1026               }
1027             plist = MPLIST_NEXT (plist);
1028           }
1029         if (registry == Mt)
1030           break;
1031         registry = Mt;
1032       }
1033 }
1034
1035 /* Return 1 if C is encodable, 0, if C is not encodable, -1 if it
1036    can't be decided now.  */
1037
1038 int
1039 mfont__encodable_p (MRealizedFont *rfont, MSymbol layouter_name, int c)
1040 {
1041   MFontEncoding *encoding;
1042
1043   if (layouter_name != Mnil)
1044     return (mfont__flt_encode_char (layouter_name, c)
1045             != MCHAR_INVALID_CODE);
1046   if (! rfont->encoding)
1047     rfont->encoding = find_encoding (&rfont->spec);
1048   encoding = rfont->encoding;
1049   if (! encoding->repertory_charset)
1050     return -1;
1051   return (ENCODE_CHAR (encoding->repertory_charset, c) != MCHAR_INVALID_CODE);
1052 }
1053
1054 unsigned
1055 mfont__encode_char (MRealizedFont *rfont, int c)
1056 {
1057   MFontEncoding *encoding;
1058   unsigned code;
1059
1060   if (rfont->layouter != Mnil)
1061     return mfont__flt_encode_char (rfont->layouter, c);
1062   if (! rfont->encoding)
1063     rfont->encoding = find_encoding (&rfont->font);
1064   encoding = rfont->encoding;
1065   if (! encoding->encoding_charset)
1066     return MCHAR_INVALID_CODE;
1067   code = ENCODE_CHAR (encoding->encoding_charset, c);
1068   if (code == MCHAR_INVALID_CODE)
1069     return MCHAR_INVALID_CODE;
1070   if (! encoding->repertory_charset)
1071     return (rfont->driver->encode_char) (rfont, c, code);
1072   if (ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
1073     return MCHAR_INVALID_CODE;
1074   return code;
1075 }
1076
1077 void
1078 mfont__get_metric (MGlyphString *gstring, int from, int to)
1079 {
1080   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1081   MRealizedFont *rfont = from_g->rface->rfont;
1082
1083   for (g = from_g; g != to_g; g++)
1084     if (g->rface->rfont != rfont)
1085       {
1086         int idx = GLYPH_INDEX (g);
1087
1088         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1089         from_g = g;
1090         rfont = g->rface->rfont;
1091         from = idx;
1092       }
1093   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1094 }
1095
1096
1097 void
1098 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1099 {
1100   int numeric;
1101
1102   if (val == Mnil)
1103     numeric = 0;
1104   else
1105     {
1106       numeric = FONT_PROPERTY_NUMERIC (val, key);
1107       if (! numeric)
1108         {
1109           numeric = mfont__property_table[key].used;
1110           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1111           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1112         }
1113     }
1114   font->property[key] = numeric;
1115 }
1116
1117 void
1118 mfont__set_spec (MFont *font, MSymbol *attrs,
1119                  unsigned short size, unsigned short resy)
1120 {
1121   int i;
1122
1123   for (i = 0; i <= MFONT_REGISTRY; i++)
1124     mfont__set_property (font, i, attrs[i]);
1125   font->property[MFONT_SIZE] = size;
1126   font->property[MFONT_RESY] = resy;
1127 }
1128
1129 /*** @} */
1130 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1131
1132 \f
1133
1134 /* External API */
1135
1136 /*** @addtogroup m17nFont */
1137 /*** @{ */
1138 /*=*/
1139
1140 /***en @name Variables: Keys of font property.  */
1141 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1142 /*** @{ */
1143 /*=*/
1144
1145 /***en
1146     @brief Key of font property specifying foundry.
1147
1148     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1149     is used as a key of font property and face property.  The property
1150     value must be a symbol whose name is a foundry name of a font.  */
1151 /***ja
1152     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1153     
1154     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1155     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1156     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1157     */
1158
1159 MSymbol Mfoundry;
1160
1161 /***en
1162     @brief Key of font property specifying family.
1163
1164     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1165     used as a key of font property and face property.  The property
1166     value must be a symbol whose name is a family name of a font.  */ 
1167 /***ja
1168     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1169     
1170     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1171     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1172     ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1173     */
1174
1175 MSymbol Mfamily;
1176
1177 /***en
1178     @brief Key of font property specifying weight.
1179
1180     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1181     used as a key of font property and face property.  The property
1182     value must be a symbol whose name is a weight name of a font (e.g
1183     "medium", "bold").  */ 
1184 /***ja
1185     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1186     
1187     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1188     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1189     ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1190     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1191     */
1192
1193 MSymbol Mweight;
1194
1195 /***en
1196     @brief Key of font property specifying style.
1197
1198     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1199     used as a key of font property and face property.  The property
1200     value must be a symbol whose name is a style name of a font (e.g
1201     "r", "i", "o").  */ 
1202 /***ja
1203     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1204     
1205     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1206     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1207     ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1208     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1209     */
1210
1211 MSymbol Mstyle;
1212
1213 /***en
1214     @brief Key of font property specifying stretch.
1215
1216     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1217     is used as a key of font property and face property.  The property
1218     value must be a symbol whose name is a stretch name of a font (e.g
1219     "normal", "condensed").  */ 
1220 /***ja
1221     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1222     
1223     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1224     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1225     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1226     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1227     */
1228
1229 MSymbol Mstretch;
1230
1231 /***en
1232     @brief Key of font property specifying additional style.
1233
1234     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1235     is used as a key of font property and face property.  The property
1236     value must be a symbol whose name is an additional style name of a
1237     font (e.g "serif", "", "sans").  */ 
1238 /***ja
1239     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1240     
1241     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1242     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1243     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1244     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1245     */
1246
1247 MSymbol Madstyle;
1248
1249 /***en
1250     @brief Key of font property specifying registry.
1251
1252     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1253     and is used as a key of font property.  The property value must be
1254     a symbol whose name is a registry name a font registry
1255     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1256 /***ja
1257     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1258     
1259     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
1260     ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
1261     ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
1262     ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1263     */
1264
1265 MSymbol Mregistry;
1266
1267 /***en
1268     @brief Key of font property specifying size.
1269
1270     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1271     used as a key of font property and face property.  The property
1272     value must be an integer specifying a font design size in the unit
1273     of 1/10 point (on 100 dpi display).  */ 
1274 /***ja
1275     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1276     
1277     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
1278     ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1279     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó
1280     ¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1281     */
1282
1283 MSymbol Msize;
1284
1285 /***en
1286     @brief Key of font property specifying resolution.
1287
1288     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1289     is used as a key of font property and face property.  The property
1290     value must be an integer to specifying a font resolution in the
1291     unit of dots per inch (dpi).  */ 
1292 /***ja
1293     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1294     
1295     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü
1296     ¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é
1297     ¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ô
1298     ÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1299     */
1300
1301 MSymbol Mresolution;
1302
1303 /*=*/
1304 /*** @} */
1305 /*=*/
1306
1307 /***en
1308     @brief List of font files and directories that contain font files.
1309
1310     The variable @c mfont_freetype_path is a plist of FreeType font
1311     files and directories that contain FreeType font files.  Key of
1312     the element is @c Mstring, and the value is a string that
1313     represents a font file or a directory.
1314
1315     The macro M17N_INIT () sets up this variable to contain the
1316     sub-directory "fonts" of the m17n database and the environment
1317     variable "M17NDIR".  The first call of mframe () creates the
1318     internal list of the actually available fonts from this variable.
1319     Thus, an application program, if necessary, must modify the
1320     variable before calling mframe ().  If it is going to add a new
1321     element, value must be a string that can be safely freed.
1322
1323     If the m17n library is not configured to use the FreeType library,
1324     this variable is not used.  */
1325 /***ja
1326     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1327
1328     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
1329     ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
1330     ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1331
1332     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
1333      ¿ô "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1334      mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
1335      ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
1336      mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
1337      ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
1338      ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1339
1340     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
1341     ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1342
1343 MPlist *mfont_freetype_path;
1344
1345 /*=*/
1346
1347 /***en
1348     @brief Create a new font.
1349
1350     The mfont () function creates a new font object that has no
1351     property.
1352
1353     @return
1354     This function returns a pointer to the created font object.  */
1355 /***ja
1356     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1357
1358     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
1359     ¥È¤òºî¤ë¡£
1360
1361     @return
1362     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1363
1364 MFont *
1365 mfont ()
1366 {
1367   MFont *font;
1368
1369   MSTRUCT_CALLOC (font, MERROR_FONT);
1370   return font;
1371 }
1372
1373 /*=*/
1374
1375 /***en
1376     @brief Create a new font from fontname.
1377
1378     The mfont_from_name () function creates a new font object.  The
1379     properties are extracted fontname $NAME.
1380
1381     How to extract properties is window system dependent.  The m17n-X
1382     library parses $NAME as XLFD (X Logical Font Description).
1383
1384     @return
1385     If the operation was successful, this function returns a pointer
1386     to the created font.  Otherwise it returns @c NULL.  */
1387
1388 /***ja
1389     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1390
1391     ´Ø¿ô mfont_from_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
1392     ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1393
1394     ¤É¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤ò¼è¤ê½Ð¤¹¤«¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£
1395     m17n-X ¥é¥¤¥Ö¥é¥ê¤Î¾ì¹ç¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ
1396     $NAME ¤ò²òÀϤ¹¤ë¡£
1397
1398     @return
1399     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_from_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1400     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1401
1402 MFont *
1403 mfont_from_name (char *name)
1404 {
1405   MFontDriver *driver;
1406   MFont template, *font;
1407   MPlist *plist;
1408   
1409   if (! mframe_default)
1410     return NULL;
1411   MPLIST_DO (plist, mframe_default->font_driver_list)
1412     {
1413       driver = MPLIST_VAL (plist);
1414       if (driver->parse_name)
1415         break;
1416     }
1417   if (MPLIST_TAIL_P (plist))
1418     return NULL;
1419
1420   if ((*driver->parse_name) (name, &template))
1421     return NULL;
1422   MSTRUCT_CALLOC (font, MERROR_FONT);
1423   *font = template;
1424   return font;
1425 }
1426
1427 /*=*/
1428
1429 /***en
1430     @brief Make a copy of a font.
1431
1432     The mfont_copy () function returns a new copy of font $FONT.  */
1433 /***ja
1434     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1435
1436     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1437
1438 MFont *
1439 mfont_copy (MFont *font)
1440 {
1441   MFont *copy;
1442
1443   MSTRUCT_MALLOC (copy, MERROR_FONT);
1444   *copy = *font;
1445   return copy;
1446 }
1447
1448 /*=*/
1449
1450 /***en
1451     @brief Create a fontname from a font.
1452
1453     The mfont_name () function creates a fontname string created from
1454     font $FONT.
1455
1456     The syntax of fontname is window system dependent.  The m17n-X
1457     library returns a fontname conforming to XLFD (X Logical Font
1458     Description).
1459
1460     @return
1461     This function returns the created fontname string, which is not freed
1462     unless the user explicitly does so by free ().  */
1463 /***ja
1464     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1465
1466     ´Ø¿ô mfont_name () ¤Ï¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È
1467     $FONT ¤ò¸µ¤Ëºî¤ë¡£
1468
1469     ¥Õ¥©¥ó¥È̾¤Îʸˡ¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£m17n-X ¥é¥¤¥Ö¥é¥ê
1470     ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¥Õ¥©¥ó¥È̾¤òÊÖ¤¹¡£
1471
1472     @return 
1473     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶
1474     ¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1475
1476 char *
1477 mfont_name (MFont *font)
1478 {
1479   MFontDriver *driver;
1480   MPlist *plist;
1481   
1482   if (! mframe_default)
1483     return NULL;
1484   MPLIST_DO (plist, mframe_default->font_driver_list)
1485     {
1486       driver = MPLIST_VAL (plist);
1487       if (driver->build_name)
1488         break;
1489     }
1490   if (MPLIST_TAIL_P (plist))
1491     return NULL;
1492
1493   return (*driver->build_name) (font);
1494 }
1495
1496 /*=*/
1497
1498 /***en
1499     @brief Get a property value of a font.
1500
1501     The mfont_get_prop () function gets the value of $KEY property of
1502     font $FONT.  $KEY must be one of the following symbols:
1503
1504         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1505         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1506
1507     @return
1508     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1509     Madstyle, or @c Mregistry, this function returns the
1510     corresponding value as a symbol.  If the font does not have $KEY
1511     property, it returns @c Mnil.
1512     If $KEY is @c Msize or @c Mresolution, this function returns the
1513     corresponding value as an integer.  If the font does not have $KEY
1514     property, it returns 0.
1515     If $KEY is something else, it returns @c NULL and assigns an error
1516     code to the external variable #merror_code.  */
1517
1518 /***ja
1519     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1520
1521     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1522     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1523     ¤Ð¤Ê¤é¤Ê¤¤¡£
1524
1525         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1526         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1527
1528     @return 
1529     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1530     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
1531     ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1532     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
1533     ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
1534     ÊÖ¤¹¡£
1535     $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1536     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1537
1538 void *
1539 mfont_get_prop (MFont *font, MSymbol key)
1540 {
1541   if (key == Mfoundry)
1542     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1543   if (key == Mfamily)
1544     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1545   if (key == Mweight)
1546     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1547   if (key == Mstyle)
1548     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1549   if (key == Mstretch)
1550     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1551   if (key == Madstyle)
1552     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1553   if (key == Mregistry)
1554     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1555   if (key == Msize)
1556     {
1557       int size = font->property[MFONT_SIZE];
1558       return (void *) size;
1559     }
1560   if (key == Mresolution)
1561     {
1562       int resy = font->property[MFONT_RESY];
1563       return (void *) resy;
1564     }
1565
1566   MERROR (MERROR_FONT, NULL);
1567 }
1568
1569
1570 /*=*/
1571 /***en
1572     @brief Put a property value to a font.
1573
1574     The mfont_put_prop () function puts a font property whose key is
1575     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1576     following symbols:
1577
1578         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1579         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1580
1581     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1582     Otherwise, $VAL must be a symbol.  */
1583 /***ja
1584     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1585
1586     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
1587     ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
1588     ¤ë¡£
1589
1590         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1591         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1592
1593     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
1594     ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1595
1596 int
1597 mfont_put_prop (MFont *font, MSymbol key, void *val)
1598 {
1599   if (key == Mfoundry)
1600     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1601   else if (key == Mfamily)
1602     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1603   else if (key == Mweight)
1604     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1605   else if (key == Mstyle)
1606     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1607   else if (key == Mstretch)
1608     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1609   else if (key == Madstyle)
1610     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1611   else if (key == Mregistry)
1612     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1613   else if (key == Msize)
1614     {
1615       unsigned size = (unsigned) val;
1616       font->property[MFONT_SIZE] = size;
1617     }
1618   else if (key == Mresolution)
1619     {
1620       unsigned resy = (unsigned) val;
1621       font->property[MFONT_RESY] =  resy;
1622     }
1623   else
1624     MERROR (MERROR_FONT, -1);
1625   return 0;
1626 }
1627
1628 /*=*/
1629
1630 /***en
1631     @brief Return the font selection priority.
1632
1633     The mfont_selection_priority () function returns a newly created
1634     array of six symbols.  The elements are the following
1635     keys of font properties ordered by priority.
1636
1637         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1638         @c Madstyle, @c Msize.
1639
1640    The m17n library selects the best matching font according to the
1641    order of this array.  A font that has a different value for a
1642    property of lower priority is preferred to a font that has a
1643    different value for a property of higher priority.  */
1644 /***ja
1645     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
1646
1647     ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
1648     ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
1649     ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
1650
1651         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1652         @c Madstyle, @c Msize.
1653
1654    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1655    Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
1656    Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
1657    */
1658
1659 MSymbol *
1660 mfont_selection_priority ()
1661 {
1662   MSymbol *keys;
1663   int i;
1664
1665   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1666   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1667     {
1668       enum MFontProperty prop = font_score_priority[i];
1669
1670       if (prop == MFONT_SIZE)
1671         keys[i] = Msize;
1672       else if (prop == MFONT_ADSTYLE)
1673         keys[i] = Madstyle;
1674       else if (prop == MFONT_FAMILY)
1675         keys[i] = Mfamily;
1676       else if (prop == MFONT_WEIGHT)
1677         keys[i] = Mweight;
1678       else if (prop == MFONT_STYLE)
1679         keys[i] = Mstyle;
1680       else if (prop == MFONT_STRETCH)
1681         keys[i] = Mstretch;
1682       else
1683         keys[i] = Mfoundry;
1684     }
1685   return keys;
1686 }
1687
1688 /*=*/
1689
1690 /***en
1691     @brief Set the font selection priority.
1692
1693     The mfont_set_selection_priority () function sets font selection
1694     priority according to $KEYS, which is an array of six symbols.
1695     Each element must be one of the below.  No two elements must be
1696     the same.
1697
1698         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1699         @c Madstyle, @c Msize.
1700
1701     See the documentation of the function mfont_selection_priority ()
1702     for details.  */
1703 /***ja
1704     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1705
1706     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1707     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
1708     ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1709
1710         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1711         @c Madstyle, @c Msize.
1712
1713     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1714      */
1715
1716 int
1717 mfont_set_selection_priority (MSymbol *keys)
1718 {
1719   int priority[FONT_SCORE_PRIORITY_SIZE];
1720   int i, j;
1721
1722   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1723     {
1724       enum MFontProperty prop;
1725
1726       if (*keys == Msize)
1727         prop = MFONT_SIZE;
1728       else if (*keys == Madstyle)
1729         prop = MFONT_ADSTYLE;
1730       else if (*keys == Mfamily)
1731         prop = MFONT_FAMILY;
1732       else if (*keys == Mweight)
1733         prop = MFONT_WEIGHT;
1734       else if (*keys == Mstyle)
1735         prop = MFONT_STYLE;
1736       else if (*keys == Mstretch)
1737         prop = MFONT_STRETCH;
1738       else if (*keys == Mfoundry)
1739         prop = MFONT_FOUNDRY;
1740       else
1741         /* Invalid element.  */
1742         return -1;
1743       for (j = 0; j < i; j++)
1744         if (priority[j] == prop)
1745           /* Duplicated element.  */
1746           return -1;
1747       priority[i] = prop;
1748     }
1749   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1750     font_score_priority[i] = priority[i];
1751   return 0;
1752 }
1753
1754 /*=*/
1755
1756 /***en
1757     @brief Find a font.
1758
1759     The mfont_find () function returns a pointer to the available font
1760     that matches best the specification $SPEC on frame $FRAME.
1761
1762     $SCORE, if not NULL, must point to a place to store the score
1763     value that indicates how well the found font matches to $SPEC.  The
1764     smaller score means a better match.  */
1765 /***ja
1766     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1767
1768     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1769     ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1770
1771     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
1772     ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
1773     ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1774     */
1775
1776 MFont *
1777 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1778 {
1779   MFont spec_copy;
1780   MRealizedFont *rfont;
1781
1782   MFONT_INIT (&spec_copy);
1783   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1784
1785   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1786   if (!rfont)
1787     return NULL;
1788   if (score)
1789     *score = rfont->score;
1790   return &rfont->font;
1791 }
1792
1793 /*=*/
1794 /***en
1795     @brief Set encoding of a font.
1796
1797     The mfont_set_encoding () function sets the encoding information
1798     of font $FONT.
1799
1800     $ENCODING_NAME is a symbol representing a charset that has the
1801     same encoding as the font.
1802
1803     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1804     has the same repertory as the font.  If it is @c Mnil, whether a
1805     specific character is supported by the font is asked to each font
1806     driver.
1807
1808     @return
1809     If the operation was successful, this function returns 0.
1810     Otherwise it returns -1 and assigns an error code to the external
1811     variable #merror_code.  */
1812 /***ja
1813     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1814
1815     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
1816     ¤òÀßÄꤹ¤ë¡£
1817
1818     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
1819     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1820
1821     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
1822     ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
1823     »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
1824     Ì䤤¹ç¤ï¤»¤ë¡£
1825
1826     @return
1827     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
1828     ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1829
1830
1831 int
1832 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1833 {
1834   MCharset *encoding_charset = MCHARSET (encoding_name);
1835   MCharset *repertory_charset;
1836   MSymbol registry;
1837   MFontEncoding *encoding;
1838   MPlist *plist;
1839
1840   if (! encoding_charset)
1841     MERROR (MERROR_FONT, -1);
1842   if (repertory_name != Mnil)
1843     {
1844       repertory_charset = MCHARSET (repertory_name);
1845       if (! repertory_charset)
1846         MERROR (MERROR_FONT, -1);
1847     }
1848   else
1849     repertory_charset = NULL;
1850
1851   MSTRUCT_CALLOC (encoding, MERROR_FONT);
1852   encoding->spec = *font;
1853   encoding->encoding_name = encoding_name;
1854   encoding->encoding_charset = encoding_charset;
1855   encoding->repertory_name = repertory_name;
1856   encoding->repertory_charset = repertory_charset;
1857   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1858   if (registry == Mnil)
1859     registry = Mt;
1860   if (! font_encoding_list)
1861     load_font_encoding_table ();
1862   mplist_push (font_encoding_list, registry, encoding);
1863   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
1864     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
1865                   sizeof (MFont)))
1866       {
1867         mplist_pop (plist);
1868         break;
1869       }
1870   return 0;
1871 }
1872
1873 /*** @} */
1874
1875 /*** @addtogroup m17nDebug */
1876 /*=*/
1877 /*** @{ */
1878
1879 /***en
1880     @brief Dump a font.
1881
1882     The mdebug_dump_font () function prints font $FONT in a human readable
1883     way to the stderr.
1884
1885     @return
1886     This function returns $FONT.  */
1887 /***ja
1888     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
1889
1890     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
1891     ·Á¤Ç°õºþ¤¹¤ë¡£
1892
1893     @return
1894     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
1895
1896 MFont *
1897 mdebug_dump_font (MFont *font)
1898 {
1899   MFontDriver *driver;
1900   MPlist *plist;
1901   char *name;
1902   
1903   if (! mframe_default)
1904     return NULL;
1905   MPLIST_DO (plist, mframe_default->font_driver_list)
1906     {
1907       driver = MPLIST_VAL (plist);
1908       if (driver->build_name)
1909         break;
1910     }
1911   if (MPLIST_TAIL_P (plist))
1912     return NULL;
1913
1914   name = (*driver->build_name) (font);
1915   fprintf (stderr, "%s", name);
1916   free (name);
1917   return font;
1918 }
1919
1920 /*** @} */
1921
1922 /*
1923   Local Variables:
1924   coding: euc-japan
1925   End:
1926 */