(mface__init): Exchange foreground and background of
[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   mfont__driver_list = mplist ();
706
707   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
708      of a score is a flag for a scalable font (see the documentation
709      of mfont_score).  */
710   i = FONT_SCORE_PRIORITY_SIZE - 1;
711   for (shift = 1; i >= 0; i--)
712     {
713       font_score_shift_bits[font_score_priority[i]] = shift;
714       if (font_score_priority[i] == MFONT_SIZE)
715         shift += 16;
716       else
717         shift += 2;
718     }
719
720   MFONT_INIT (&default_encoding.spec);
721   default_encoding.encoding_name = Mnil;
722   default_encoding.encoding_charset = NULL;
723   default_encoding.repertory_name = Mnil;
724   default_encoding.repertory_charset = NULL;
725   {
726     char *path, *buf;
727     int bufsize;
728
729     mfont_freetype_path = mplist ();
730     bufsize = strlen (M17NDIR) + 7;
731     buf = alloca (bufsize);
732     sprintf (buf, "%s/fonts", M17NDIR);
733     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
734     path = getenv ("M17NDIR");
735     if (path)
736       {
737         i = strlen (path) + 7;
738         if (i > bufsize)
739           buf = alloca (i);
740         sprintf (buf, "%s/fonts", path);
741         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
742       }
743   }
744
745 #ifdef HAVE_FREETYPE
746   if (mfont__ft_init () < 0)
747     return -1;
748 #endif /* HAVE_FREETYPE */
749   if (mfont__flt_init () < 0)
750     return -1;
751
752   return 0;
753 }
754
755 void
756 mfont__fini ()
757 {
758   MPlist *plist;
759   int i;
760
761   mfont__flt_fini ();
762 #ifdef HAVE_FREETYPE
763   mfont__ft_fini ();
764 #endif /* HAVE_FREETYPE */
765
766   MPLIST_DO (plist, mfont_freetype_path)
767     free (MPLIST_VAL (plist));
768   M17N_OBJECT_UNREF (mfont_freetype_path);
769
770   M17N_OBJECT_UNREF (mfont__driver_list);
771
772   if (font_resize_list)
773     {
774       MPLIST_DO (plist, font_resize_list)
775         free (MPLIST_VAL (plist));
776       M17N_OBJECT_UNREF (font_resize_list);
777       font_resize_list = NULL;
778     }
779   if (font_encoding_list)
780     {
781       MPLIST_DO (plist, font_encoding_list)
782         free (MPLIST_VAL (plist));
783       M17N_OBJECT_UNREF (font_encoding_list);
784       font_encoding_list = NULL;
785     }
786   for (i = 0; i <= MFONT_REGISTRY; i++)
787     MLIST_FREE1 (&mfont__property_table[i], names);
788 }
789
790 void
791 mfont__free_realized (MRealizedFont *rfont)
792 {
793   if (rfont->info)
794     M17N_OBJECT_UNREF (rfont->info);
795   free (rfont);
796 }
797
798
799 /* Compare FONT with REQUEST and return how much they differs.  If
800    FONT does not match with SPEC, return -1.  */
801
802 int
803 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
804 {
805   int score = 0;
806   int i = FONT_SCORE_PRIORITY_SIZE;
807
808   while (--i >= 0)
809     {
810       enum MFontProperty prop = font_score_priority[i];
811
812       if (request->property[prop] != 0)
813         {
814           int val = 0;
815
816           if (spec->property[prop] && font->property[prop]
817               && font->property[prop] != spec->property[prop])
818             return -1;
819           if (font->property[prop])
820             val = abs (font->property[prop] - request->property[prop]);
821           if (prop == MFONT_SIZE)
822             {
823               if (font->property[MFONT_RESY] == 0)
824                 /* This is a scalable font.  We prefer a bitmap font
825                    if the size matches exactly.  */
826                 score |= 1;
827               else
828                 score |= (val << font_score_shift_bits[MFONT_SIZE]
829                           | ((limited_size && val > 0) ? 0x400000 : 0));
830             }
831           else
832             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
833         }
834     }
835   return score;
836 }
837
838
839 /** Return 1 iff FONT matches SPEC.  */
840
841 int
842 mfont__match_p (MFont *font, MFont *spec, int prop)
843 {
844   for (; prop >= 0; prop--)
845     if (spec->property[prop] && font->property[prop]
846         && font->property[prop] != spec->property[prop])
847       return 0;
848   return 1;
849 }
850
851
852 void
853 mfont__set_spec_from_face (MFont *spec, MFace *face)
854 {
855   int i;
856
857   for (i = 0; i <= MFONT_ADSTYLE; i++)
858     mfont__set_property (spec, i, face->property[i]);
859   /* The value 1 is "iso8859-1".  */
860   spec->property[MFONT_REGISTRY] = 1;
861   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
862   spec->property[MFONT_RESY] = 0;
863 }
864
865
866 extern MSymbol
867 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
868 {
869   int i;
870   MSymbol spec_list[MFONT_REGISTRY + 1];
871   MSymbol registry;
872
873   MFONT_INIT (spec);
874   memset (spec_list, 0, sizeof spec_list);
875   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
876     {
877       if (! MPLIST_SYMBOL_P (plist))
878         MERROR (MERROR_FONT, Mnil);     
879       spec_list[i] = MPLIST_SYMBOL (plist);
880     }
881   registry = spec_list[i - 1];
882   mfont__set_property (spec, MFONT_REGISTRY, registry);
883   for (i -= 2; i >= 0; i--)
884     mfont__set_property (spec, i, spec_list[i]);
885   return registry;
886 }
887
888 MRealizedFont *
889 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
890                MSymbol layouter)
891 {
892   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
893   MPlist *plist;
894   MRealizedFont *best;
895   int i;
896   int mdebug_mask = MDEBUG_FONT;
897
898   if (registry == Mnil)
899     registry = Mt;
900
901   MPLIST_DO (plist, frame->realized_font_list)
902     {
903       best = MPLIST_VAL (plist);
904       if (MPLIST_KEY (plist) == registry
905           && ! memcmp (&best->spec, spec, sizeof (MFont))
906           && ! memcmp (&best->request, request, sizeof (MFont)))
907         {
908           if (best->layouter != layouter)
909             {
910               MRealizedFont *copy;
911
912               MSTRUCT_MALLOC (copy, MERROR_FONT);
913               *copy = *best;
914               copy->layouter = layouter;
915               if (copy->info)
916                 M17N_OBJECT_REF (copy->info);
917               mplist_add (frame->realized_font_list, registry, copy);
918               best = copy;
919             }
920           return best;
921         }
922     }
923
924   MDEBUG_PUSH_TIME ();
925   best = NULL;
926   MPLIST_DO (plist, mfont__driver_list)
927     {
928       MFontDriver *driver = MPLIST_VAL (plist);
929       MRealizedFont *this
930         = (driver->select) (frame, spec, request, limited_size);
931
932       if (this
933           && (! best
934               || best->score < this->score))
935         {
936           free (best);
937           best = this;
938           if (this->score == 0)
939             break;
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> from <%s>.",
956                             gen_font_name (buf1, &best->font),
957                             buf2));
958       else
959         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
960       MDEBUG_POP_TIME ();
961     }
962
963   if (! best)
964     return NULL;
965   best->layouter = layouter;
966   mplist_add (frame->realized_font_list, registry, best);
967   return best;
968 }
969
970
971 /** Open a font specified in RFONT.  Return 0 if successfully
972     opened, otherwise return -1.  */
973
974 int
975 mfont__open (MRealizedFont *rfont)
976 {
977   MPlist *realized_font_list;
978   MSymbol registry = FONT_PROPERTY (&rfont->font, MFONT_REGISTRY);
979
980   if (rfont->status)
981     mdebug_hook ();
982
983   MPLIST_DO (realized_font_list, rfont->frame->realized_font_list)
984     {
985       MRealizedFont *this_rfont = MPLIST_VAL (realized_font_list);
986
987       if (this_rfont->status != 0
988           && MPLIST_KEY (realized_font_list) == registry
989           && ! memcmp (&this_rfont->font, &rfont->font, sizeof (MFont)))
990         {
991           if (rfont->info)
992             M17N_OBJECT_UNREF (rfont->info);
993           rfont->info = this_rfont->info;
994           M17N_OBJECT_REF (this_rfont->info);
995           rfont->status = this_rfont->status;
996           return (this_rfont->status > 0 ? 0 : -1);
997         }
998     }
999
1000   return (rfont->driver->open) (rfont);
1001 }
1002
1003 void
1004 mfont__close (MRealizedFont *rfont)
1005 {
1006   (rfont->driver->close) (rfont);
1007 }
1008
1009 void
1010 mfont__resize (MFont *spec, MFont *request)
1011 {
1012   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1013   MFontResize *resize;
1014   MPlist *plist;
1015
1016   if (! font_resize_list)
1017     load_font_resize_table ();
1018   if (! MPLIST_TAIL_P (font_resize_list))
1019     while (1)
1020       {
1021         plist = font_resize_list;
1022         while (registry ? (plist = mplist_find_by_key (plist, registry))
1023                : plist)
1024           {
1025             resize = (MFontResize *) MPLIST_VAL (plist);
1026             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1027               {
1028                 request->property[MFONT_SIZE]
1029                   = request->property[MFONT_SIZE] * resize->resize / 100;
1030                 return;
1031               }
1032             plist = MPLIST_NEXT (plist);
1033           }
1034         if (registry == Mt)
1035           break;
1036         registry = Mt;
1037       }
1038 }
1039
1040 /* Return 1 if C is encodable, 0, if C is not encodable, -1 if it
1041    can't be decided now.  */
1042
1043 int
1044 mfont__encodable_p (MRealizedFont *rfont, MSymbol layouter_name, int c)
1045 {
1046   MFontEncoding *encoding;
1047
1048   if (layouter_name != Mnil)
1049     return (mfont__flt_encode_char (layouter_name, c)
1050             != MCHAR_INVALID_CODE);
1051   if (! rfont->encoding)
1052     rfont->encoding = find_encoding (&rfont->spec);
1053   encoding = rfont->encoding;
1054   if (! encoding->repertory_charset)
1055     return -1;
1056   return (ENCODE_CHAR (encoding->repertory_charset, c) != MCHAR_INVALID_CODE);
1057 }
1058
1059 unsigned
1060 mfont__encode_char (MRealizedFont *rfont, int c)
1061 {
1062   MFontEncoding *encoding;
1063   unsigned code;
1064
1065   if (rfont->layouter != Mnil)
1066     return mfont__flt_encode_char (rfont->layouter, c);
1067   if (! rfont->encoding)
1068     rfont->encoding = find_encoding (&rfont->font);
1069   encoding = rfont->encoding;
1070   if (! encoding->encoding_charset)
1071     return MCHAR_INVALID_CODE;
1072   code = ENCODE_CHAR (encoding->encoding_charset, c);
1073   if (code == MCHAR_INVALID_CODE)
1074     return MCHAR_INVALID_CODE;
1075   if (! encoding->repertory_charset)
1076     return (rfont->driver->encode_char) (rfont, c, code);
1077   if (ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
1078     return MCHAR_INVALID_CODE;
1079   return code;
1080 }
1081
1082 void
1083 mfont__get_metric (MGlyphString *gstring, int from, int to)
1084 {
1085   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1086   MRealizedFont *rfont = from_g->rface->rfont;
1087
1088   for (g = from_g; g != to_g; g++)
1089     if (g->rface->rfont != rfont)
1090       {
1091         int idx = GLYPH_INDEX (g);
1092
1093         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1094         from_g = g;
1095         rfont = g->rface->rfont;
1096         from = idx;
1097       }
1098   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1099 }
1100
1101
1102 void
1103 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1104 {
1105   int numeric;
1106
1107   if (val == Mnil)
1108     numeric = 0;
1109   else
1110     {
1111       numeric = FONT_PROPERTY_NUMERIC (val, key);
1112       if (! numeric)
1113         {
1114           numeric = mfont__property_table[key].used;
1115           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1116           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1117         }
1118     }
1119   font->property[key] = numeric;
1120 }
1121
1122 void
1123 mfont__set_spec (MFont *font, MSymbol *attrs,
1124                  unsigned short size, unsigned short resy)
1125 {
1126   int i;
1127
1128   for (i = 0; i <= MFONT_REGISTRY; i++)
1129     mfont__set_property (font, i, attrs[i]);
1130   font->property[MFONT_SIZE] = size;
1131   font->property[MFONT_RESY] = resy;
1132 }
1133
1134 /*** @} */
1135 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1136
1137 \f
1138
1139 /* External API */
1140
1141 /*** @addtogroup m17nFont */
1142 /*** @{ */
1143 /*=*/
1144
1145 /***en @name Variables: Keys of font property.  */
1146 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1147 /*** @{ */
1148 /*=*/
1149
1150 /***en
1151     @brief Key of font property specifying foundry.
1152
1153     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1154     is used as a key of font property and face property.  The property
1155     value must be a symbol whose name is a foundry name of a font.  */
1156 /***ja
1157     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1158     
1159     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1160     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1161     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1162     */
1163
1164 MSymbol Mfoundry;
1165
1166 /***en
1167     @brief Key of font property specifying family.
1168
1169     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1170     used as a key of font property and face property.  The property
1171     value must be a symbol whose name is a family name of a font.  */ 
1172 /***ja
1173     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1174     
1175     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1176     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1177     ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1178     */
1179
1180 MSymbol Mfamily;
1181
1182 /***en
1183     @brief Key of font property specifying weight.
1184
1185     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1186     used as a key of font property and face property.  The property
1187     value must be a symbol whose name is a weight name of a font (e.g
1188     "medium", "bold").  */ 
1189 /***ja
1190     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1191     
1192     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1193     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1194     ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1195     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1196     */
1197
1198 MSymbol Mweight;
1199
1200 /***en
1201     @brief Key of font property specifying style.
1202
1203     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1204     used as a key of font property and face property.  The property
1205     value must be a symbol whose name is a style name of a font (e.g
1206     "r", "i", "o").  */ 
1207 /***ja
1208     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1209     
1210     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1211     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1212     ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1213     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1214     */
1215
1216 MSymbol Mstyle;
1217
1218 /***en
1219     @brief Key of font property specifying stretch.
1220
1221     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1222     is used as a key of font property and face property.  The property
1223     value must be a symbol whose name is a stretch name of a font (e.g
1224     "normal", "condensed").  */ 
1225 /***ja
1226     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1227     
1228     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1229     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1230     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1231     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1232     */
1233
1234 MSymbol Mstretch;
1235
1236 /***en
1237     @brief Key of font property specifying additional style.
1238
1239     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1240     is used as a key of font property and face property.  The property
1241     value must be a symbol whose name is an additional style name of a
1242     font (e.g "serif", "", "sans").  */ 
1243 /***ja
1244     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1245     
1246     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1247     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1248     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1249     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1250     */
1251
1252 MSymbol Madstyle;
1253
1254 /***en
1255     @brief Key of font property specifying registry.
1256
1257     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1258     and is used as a key of font property.  The property value must be
1259     a symbol whose name is a registry name a font registry
1260     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1261 /***ja
1262     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1263     
1264     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
1265     ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
1266     ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
1267     ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1268     */
1269
1270 MSymbol Mregistry;
1271
1272 /***en
1273     @brief Key of font property specifying size.
1274
1275     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1276     used as a key of font property and face property.  The property
1277     value must be an integer specifying a font design size in the unit
1278     of 1/10 point (on 100 dpi display).  */ 
1279 /***ja
1280     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1281     
1282     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
1283     ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1284     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó
1285     ¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1286     */
1287
1288 MSymbol Msize;
1289
1290 /***en
1291     @brief Key of font property specifying resolution.
1292
1293     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1294     is used as a key of font property and face property.  The property
1295     value must be an integer to specifying a font resolution in the
1296     unit of dots per inch (dpi).  */ 
1297 /***ja
1298     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1299     
1300     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü
1301     ¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é
1302     ¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ô
1303     ÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1304     */
1305
1306 MSymbol Mresolution;
1307
1308 /*=*/
1309 /*** @} */
1310 /*=*/
1311
1312 /***en
1313     @brief List of font files and directories that contain font files.
1314
1315     The variable @c mfont_freetype_path is a plist of FreeType font
1316     files and directories that contain FreeType font files.  Key of
1317     the element is @c Mstring, and the value is a string that
1318     represents a font file or a directory.
1319
1320     The macro M17N_INIT () sets up this variable to contain the
1321     sub-directory "fonts" of the m17n database and the environment
1322     variable "M17NDIR".  The first call of mframe () creates the
1323     internal list of the actually available fonts from this variable.
1324     Thus, an application program, if necessary, must modify the
1325     variable before calling mframe ().  If it is going to add a new
1326     element, value must be a string that can be safely freed.
1327
1328     If the m17n library is not configured to use the FreeType library,
1329     this variable is not used.  */
1330 /***ja
1331     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1332
1333     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
1334     ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
1335     ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1336
1337     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
1338      ¿ô "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1339      mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
1340      ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
1341      mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
1342      ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
1343      ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1344
1345     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
1346     ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1347
1348 MPlist *mfont_freetype_path;
1349
1350 /*=*/
1351
1352 /***en
1353     @brief Create a new font.
1354
1355     The mfont () function creates a new font object that has no
1356     property.
1357
1358     @return
1359     This function returns a pointer to the created font object.  */
1360 /***ja
1361     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1362
1363     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
1364     ¥È¤òºî¤ë¡£
1365
1366     @return
1367     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1368
1369 MFont *
1370 mfont ()
1371 {
1372   MFont *font;
1373
1374   MSTRUCT_CALLOC (font, MERROR_FONT);
1375   return font;
1376 }
1377
1378 /*=*/
1379
1380 /***en
1381     @brief Create a new font from fontname.
1382
1383     The mfont_from_name () function creates a new font object.  The
1384     properties are extracted fontname $NAME.
1385
1386     How to extract properties is window system dependent.  The m17n-X
1387     library parses $NAME as XLFD (X Logical Font Description).
1388
1389     @return
1390     If the operation was successful, this function returns a pointer
1391     to the created font.  Otherwise it returns @c NULL.  */
1392
1393 /***ja
1394     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1395
1396     ´Ø¿ô mfont_from_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
1397     ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1398
1399     ¤É¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤ò¼è¤ê½Ð¤¹¤«¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£
1400     m17n-X ¥é¥¤¥Ö¥é¥ê¤Î¾ì¹ç¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ
1401     $NAME ¤ò²òÀϤ¹¤ë¡£
1402
1403     @return
1404     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_from_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1405     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1406
1407 MFont *
1408 mfont_from_name (char *name)
1409 {
1410   MFont template, *font;
1411
1412   if (mwin__parse_font_name (name, &template) < 0)
1413     return NULL;
1414   MSTRUCT_CALLOC (font, MERROR_FONT);
1415   *font = template;
1416   return font;
1417 }
1418
1419 /*=*/
1420
1421 /***en
1422     @brief Make a copy of a font.
1423
1424     The mfont_copy () function returns a new copy of font $FONT.  */
1425 /***ja
1426     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1427
1428     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1429
1430 MFont *
1431 mfont_copy (MFont *font)
1432 {
1433   MFont *copy;
1434
1435   MSTRUCT_MALLOC (copy, MERROR_FONT);
1436   *copy = *font;
1437   return copy;
1438 }
1439
1440 /*=*/
1441
1442 /***en
1443     @brief Create a fontname from a font.
1444
1445     The mfont_name () function creates a fontname string created from
1446     font $FONT.
1447
1448     The syntax of fontname is window system dependent.  The m17n-X
1449     library returns a fontname conforming to XLFD (X Logical Font
1450     Description).
1451
1452     @return
1453     This function returns the created fontname string, which is not freed
1454     unless the user explicitly does so by free ().  */
1455 /***ja
1456     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1457
1458     ´Ø¿ô mfont_name () ¤Ï¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È
1459     $FONT ¤ò¸µ¤Ëºî¤ë¡£
1460
1461     ¥Õ¥©¥ó¥È̾¤Îʸˡ¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£m17n-X ¥é¥¤¥Ö¥é¥ê
1462     ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¥Õ¥©¥ó¥È̾¤òÊÖ¤¹¡£
1463
1464     @return 
1465     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶
1466     ¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1467
1468 char *
1469 mfont_name (MFont *font)
1470 {
1471   return mwin__build_font_name (font);
1472 }
1473
1474 /*=*/
1475
1476 /***en
1477     @brief Get a property value of a font.
1478
1479     The mfont_get_prop () function gets the value of $KEY property of
1480     font $FONT.  $KEY must be one of the following symbols:
1481
1482         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1483         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1484
1485     @return
1486     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1487     Madstyle, or @c Mregistry, this function returns the
1488     corresponding value as a symbol.  If the font does not have $KEY
1489     property, it returns @c Mnil.
1490     If $KEY is @c Msize or @c Mresolution, this function returns the
1491     corresponding value as an integer.  If the font does not have $KEY
1492     property, it returns 0.
1493     If $KEY is something else, it returns @c NULL and assigns an error
1494     code to the external variable #merror_code.  */
1495
1496 /***ja
1497     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1498
1499     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1500     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1501     ¤Ð¤Ê¤é¤Ê¤¤¡£
1502
1503         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1504         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1505
1506     @return 
1507     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1508     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
1509     ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1510     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
1511     ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
1512     ÊÖ¤¹¡£
1513     $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1514     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1515
1516 void *
1517 mfont_get_prop (MFont *font, MSymbol key)
1518 {
1519   if (key == Mfoundry)
1520     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1521   if (key == Mfamily)
1522     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1523   if (key == Mweight)
1524     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1525   if (key == Mstyle)
1526     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1527   if (key == Mstretch)
1528     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1529   if (key == Madstyle)
1530     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1531   if (key == Mregistry)
1532     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1533   if (key == Msize)
1534     {
1535       int size = font->property[MFONT_SIZE];
1536       return (void *) size;
1537     }
1538   if (key == Mresolution)
1539     {
1540       int resy = font->property[MFONT_RESY];
1541       return (void *) resy;
1542     }
1543
1544   MERROR (MERROR_FONT, NULL);
1545 }
1546
1547
1548 /*=*/
1549 /***en
1550     @brief Put a property value to a font.
1551
1552     The mfont_put_prop () function puts a font property whose key is
1553     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1554     following symbols:
1555
1556         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1557         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1558
1559     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1560     Otherwise, $VAL must be a symbol.  */
1561 /***ja
1562     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1563
1564     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
1565     ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
1566     ¤ë¡£
1567
1568         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1569         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1570
1571     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
1572     ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1573
1574 int
1575 mfont_put_prop (MFont *font, MSymbol key, void *val)
1576 {
1577   if (key == Mfoundry)
1578     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1579   else if (key == Mfamily)
1580     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1581   else if (key == Mweight)
1582     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1583   else if (key == Mstyle)
1584     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1585   else if (key == Mstretch)
1586     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1587   else if (key == Madstyle)
1588     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1589   else if (key == Mregistry)
1590     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1591   else if (key == Msize)
1592     {
1593       unsigned size = (unsigned) val;
1594       font->property[MFONT_SIZE] = size;
1595     }
1596   else if (key == Mresolution)
1597     {
1598       unsigned resy = (unsigned) val;
1599       font->property[MFONT_RESY] =  resy;
1600     }
1601   else
1602     MERROR (MERROR_FONT, -1);
1603   return 0;
1604 }
1605
1606 /*=*/
1607
1608 /***en
1609     @brief Return the font selection priority.
1610
1611     The mfont_selection_priority () function returns a newly created
1612     array of six symbols.  The elements are the following
1613     keys of font properties ordered by priority.
1614
1615         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1616         @c Madstyle, @c Msize.
1617
1618    The m17n library selects the best matching font according to the
1619    order of this array.  A font that has a different value for a
1620    property of lower priority is preferred to a font that has a
1621    different value for a property of higher priority.  */
1622 /***ja
1623     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
1624
1625     ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
1626     ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
1627     ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
1628
1629         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1630         @c Madstyle, @c Msize.
1631
1632    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1633    Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
1634    Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
1635    */
1636
1637 MSymbol *
1638 mfont_selection_priority ()
1639 {
1640   MSymbol *keys;
1641   int i;
1642
1643   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1644   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1645     {
1646       enum MFontProperty prop = font_score_priority[i];
1647
1648       if (prop == MFONT_SIZE)
1649         keys[i] = Msize;
1650       else if (prop == MFONT_ADSTYLE)
1651         keys[i] = Madstyle;
1652       else if (prop == MFONT_FAMILY)
1653         keys[i] = Mfamily;
1654       else if (prop == MFONT_WEIGHT)
1655         keys[i] = Mweight;
1656       else if (prop == MFONT_STYLE)
1657         keys[i] = Mstyle;
1658       else if (prop == MFONT_STRETCH)
1659         keys[i] = Mstretch;
1660       else
1661         keys[i] = Mfoundry;
1662     }
1663   return keys;
1664 }
1665
1666 /*=*/
1667
1668 /***en
1669     @brief Set the font selection priority.
1670
1671     The mfont_set_selection_priority () function sets font selection
1672     priority according to $KEYS, which is an array of six symbols.
1673     Each element must be one of the below.  No two elements must be
1674     the same.
1675
1676         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1677         @c Madstyle, @c Msize.
1678
1679     See the documentation of the function mfont_selection_priority ()
1680     for details.  */
1681 /***ja
1682     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1683
1684     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1685     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
1686     ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1687
1688         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1689         @c Madstyle, @c Msize.
1690
1691     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1692      */
1693
1694 int
1695 mfont_set_selection_priority (MSymbol *keys)
1696 {
1697   int priority[FONT_SCORE_PRIORITY_SIZE];
1698   int i, j;
1699
1700   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1701     {
1702       enum MFontProperty prop;
1703
1704       if (*keys == Msize)
1705         prop = MFONT_SIZE;
1706       else if (*keys == Madstyle)
1707         prop = MFONT_ADSTYLE;
1708       else if (*keys == Mfamily)
1709         prop = MFONT_FAMILY;
1710       else if (*keys == Mweight)
1711         prop = MFONT_WEIGHT;
1712       else if (*keys == Mstyle)
1713         prop = MFONT_STYLE;
1714       else if (*keys == Mstretch)
1715         prop = MFONT_STRETCH;
1716       else if (*keys == Mfoundry)
1717         prop = MFONT_FOUNDRY;
1718       else
1719         /* Invalid element.  */
1720         return -1;
1721       for (j = 0; j < i; j++)
1722         if (priority[j] == prop)
1723           /* Duplicated element.  */
1724           return -1;
1725       priority[i] = prop;
1726     }
1727   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1728     font_score_priority[i] = priority[i];
1729   return 0;
1730 }
1731
1732 /*=*/
1733
1734 /***en
1735     @brief Find a font.
1736
1737     The mfont_find () function returns a pointer to the available font
1738     that matches best the specification $SPEC on frame $FRAME.
1739
1740     $SCORE, if not NULL, must point to a place to store the score
1741     value that indicates how well the found font matches to $SPEC.  The
1742     smaller score means a better match.  */
1743 /***ja
1744     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1745
1746     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1747     ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1748
1749     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
1750     ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
1751     ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1752     */
1753
1754 MFont *
1755 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1756 {
1757   MFont spec_copy;
1758   MRealizedFont *rfont;
1759
1760   MFONT_INIT (&spec_copy);
1761   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1762
1763   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1764   if (!rfont)
1765     return NULL;
1766   if (score)
1767     *score = rfont->score;
1768   return &rfont->font;
1769 }
1770
1771 /*=*/
1772 /***en
1773     @brief Set encoding of a font.
1774
1775     The mfont_set_encoding () function sets the encoding information
1776     of font $FONT.
1777
1778     $ENCODING_NAME is a symbol representing a charset that has the
1779     same encoding as the font.
1780
1781     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1782     has the same repertory as the font.  If it is @c Mnil, whether a
1783     specific character is supported by the font is asked to each font
1784     driver.
1785
1786     @return
1787     If the operation was successful, this function returns 0.
1788     Otherwise it returns -1 and assigns an error code to the external
1789     variable #merror_code.  */
1790 /***ja
1791     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1792
1793     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
1794     ¤òÀßÄꤹ¤ë¡£
1795
1796     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
1797     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1798
1799     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
1800     ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
1801     »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
1802     Ì䤤¹ç¤ï¤»¤ë¡£
1803
1804     @return
1805     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
1806     ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1807
1808
1809 int
1810 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1811 {
1812   MCharset *encoding_charset = MCHARSET (encoding_name);
1813   MCharset *repertory_charset;
1814   MSymbol registry;
1815   MFontEncoding *encoding;
1816   MPlist *plist;
1817
1818   if (! encoding_charset)
1819     MERROR (MERROR_FONT, -1);
1820   if (repertory_name != Mnil)
1821     {
1822       repertory_charset = MCHARSET (repertory_name);
1823       if (! repertory_charset)
1824         MERROR (MERROR_FONT, -1);
1825     }
1826   else
1827     repertory_charset = NULL;
1828
1829   MSTRUCT_CALLOC (encoding, MERROR_FONT);
1830   encoding->spec = *font;
1831   encoding->encoding_name = encoding_name;
1832   encoding->encoding_charset = encoding_charset;
1833   encoding->repertory_name = repertory_name;
1834   encoding->repertory_charset = repertory_charset;
1835   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1836   if (registry == Mnil)
1837     registry = Mt;
1838   if (! font_encoding_list)
1839     load_font_encoding_table ();
1840   mplist_push (font_encoding_list, registry, encoding);
1841   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
1842     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
1843                   sizeof (MFont)))
1844       {
1845         mplist_pop (plist);
1846         break;
1847       }
1848   return 0;
1849 }
1850
1851 /*** @} */
1852
1853 /*** @addtogroup m17nDebug */
1854 /*=*/
1855 /*** @{ */
1856
1857 /***en
1858     @brief Dump a font.
1859
1860     The mdebug_dump_font () function prints font $FONT in a human readable
1861     way to the stderr.
1862
1863     @return
1864     This function returns $FONT.  */
1865 /***ja
1866     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
1867
1868     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
1869     ·Á¤Ç°õºþ¤¹¤ë¡£
1870
1871     @return
1872     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
1873
1874 MFont *
1875 mdebug_dump_font (MFont *font)
1876 {
1877   char *name = mwin__build_font_name (font);
1878
1879   fprintf (stderr, "%s", name);
1880   free (name);
1881   return font;
1882 }
1883
1884 /*** @} */
1885
1886 /*
1887   Local Variables:
1888   coding: euc-japan
1889   End:
1890 */