(MXFont): New members smallest and larger.
[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     "regular",
377     "normal",
378     "medium",
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         mplist_push (font_encoding_list, Mt, encoding);
529       else
530         pl = mplist_add (pl, registry, encoding);
531       continue;
532
533     warning:
534       free (encoding);
535     }
536
537   M17N_OBJECT_UNREF (encoding_list);
538   return 0;
539 }
540
541 typedef struct {
542   MFont spec;
543   int resize;
544 } MFontResize;
545
546 static MPlist *font_resize_list;
547
548 /** Load font size table from the data <font size>.
549     The data has this form:
550         (FONT-SPEC RESIZE-FACTOR) ...
551     where FONT-SPEC has this form:
552         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
553     All elements of FONT-SPEC are symbols.  */
554
555 static int
556 load_font_resize_table ()
557 {
558   MDatabase *mdb;
559   MPlist *size_adjust_list, *plist, *pl, *elt;
560
561   font_resize_list = pl = mplist ();
562
563   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
564   if (! mdb)
565     return -1;
566   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
567     MERROR (MERROR_FONT, -1);
568
569   MPLIST_DO (plist, size_adjust_list)
570     {
571       MFontResize *resize;
572       MSymbol registry;
573
574       MSTRUCT_CALLOC (resize, MERROR_FONT);
575
576       if (! MPLIST_PLIST_P (plist)
577           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
578           || ! MPLIST_PLIST_P (elt))
579         MWARNING (MERROR_FONT);
580       registry = mfont__set_spec_from_plist (&resize->spec,
581                                              MPLIST_PLIST (elt));
582       elt = MPLIST_NEXT (elt);
583       if (! MPLIST_INTEGER_P (elt))
584         MWARNING (MERROR_FONT);
585       resize->resize = MPLIST_INTEGER (elt);
586
587       if (registry == Mnil)
588         registry = Mt;
589       pl = mplist_add (pl, registry, resize);
590       continue;
591
592     warning:
593       free (resize);
594     }
595
596   M17N_OBJECT_UNREF (size_adjust_list);
597   return 0;
598 }
599
600 /** Return a font encoding (and repertory) of FONT.  */
601
602 static MFontEncoding *
603 find_encoding (MFont *font)
604 {
605   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
606   MFontEncoding *encoding = NULL;
607   MPlist *plist;
608
609   if (! font_encoding_list)
610     load_font_encoding_table ();
611   plist = font_encoding_list;
612   while (! MPLIST_TAIL_P (plist))
613     {
614       encoding = (MFontEncoding *) MPLIST_VAL (plist);
615       if (mfont__match_p (font, &encoding->spec, MFONT_REGISTRY))
616         {
617           if (encoding->encoding_name != Mnil
618               && ! encoding->encoding_charset)
619             {
620               encoding->encoding_charset = MCHARSET (encoding->encoding_name);
621               if (! encoding->encoding_charset)
622                 {
623                   mplist_pop (plist);
624                   continue;
625                 }
626             }
627           if (encoding->repertory_name == encoding->encoding_name)
628             encoding->repertory_charset = encoding->encoding_charset;
629           else if (encoding->repertory_name != Mnil)
630             {
631               encoding->repertory_charset
632                 = MCHARSET (encoding->repertory_name);
633               if (! encoding->repertory_charset)
634                 {
635                   mplist_pop (plist);
636                   continue;
637                 }
638             }
639           return encoding;
640         }
641
642       if (registry && MPLIST_KEY (plist) != Mt)
643         {
644           plist = mplist_find_by_key (plist, registry);
645           if (! plist)
646             break;
647         }
648       else
649         plist = MPLIST_NEXT (plist);
650     }
651   return &default_encoding;
652 }
653
654 /* XLFD parser/generator */
655
656 /** Indices to each field of split font name.  */
657
658 enum xlfd_field_idx
659   {
660     XLFD_FOUNDRY,
661     XLFD_FAMILY,
662     XLFD_WEIGHT,
663     XLFD_SLANT,
664     XLFD_SWIDTH,
665     XLFD_ADSTYLE,
666     XLFD_PIXEL,
667     XLFD_POINT,
668     XLFD_RESX,
669     XLFD_RESY,
670     XLFD_SPACING,
671     XLFD_AVGWIDTH,
672     XLFD_REGISTRY,              /* This contains ENCODING.  */
673     /* anchor */
674     XLFD_FIELD_MAX
675   };
676
677 static int
678 xlfd_parse_name (char *name, MFont *font)
679 {
680   char *field[XLFD_FIELD_MAX];
681   unsigned short size, resy, avgwidth;
682   MSymbol attrs[MFONT_PROPERTY_MAX];
683   char copy[513];
684   int i;
685   char *p;
686
687   if (name[0] != '-')
688     return -1;
689
690   field[0] = copy;
691   for (i = 1, p = copy, name++; *name; p++, name++)
692     {
693       if (p - copy > 512)
694         return -1;
695       if (*name == '-'
696           && i < XLFD_FIELD_MAX)
697         {
698           *p = '\0';
699           if (field[i - 1][0] == '*')
700             field[i - 1] = NULL;
701           field[i++] = p + 1;
702         }
703       else
704         *p = tolower (*name);
705     }
706   *p = '\0';
707   if (field[i - 1][0] == '*')
708     field[i - 1] = NULL;
709   while (i < XLFD_FIELD_MAX)
710     field[i++] = NULL;
711
712   resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
713   avgwidth = field[XLFD_AVGWIDTH] ? atoi (field[XLFD_AVGWIDTH]) : 0;
714   if (! avgwidth)
715     size = 0;
716   else if (! field[XLFD_PIXEL])
717     size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
718   else if (field[XLFD_PIXEL][0] == '[')
719     {
720       /* The pixel size field specifies a transformation matrix of the
721          form "[A B C D]".  The XLFD spec says that the scalar value N
722          for the pixel size is equivalent to D.  */
723       char *p0 = field[XLFD_PIXEL] + 1, *p1;
724       double d;
725
726       for (i = 0; i < 4; i++, p0 = p1)
727         d = strtod (p0, &p1);
728       size = d * 10;
729     }
730   else
731     size = atoi (field[XLFD_PIXEL]) * 10;
732
733   attrs[MFONT_FOUNDRY]
734     = field[XLFD_FOUNDRY] ? msymbol (field[XLFD_FOUNDRY]) : Mnil;
735   attrs[MFONT_FAMILY]
736     = field[XLFD_FAMILY] ? msymbol (field[XLFD_FAMILY]) : Mnil;
737   attrs[MFONT_WEIGHT]
738     = field[XLFD_WEIGHT] ? msymbol (field[XLFD_WEIGHT]) : Mnil;
739   attrs[MFONT_STYLE]
740     = field[XLFD_SLANT] ? msymbol (field[XLFD_SLANT]) : Mnil;
741   attrs[MFONT_STRETCH]
742     = field[XLFD_SWIDTH] ? msymbol (field[XLFD_SWIDTH]) : Mnil;
743   attrs[MFONT_ADSTYLE]
744     = field[XLFD_ADSTYLE] ? msymbol (field[XLFD_ADSTYLE]) : Mnil;
745   attrs[MFONT_REGISTRY]
746     = field[XLFD_REGISTRY] ? msymbol (field[XLFD_REGISTRY]) : Mnil;
747   mfont__set_spec (font, attrs, size, resy);
748   return 0;
749 }
750
751 static char *
752 xlfd_unparse_name (MFont *font)
753 {
754   MSymbol prop[7];
755   char name[513];
756   char *str[7];
757   int len, i;
758   unsigned short size, resy;
759
760   prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
761   prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
762   prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
763   prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
764   prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
765   prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
766   prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
767   for (len = 0, i = 0; i < 7; i++)
768     {
769       if (prop[i] != Mnil)
770         {
771           str[i] = msymbol_name (prop[i]);
772           len += strlen (str[i]);
773         }
774       else
775         {
776           str[i] = "*";
777           len++;
778         }
779     }
780   if ((len
781        + 12                     /* 12 dashes */
782        + 3                      /* 3 asterisks */
783        + 30                     /* 3 integers (each 10 digits) */
784        + 1)                     /* '\0' terminal */
785       > 513)
786     return NULL;
787
788   size = (int) mfont_get_prop (font, Msize);
789   if ((size % 10) < 5)
790     size /= 10;
791   else
792     size = size / 10 + 1;
793   resy = (int) mfont_get_prop (font, Mresolution);
794
795   sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-*-*-%s",
796            str[0], str[1], str[2], str[3], str[4], str[5],
797            size, resy, resy,  str[6]);
798   return strdup (name);
799 }
800
801 \f
802 /* Internal API */
803
804 int
805 mfont__init ()
806 {
807   int i, shift;
808
809   Mfoundry = msymbol ("foundry");
810   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
811   Mfamily = msymbol ("family");
812   mfont__property_table[MFONT_FAMILY].property = Mfamily;
813   Mweight = msymbol ("weight");
814   mfont__property_table[MFONT_WEIGHT].property = Mweight;
815   Mstyle = msymbol ("style");
816   mfont__property_table[MFONT_STYLE].property = Mstyle;
817   Mstretch = msymbol ("stretch");
818   mfont__property_table[MFONT_STRETCH].property = Mstretch;
819   Madstyle = msymbol ("adstyle");
820   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
821   Mregistry = msymbol ("registry");
822   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
823
824   Msize = msymbol ("size");
825   Mresolution = msymbol ("resolution");
826
827   Mfontconfig = msymbol ("fontconfig");
828
829   Mx = msymbol ("x");
830   Mfreetype = msymbol ("freetype");
831   Mxft = msymbol ("xft");
832
833   /* The first entry of each mfont__property_table must be Mnil so
834      that actual properties get positive numeric numbers.  */
835   for (i = 0; i <= MFONT_REGISTRY; i++)
836     {
837       MLIST_INIT1 (&mfont__property_table[i], names, 8);
838       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
839     }
840
841   /* Register predefined font property names.  */
842   for (i = 0; i <= MFONT_REGISTRY; i++)
843     {
844       int j;
845
846       for (j = 0; j < font_common_names[i].num; j++)
847         {
848           MSymbol sym = msymbol (font_common_names[i].names[j]);
849
850           if (sym == Mnil)
851             return -1;
852           if (msymbol_put (sym, mfont__property_table[i].property,
853                            (void *) (j + 1)) < 0)
854             return -1;
855           MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
856         }
857     }
858
859   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
860      of a score is a flag for a scalable font (see the documentation
861      of mfont_score).  */
862   i = FONT_SCORE_PRIORITY_SIZE - 1;
863   for (shift = 1; i >= 0; i--)
864     {
865       font_score_shift_bits[font_score_priority[i]] = shift;
866       if (font_score_priority[i] == MFONT_SIZE)
867         shift += 16;
868       else
869         shift += 2;
870     }
871
872   MFONT_INIT (&default_encoding.spec);
873   default_encoding.encoding_name = Mnil;
874   default_encoding.encoding_charset = NULL;
875   default_encoding.repertory_name = Mnil;
876   default_encoding.repertory_charset = NULL;
877   {
878     char *path, *buf;
879     int bufsize;
880
881     mfont_freetype_path = mplist ();
882     bufsize = strlen (M17NDIR) + 7;
883     buf = alloca (bufsize);
884     sprintf (buf, "%s/fonts", M17NDIR);
885     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
886     path = getenv ("M17NDIR");
887     if (path)
888       {
889         i = strlen (path) + 7;
890         if (i > bufsize)
891           buf = alloca (i);
892         sprintf (buf, "%s/fonts", path);
893         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
894       }
895   }
896
897 #ifdef HAVE_FREETYPE
898   if (mfont__ft_init () < 0)
899     return -1;
900 #endif /* HAVE_FREETYPE */
901   if (mfont__flt_init () < 0)
902     return -1;
903
904   return 0;
905 }
906
907 void
908 mfont__fini ()
909 {
910   MPlist *plist;
911   int i;
912
913   mfont__flt_fini ();
914 #ifdef HAVE_FREETYPE
915   mfont__ft_fini ();
916 #endif /* HAVE_FREETYPE */
917
918   MPLIST_DO (plist, mfont_freetype_path)
919     free (MPLIST_VAL (plist));
920   M17N_OBJECT_UNREF (mfont_freetype_path);
921
922   if (font_resize_list)
923     {
924       MPLIST_DO (plist, font_resize_list)
925         free (MPLIST_VAL (plist));
926       M17N_OBJECT_UNREF (font_resize_list);
927       font_resize_list = NULL;
928     }
929   if (font_encoding_list)
930     {
931       MPLIST_DO (plist, font_encoding_list)
932         free (MPLIST_VAL (plist));
933       M17N_OBJECT_UNREF (font_encoding_list);
934       font_encoding_list = NULL;
935     }
936   for (i = 0; i <= MFONT_REGISTRY; i++)
937     MLIST_FREE1 (&mfont__property_table[i], names);
938 }
939
940 void
941 mfont__free_realized (MRealizedFont *rfont)
942 {
943   M17N_OBJECT_UNREF (rfont->info);
944   free (rfont);
945 }
946
947
948 /* Compare FONT with REQUEST and return how much they differs.  If
949    FONT does not match with SPEC, return -1.  */
950
951 int
952 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
953 {
954   int score = 0;
955   int i = FONT_SCORE_PRIORITY_SIZE;
956
957   while (--i >= 0)
958     {
959       enum MFontProperty prop = font_score_priority[i];
960
961       if (request->property[prop] != 0)
962         {
963           int val = 0;
964
965           if (spec->property[prop] && font->property[prop]
966               && font->property[prop] != spec->property[prop])
967             return -1;
968           if (font->property[prop])
969             val = abs (font->property[prop] - request->property[prop]);
970           if (val && prop <= MFONT_FAMILY)
971             val = 1;
972           if (prop == MFONT_SIZE)
973             {
974               if (font->property[MFONT_RESY] == 0)
975                 /* This is a scalable font.  We prefer a bitmap font
976                    if the size matches exactly.  */
977                 score |= 1;
978               else
979                 score |= (val << font_score_shift_bits[MFONT_SIZE]
980                           | ((limited_size && val > 0) ? 0x400000 : 0));
981             }
982           else
983             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
984         }
985     }
986   return score;
987 }
988
989
990 /** Return 1 iff FONT matches SPEC.  */
991
992 int
993 mfont__match_p (MFont *font, MFont *spec, int prop)
994 {
995   for (; prop >= 0; prop--)
996     if (spec->property[prop] && font->property[prop]
997         && font->property[prop] != spec->property[prop])
998       return 0;
999   return 1;
1000 }
1001
1002
1003 void
1004 mfont__set_spec_from_face (MFont *spec, MFace *face)
1005 {
1006   int i;
1007
1008   for (i = 0; i <= MFONT_ADSTYLE; i++)
1009     mfont__set_property (spec, i, face->property[i]);
1010   /* The value 1 is "iso8859-1".  */
1011   spec->property[MFONT_REGISTRY] = 1;
1012   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
1013   spec->property[MFONT_RESY] = 0;
1014 }
1015
1016
1017 extern MSymbol
1018 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
1019 {
1020   int i;
1021   MSymbol spec_list[MFONT_REGISTRY + 1];
1022   MSymbol registry;
1023
1024   MFONT_INIT (spec);
1025   memset (spec_list, 0, sizeof spec_list);
1026   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
1027     {
1028       if (! MPLIST_SYMBOL_P (plist))
1029         MERROR (MERROR_FONT, Mnil);     
1030       spec_list[i] = MPLIST_SYMBOL (plist);
1031     }
1032   registry = spec_list[i - 1];
1033   mfont__set_property (spec, MFONT_REGISTRY, registry);
1034   for (i -= 2; i >= 0; i--)
1035     mfont__set_property (spec, i, spec_list[i]);
1036   return registry;
1037 }
1038
1039 MRealizedFont *
1040 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
1041                MSymbol layouter)
1042 {
1043   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1044   MPlist *plist;
1045   MRealizedFont *best;
1046   int i;
1047   int mdebug_mask = MDEBUG_FONT;
1048
1049   if (registry == Mnil)
1050     registry = Mt;
1051
1052   MPLIST_DO (plist, frame->realized_font_list)
1053     {
1054       best = MPLIST_VAL (plist);
1055       if (MPLIST_KEY (plist) == registry
1056           && ! memcmp (&best->spec, spec, sizeof (MFont))
1057           && ! memcmp (&best->request, request, sizeof (MFont)))
1058         {
1059           if (best->layouter != layouter)
1060             {
1061               MRealizedFont *copy;
1062
1063               MSTRUCT_MALLOC (copy, MERROR_FONT);
1064               *copy = *best;
1065               copy->layouter = layouter;
1066               mplist_add (frame->realized_font_list, registry, copy);
1067               if (copy->info)
1068                 M17N_OBJECT_REF (copy->info);
1069               best = copy;
1070             }
1071           return best;
1072         }
1073     }
1074
1075   MDEBUG_PUSH_TIME ();
1076   best = NULL;
1077   MPLIST_DO (plist, frame->font_driver_list)
1078     {
1079       MFontDriver *driver = MPLIST_VAL (plist);
1080       MRealizedFont *this
1081         = (driver->select) (frame, spec, request, limited_size);
1082
1083       if (this)
1084         {
1085           this->driver = driver;
1086           if (! best
1087               || this->score < best->score)
1088             {
1089               if (best)
1090                 mfont__free_realized (best);
1091               best = this;
1092               if (this->score == 0)
1093                 break;
1094             }
1095           else
1096             mfont__free_realized (this);
1097         }
1098     }
1099
1100   if (mdebug__flag & mdebug_mask)
1101     {
1102       char buf1[256], buf2[256];
1103       MFont font = *spec;
1104
1105       for (i = 0; i < MFONT_PROPERTY_MAX; i++)
1106         if (! font.property[i])
1107           font.property[i] = request->property[i];
1108       gen_font_name (buf2, &font);
1109
1110       if (best)
1111         MDEBUG_PRINT_TIME ("FONT", 
1112                            (stderr, " to select <%s> (%x)from <%s>.",
1113                             gen_font_name (buf1, &best->font),
1114                             best->score,
1115                             buf2));
1116       else
1117         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
1118       MDEBUG_POP_TIME ();
1119     }
1120
1121   if (! best)
1122     return NULL;
1123   best->layouter = layouter;
1124   mplist_add (frame->realized_font_list, registry, best);
1125   return best;
1126 }
1127
1128
1129 /** Open a font specified in RFONT.  Return 0 if successfully
1130     opened, otherwise return -1.  */
1131
1132 int
1133 mfont__open (MRealizedFont *rfont)
1134 {
1135   return (rfont->driver->open) (rfont);
1136 }
1137
1138 void
1139 mfont__resize (MFont *spec, MFont *request)
1140 {
1141   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1142   MFontResize *resize;
1143   MPlist *plist;
1144
1145   if (! font_resize_list)
1146     load_font_resize_table ();
1147   if (! MPLIST_TAIL_P (font_resize_list))
1148     while (1)
1149       {
1150         plist = font_resize_list;
1151         while (registry ? (plist = mplist_find_by_key (plist, registry))
1152                : plist)
1153           {
1154             resize = (MFontResize *) MPLIST_VAL (plist);
1155             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1156               {
1157                 request->property[MFONT_SIZE]
1158                   = request->property[MFONT_SIZE] * resize->resize / 100;
1159                 return;
1160               }
1161             plist = MPLIST_NEXT (plist);
1162           }
1163         if (registry == Mt)
1164           break;
1165         registry = Mt;
1166       }
1167 }
1168
1169
1170 unsigned
1171 mfont__encode_char (MRealizedFont *rfont, int c)
1172 {
1173   MFontEncoding *encoding;
1174   unsigned code;
1175
1176   if (rfont->layouter != Mnil)
1177     return mfont__flt_encode_char (rfont->layouter, c);
1178   if (! rfont->encoding)
1179     rfont->encoding = find_encoding (&rfont->font);
1180   encoding = rfont->encoding;
1181   if (! encoding->encoding_charset)
1182     return MCHAR_INVALID_CODE;
1183   if (encoding->repertory_charset
1184       && ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
1185     return MCHAR_INVALID_CODE;
1186   code = ENCODE_CHAR (encoding->encoding_charset, c);
1187   if (code == MCHAR_INVALID_CODE)
1188     return MCHAR_INVALID_CODE;
1189   return (rfont->driver->encode_char) (rfont, code);
1190 }
1191
1192 void
1193 mfont__get_metric (MGlyphString *gstring, int from, int to)
1194 {
1195   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1196   MRealizedFont *rfont = from_g->rface->rfont;
1197
1198   for (g = from_g; g != to_g; g++)
1199     if (g->rface->rfont != rfont)
1200       {
1201         int idx = GLYPH_INDEX (g);
1202
1203         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1204         from_g = g;
1205         rfont = g->rface->rfont;
1206         from = idx;
1207       }
1208   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1209 }
1210
1211
1212 void
1213 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1214 {
1215   int numeric;
1216
1217   if (val == Mnil)
1218     numeric = 0;
1219   else
1220     {
1221       numeric = FONT_PROPERTY_NUMERIC (val, key);
1222       if (! numeric)
1223         {
1224           numeric = mfont__property_table[key].used;
1225           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1226           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1227         }
1228     }
1229   font->property[key] = numeric;
1230 }
1231
1232 void
1233 mfont__set_spec (MFont *font, MSymbol *attrs,
1234                  unsigned short size, unsigned short resy)
1235 {
1236   int i;
1237
1238   for (i = 0; i <= MFONT_REGISTRY; i++)
1239     mfont__set_property (font, i, attrs[i]);
1240   font->property[MFONT_SIZE] = size;
1241   font->property[MFONT_RESY] = resy;
1242 }
1243
1244 int
1245 mfont__parse_name_into_font (char *name, MSymbol format, MFont *font)
1246 {
1247   int result = -1;
1248
1249   if (format == Mx || format == Mnil)
1250     result = xlfd_parse_name (name, font);
1251 #ifdef HAVE_FONTCONFIG
1252   if (format == Mfontconfig || (! result && format == Mnil))
1253     result = mfont__ft_parse_name (name, font);
1254 #endif
1255   return result;
1256 }
1257
1258 MPlist *
1259 mfont__encoding_list (void)
1260 {
1261   if (! font_encoding_list)
1262     load_font_encoding_table ();
1263   return font_encoding_list;
1264 }
1265
1266 /*** @} */
1267 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1268
1269 \f
1270
1271 /* External API */
1272
1273 /*** @addtogroup m17nFont */
1274 /*** @{ */
1275 /*=*/
1276
1277 /***en @name Variables: Keys of font property.  */
1278 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1279 /*** @{ */
1280 /*=*/
1281
1282 /***en
1283     @brief Key of font property specifying foundry.
1284
1285     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1286     is used as a key of font property and face property.  The property
1287     value must be a symbol whose name is a foundry name of a font.  */
1288 /***ja
1289     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1290     
1291     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1292     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1293     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1294     */
1295
1296 MSymbol Mfoundry;
1297
1298 /***en
1299     @brief Key of font property specifying family.
1300
1301     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1302     used as a key of font property and face property.  The property
1303     value must be a symbol whose name is a family name of a font.  */ 
1304 /***ja
1305     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1306     
1307     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1308     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1309     ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1310     */
1311
1312 MSymbol Mfamily;
1313
1314 /***en
1315     @brief Key of font property specifying weight.
1316
1317     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1318     used as a key of font property and face property.  The property
1319     value must be a symbol whose name is a weight name of a font (e.g
1320     "medium", "bold").  */ 
1321 /***ja
1322     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1323     
1324     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1325     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1326     ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1327     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1328     */
1329
1330 MSymbol Mweight;
1331
1332 /***en
1333     @brief Key of font property specifying style.
1334
1335     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1336     used as a key of font property and face property.  The property
1337     value must be a symbol whose name is a style name of a font (e.g
1338     "r", "i", "o").  */ 
1339 /***ja
1340     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1341     
1342     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1343     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1344     ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1345     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1346     */
1347
1348 MSymbol Mstyle;
1349
1350 /***en
1351     @brief Key of font property specifying stretch.
1352
1353     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1354     is used as a key of font property and face property.  The property
1355     value must be a symbol whose name is a stretch name of a font (e.g
1356     "normal", "condensed").  */ 
1357 /***ja
1358     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1359     
1360     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1361     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1362     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1363     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1364     */
1365
1366 MSymbol Mstretch;
1367
1368 /***en
1369     @brief Key of font property specifying additional style.
1370
1371     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1372     is used as a key of font property and face property.  The property
1373     value must be a symbol whose name is an additional style name of a
1374     font (e.g "serif", "", "sans").  */ 
1375 /***ja
1376     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1377     
1378     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1379     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1380     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1381     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1382     */
1383
1384 MSymbol Madstyle;
1385
1386 /***en
1387     @brief Key of font property specifying registry.
1388
1389     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1390     and is used as a key of font property.  The property value must be
1391     a symbol whose name is a registry name a font registry
1392     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1393 /***ja
1394     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1395     
1396     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
1397     ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
1398     ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
1399     ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1400     */
1401
1402 MSymbol Mregistry;
1403
1404 /***en
1405     @brief Key of font property specifying size.
1406
1407     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1408     used as a key of font property and face property.  The property
1409     value must be an integer specifying a font design size in the unit
1410     of 1/10 point (on 100 dpi display).  */ 
1411 /***ja
1412     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1413     
1414     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
1415     ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1416     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó
1417     ¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1418     */
1419
1420 MSymbol Msize;
1421
1422 /***en
1423     @brief Key of font property specifying resolution.
1424
1425     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1426     is used as a key of font property and face property.  The property
1427     value must be an integer to specifying a font resolution in the
1428     unit of dots per inch (dpi).  */ 
1429 /***ja
1430     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1431     
1432     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü
1433     ¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é
1434     ¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ô
1435     ÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1436     */
1437
1438 MSymbol Mresolution;
1439
1440 /***en
1441     @brief Symobl of name "fontconfig".
1442
1443     The variable #Mfontconfig is to be used as an argument of the
1444     functions mfont_parse_name () and mfont_unparse_name ().  */
1445
1446 MSymbol Mfontconfig;
1447
1448 /***en
1449     @brief Symbol of name "x".
1450
1451     The variable #Mx is to be used for a value of <type> member of the
1452     structure #MDrawGlyph to specify the type of <fontp> member is
1453     actually (XFontStruct *).  */
1454
1455 MSymbol Mx;
1456
1457 /***en
1458     @brief Symbol of name "freetype".
1459
1460     The variable #Mfreetype is to be used for a value of <type> member
1461     of the structure #MDrawGlyph to specify the type of <fontp> member
1462     is actually FT_Face.  */
1463
1464 MSymbol Mfreetype;
1465
1466 /***en
1467     @brief Symbol of name "xft".
1468
1469     The variable #Mxft is to be used for a value of <type> member of the
1470     structure #MDrawGlyph to specify the type of <fontp> member
1471     is actually (XftFont *).  */
1472
1473 MSymbol Mxft;
1474
1475 /*=*/
1476 /*** @} */
1477 /*=*/
1478
1479 /***en
1480     @brief List of font files and directories that contain font files.
1481
1482     The variable @c mfont_freetype_path is a plist of FreeType font
1483     files and directories that contain FreeType font files.  Key of
1484     the element is @c Mstring, and the value is a string that
1485     represents a font file or a directory.
1486
1487     The macro M17N_INIT () sets up this variable to contain the
1488     sub-directory "fonts" of the m17n database and the environment
1489     variable "M17NDIR".  The first call of mframe () creates the
1490     internal list of the actually available fonts from this variable.
1491     Thus, an application program, if necessary, must modify the
1492     variable before calling mframe ().  If it is going to add a new
1493     element, value must be a string that can be safely freed.
1494
1495     If the m17n library is not configured to use the FreeType library,
1496     this variable is not used.  */
1497 /***ja
1498     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1499
1500     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
1501     ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
1502     ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1503
1504     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
1505      ¿ô "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1506      mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
1507      ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
1508      mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
1509      ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
1510      ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1511
1512     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
1513     ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1514
1515 MPlist *mfont_freetype_path;
1516
1517 /*=*/
1518
1519 /***en
1520     @brief Create a new font.
1521
1522     The mfont () function creates a new font object that has no
1523     property.
1524
1525     @return
1526     This function returns a pointer to the created font object.  */
1527 /***ja
1528     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1529
1530     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
1531     ¥È¤òºî¤ë¡£
1532
1533     @return
1534     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1535
1536 MFont *
1537 mfont ()
1538 {
1539   MFont *font;
1540
1541   MSTRUCT_CALLOC (font, MERROR_FONT);
1542   return font;
1543 }
1544
1545 /*=*/
1546
1547 /***en
1548     @brief Create a font by parsing a fontname.
1549
1550     The mfont_parse_name () function creates a new font object.  The
1551     properties are extracted fontname $NAME.
1552
1553     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
1554     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
1555     #Mfontconfig, $NAME is parsed as Fontconfig's textual
1556     representation of font.  If $FORMAT is #Mnil, $NAME is at first
1557     parsed as XLFD, and it it fails, parsed as Fontconfig's
1558     representation.
1559
1560     @return
1561     If the operation was successful, this function returns a pointer
1562     to the created font.  Otherwise it returns @c NULL.  */
1563
1564 /***ja
1565     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1566
1567     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
1568     ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1569
1570     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
1571     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1572     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­
1573     ¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD ¤Ë
1574     ½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
1575
1576     @return
1577     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1578     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1579
1580 MFont *
1581 mfont_parse_name (char *name, MSymbol format)
1582 {
1583   MFont template, *font;
1584   
1585   MFONT_INIT (&template);
1586   if (mfont__parse_name_into_font (name, format, &template) < 0)
1587     MERROR (MERROR_FONT, NULL);
1588   MSTRUCT_CALLOC (font, MERROR_FONT);
1589   *font = template;
1590   return font;
1591 }
1592
1593 /*=*/
1594
1595 /***en
1596     @brief Create a fontname from a font.
1597
1598     The mfont_unparse_name () function creates a fontname string
1599     from font $FONT according to $FORMAT.
1600
1601     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
1602     is in XLFD (X Logical Font Description) format.  If it is
1603     #Mfontconfig, the fontname is in the style of Fontconfig's text
1604     representation.
1605
1606     @return
1607     This function returns a newly allocated fontname string, which is
1608     not freed unless the user explicitly does so by free ().  */
1609
1610 /***ja
1611     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1612
1613     ´Ø¿ô mfont_unparse_name () ¤Ï $FORMAT ¤Ë¤·¤¿¤¬¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»ú
1614     Îó¤ò¥Õ¥©¥ó¥È$FONT ¤ò¸µ¤Ëºî¤ë¡£
1615
1616     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£#Mx ¤Ê¤é¤Ð¥Õ¥©
1617     ¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£#Mfontconfig ¤Ê
1618     ¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
1619
1620     @return 
1621     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢
1622     ¥æ¡¼¥¶¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1623
1624 char *
1625 mfont_unparse_name (MFont *font, MSymbol format)
1626 {
1627   char *name;
1628
1629   if (format == Mx)
1630     name = xlfd_unparse_name (font);
1631 #ifdef HAVE_FONTCONFIG
1632   else if (format == Mfontconfig)
1633     name = mfont__ft_unparse_name (font);
1634 #endif
1635   else
1636     MERROR (MERROR_FONT, NULL);
1637   return name;
1638 }
1639
1640 /*=*/
1641
1642 /***en
1643     @brief Make a copy of a font.
1644
1645     The mfont_copy () function returns a new copy of font $FONT.  */
1646 /***ja
1647     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1648
1649     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1650
1651 MFont *
1652 mfont_copy (MFont *font)
1653 {
1654   MFont *copy;
1655
1656   MSTRUCT_MALLOC (copy, MERROR_FONT);
1657   *copy = *font;
1658   return copy;
1659 }
1660
1661 /*=*/
1662
1663 /***en
1664     @brief Get a property value of a font.
1665
1666     The mfont_get_prop () function gets the value of $KEY property of
1667     font $FONT.  $KEY must be one of the following symbols:
1668
1669         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1670         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1671
1672     @return
1673     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1674     Madstyle, or @c Mregistry, this function returns the
1675     corresponding value as a symbol.  If the font does not have $KEY
1676     property, it returns @c Mnil.
1677     If $KEY is @c Msize or @c Mresolution, this function returns the
1678     corresponding value as an integer.  If the font does not have $KEY
1679     property, it returns 0.
1680     If $KEY is something else, it returns @c NULL and assigns an error
1681     code to the external variable #merror_code.  */
1682
1683 /***ja
1684     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1685
1686     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1687     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1688     ¤Ð¤Ê¤é¤Ê¤¤¡£
1689
1690         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1691         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1692
1693     @return 
1694     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1695     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
1696     ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1697     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
1698     ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
1699     ÊÖ¤¹¡£
1700     $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1701     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1702
1703 void *
1704 mfont_get_prop (MFont *font, MSymbol key)
1705 {
1706   if (key == Mfoundry)
1707     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1708   if (key == Mfamily)
1709     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1710   if (key == Mweight)
1711     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1712   if (key == Mstyle)
1713     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1714   if (key == Mstretch)
1715     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1716   if (key == Madstyle)
1717     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1718   if (key == Mregistry)
1719     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1720   if (key == Msize)
1721     {
1722       int size = font->property[MFONT_SIZE];
1723       return (void *) size;
1724     }
1725   if (key == Mresolution)
1726     {
1727       int resy = font->property[MFONT_RESY];
1728       return (void *) resy;
1729     }
1730
1731   MERROR (MERROR_FONT, NULL);
1732 }
1733
1734
1735 /*=*/
1736 /***en
1737     @brief Put a property value to a font.
1738
1739     The mfont_put_prop () function puts a font property whose key is
1740     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1741     following symbols:
1742
1743         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1744         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1745
1746     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1747     Otherwise, $VAL must be a symbol.  */
1748 /***ja
1749     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1750
1751     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
1752     ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
1753     ¤ë¡£
1754
1755         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1756         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1757
1758     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
1759     ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1760
1761 int
1762 mfont_put_prop (MFont *font, MSymbol key, void *val)
1763 {
1764   if (key == Mfoundry)
1765     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1766   else if (key == Mfamily)
1767     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1768   else if (key == Mweight)
1769     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1770   else if (key == Mstyle)
1771     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1772   else if (key == Mstretch)
1773     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1774   else if (key == Madstyle)
1775     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1776   else if (key == Mregistry)
1777     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1778   else if (key == Msize)
1779     {
1780       unsigned size = (unsigned) val;
1781       font->property[MFONT_SIZE] = size;
1782     }
1783   else if (key == Mresolution)
1784     {
1785       unsigned resy = (unsigned) val;
1786       font->property[MFONT_RESY] =  resy;
1787     }
1788   else
1789     MERROR (MERROR_FONT, -1);
1790   return 0;
1791 }
1792
1793 /*=*/
1794
1795 /***en
1796     @brief Return the font selection priority.
1797
1798     The mfont_selection_priority () function returns a newly created
1799     array of six symbols.  The elements are the following
1800     keys of font properties ordered by priority.
1801
1802         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1803         @c Madstyle, @c Msize.
1804
1805    The m17n library selects the best matching font according to the
1806    order of this array.  A font that has a different value for a
1807    property of lower priority is preferred to a font that has a
1808    different value for a property of higher priority.  */
1809 /***ja
1810     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
1811
1812     ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
1813     ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
1814     ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
1815
1816         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1817         @c Madstyle, @c Msize.
1818
1819    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1820    Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
1821    Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
1822    */
1823
1824 MSymbol *
1825 mfont_selection_priority ()
1826 {
1827   MSymbol *keys;
1828   int i;
1829
1830   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1831   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1832     {
1833       enum MFontProperty prop = font_score_priority[i];
1834
1835       if (prop == MFONT_SIZE)
1836         keys[i] = Msize;
1837       else if (prop == MFONT_ADSTYLE)
1838         keys[i] = Madstyle;
1839       else if (prop == MFONT_FAMILY)
1840         keys[i] = Mfamily;
1841       else if (prop == MFONT_WEIGHT)
1842         keys[i] = Mweight;
1843       else if (prop == MFONT_STYLE)
1844         keys[i] = Mstyle;
1845       else if (prop == MFONT_STRETCH)
1846         keys[i] = Mstretch;
1847       else
1848         keys[i] = Mfoundry;
1849     }
1850   return keys;
1851 }
1852
1853 /*=*/
1854
1855 /***en
1856     @brief Set the font selection priority.
1857
1858     The mfont_set_selection_priority () function sets font selection
1859     priority according to $KEYS, which is an array of six symbols.
1860     Each element must be one of the below.  No two elements must be
1861     the same.
1862
1863         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1864         @c Madstyle, @c Msize.
1865
1866     See the documentation of the function mfont_selection_priority ()
1867     for details.  */
1868 /***ja
1869     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1870
1871     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1872     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
1873     ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1874
1875         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1876         @c Madstyle, @c Msize.
1877
1878     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1879      */
1880
1881 int
1882 mfont_set_selection_priority (MSymbol *keys)
1883 {
1884   int priority[FONT_SCORE_PRIORITY_SIZE];
1885   int i, j;
1886
1887   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1888     {
1889       enum MFontProperty prop;
1890
1891       if (*keys == Msize)
1892         prop = MFONT_SIZE;
1893       else if (*keys == Madstyle)
1894         prop = MFONT_ADSTYLE;
1895       else if (*keys == Mfamily)
1896         prop = MFONT_FAMILY;
1897       else if (*keys == Mweight)
1898         prop = MFONT_WEIGHT;
1899       else if (*keys == Mstyle)
1900         prop = MFONT_STYLE;
1901       else if (*keys == Mstretch)
1902         prop = MFONT_STRETCH;
1903       else if (*keys == Mfoundry)
1904         prop = MFONT_FOUNDRY;
1905       else
1906         /* Invalid element.  */
1907         return -1;
1908       for (j = 0; j < i; j++)
1909         if (priority[j] == prop)
1910           /* Duplicated element.  */
1911           return -1;
1912       priority[i] = prop;
1913     }
1914   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1915     font_score_priority[i] = priority[i];
1916   return 0;
1917 }
1918
1919 /*=*/
1920
1921 /***en
1922     @brief Find a font.
1923
1924     The mfont_find () function returns a pointer to the available font
1925     that matches best the specification $SPEC on frame $FRAME.
1926
1927     $SCORE, if not NULL, must point to a place to store the score
1928     value that indicates how well the found font matches to $SPEC.  The
1929     smaller score means a better match.  */
1930 /***ja
1931     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1932
1933     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1934     ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1935
1936     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
1937     ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
1938     ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1939     */
1940
1941 MFont *
1942 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1943 {
1944   MFont spec_copy;
1945   MRealizedFont *rfont;
1946
1947   MFONT_INIT (&spec_copy);
1948   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1949
1950   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1951   if (!rfont)
1952     return NULL;
1953   if (score)
1954     *score = rfont->score;
1955   return &rfont->font;
1956 }
1957
1958 /*=*/
1959 /***en
1960     @brief Set encoding of a font.
1961
1962     The mfont_set_encoding () function sets the encoding information
1963     of font $FONT.
1964
1965     $ENCODING_NAME is a symbol representing a charset that has the
1966     same encoding as the font.
1967
1968     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1969     has the same repertory as the font.  If it is @c Mnil, whether a
1970     specific character is supported by the font is asked to each font
1971     driver.
1972
1973     @return
1974     If the operation was successful, this function returns 0.
1975     Otherwise it returns -1 and assigns an error code to the external
1976     variable #merror_code.  */
1977 /***ja
1978     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1979
1980     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
1981     ¤òÀßÄꤹ¤ë¡£
1982
1983     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
1984     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1985
1986     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
1987     ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
1988     »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
1989     Ì䤤¹ç¤ï¤»¤ë¡£
1990
1991     @return
1992     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
1993     ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1994
1995
1996 int
1997 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1998 {
1999   MCharset *encoding_charset = MCHARSET (encoding_name);
2000   MCharset *repertory_charset;
2001   MSymbol registry;
2002   MFontEncoding *encoding;
2003   MPlist *plist;
2004
2005   if (! encoding_charset)
2006     MERROR (MERROR_FONT, -1);
2007   if (repertory_name != Mnil)
2008     {
2009       repertory_charset = MCHARSET (repertory_name);
2010       if (! repertory_charset)
2011         MERROR (MERROR_FONT, -1);
2012     }
2013   else
2014     repertory_charset = NULL;
2015
2016   MSTRUCT_CALLOC (encoding, MERROR_FONT);
2017   encoding->spec = *font;
2018   encoding->encoding_name = encoding_name;
2019   encoding->encoding_charset = encoding_charset;
2020   encoding->repertory_name = repertory_name;
2021   encoding->repertory_charset = repertory_charset;
2022   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
2023   if (registry == Mnil)
2024     registry = Mt;
2025   if (! font_encoding_list)
2026     load_font_encoding_table ();
2027   mplist_push (font_encoding_list, registry, encoding);
2028   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
2029     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
2030                   sizeof (MFont)))
2031       {
2032         mplist_pop (plist);
2033         break;
2034       }
2035   return 0;
2036 }
2037
2038 /*=*/
2039
2040 /***en
2041     @brief Create a fontname from a font.
2042
2043     This function is obsolete.   Use mfont_unparse_name instead. */
2044 /***ja
2045     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2046
2047     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2048
2049 char *
2050 mfont_name (MFont *font)
2051 {
2052   return mfont_unparse_name (font, Mx);
2053 }
2054
2055 /*=*/
2056
2057 /***en
2058     @brief Create a new font from fontname.
2059
2060     This function is obsolete.  Use mfont_parse_name () instead.  */
2061
2062 /***ja
2063     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2064
2065     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2066
2067 MFont *
2068 mfont_from_name (char *name)
2069 {
2070   return mfont_parse_name (name, Mx);
2071 }
2072
2073 /*=*/
2074
2075 /***en
2076     @brief Get resize information of a font.
2077
2078     The mfont_resize_ratio () function lookups the m17n database
2079     \<font, reisize\> and returns a resizing ratio (in percentage) of
2080     FONT.  For instance, if the return value is 150, that means that
2081     the m17n library uses an 1.5 time bigger font than a specified
2082     size.  */
2083
2084 /***ja
2085     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
2086
2087     ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> ¤ò¸¡
2088     º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë¤òÊÖ¤¹¡£¤¿¤È¤¨
2089     ¤ÐÊÖÃͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 ÇܤÎ
2090     ¥Õ¥©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
2091
2092 int
2093 mfont_resize_ratio (MFont *font)
2094 {
2095   MFont request = *font;
2096
2097   mfont__resize (font, &request);
2098   return (font->property[MFONT_SIZE] * 100 / request.property[MFONT_SIZE]);
2099 }
2100
2101 /*=*/
2102
2103 /***en
2104     @brief Get a list of fonts.
2105
2106     The mfont_list () functions returns a list of fonts available on
2107     frame $FRAME.  $FONT, if not @c Mnil, limits fonts to ones
2108     that match with $FONT.  $LANGUAGE, if not @c Mnil, limits fonts to
2109     ones that support $LANGUAGE.  $MAXNUM, if greater than 0, limits
2110     the number of fonts.
2111
2112     @return
2113     This function returns a plist whose keys are family names and
2114     values are pointers to the object MFont.  The plist must be freed
2115     by m17n_object_unref ().  If no font is found, it returns
2116     NULL.  */
2117
2118 /***ja
2119     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
2120
2121     ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È
2122     ¤òÊÖ¤¹¡£ $FONT ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©
2123     ¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£$LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò
2124     ¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£ $MAXNUM ¤Ï¡¢0 ¤è¤êÂç
2125     ¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
2126
2127     @return 
2128     ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§
2129     ¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê plist ¤òÊÖ¤¹¡£plist ¤Ï
2130     m17n_object_unref () ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð
2131     NULL ¤òÊÖ¤¹¡£  */
2132
2133 MPlist *
2134 mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
2135 {
2136   MPlist *plist = mplist (), *p;
2137   int num = 0;
2138   
2139   MPLIST_DO (p, frame->font_driver_list)
2140     {
2141       MFontDriver *driver = MPLIST_VAL (p);
2142
2143       num += (driver->list) (frame, plist, font, language,
2144                              maxnum > 0 ? maxnum - num : 0);
2145       if (maxnum > 0 && num >= maxnum)
2146         break;
2147     }
2148   if (MPLIST_TAIL_P (plist))
2149     {
2150       M17N_OBJECT_UNREF (plist);
2151       plist = NULL;
2152     }
2153   return plist;
2154 }
2155
2156 /*** @} */
2157
2158 /*** @addtogroup m17nDebug */
2159 /*=*/
2160 /*** @{ */
2161
2162 /***en
2163     @brief Dump a font.
2164
2165     The mdebug_dump_font () function prints font $FONT in a human readable
2166     way to the stderr.
2167
2168     @return
2169     This function returns $FONT.  */
2170 /***ja
2171     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2172
2173     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
2174     ·Á¤Ç°õºþ¤¹¤ë¡£
2175
2176     @return
2177     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2178
2179 MFont *
2180 mdebug_dump_font (MFont *font)
2181 {
2182   char *name;
2183   
2184   name = mfont_unparse_name (font, Mx);
2185   if (name)
2186     {
2187       fprintf (stderr, "%s", name);
2188       free (name);
2189     }
2190   return font;
2191 }
2192
2193 void
2194 mdebug_dump_font_list (MFrame *frame, MSymbol family, MSymbol lang)
2195 {
2196   MPlist *plist, *p;
2197
2198   if (family == Mnil)
2199     plist = mfont_list (frame, NULL, lang, 0);
2200   else
2201     {
2202       MFont font;
2203
2204       MFONT_INIT (&font);
2205       mfont__set_property (&font, MFONT_FAMILY, family);
2206       plist = mfont_list (frame, &font, lang, 0);
2207     }
2208   MPLIST_DO (p, plist)
2209     {
2210       mdebug_dump_font (MPLIST_VAL (p));
2211       fprintf (stderr, "\n");
2212     }
2213   M17N_OBJECT_UNREF (plist);
2214 }
2215
2216 /*** @} */
2217
2218 /*
2219   Local Variables:
2220   coding: euc-japan
2221   End:
2222 */