3dc2301f554a925f615a1a90c51deba03b51448c
[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, @c Mspacing.
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.  
37
38     "The font property that belongs to font F and whose key is @c
39     Mxxx" may be shortened to "the xxx property of F".
40
41     The value of a foundry property is a symbol representing font
42     foundry information, e.g. adobe, misc, etc.
43
44     The value of a family property is a symbol representing font family
45     information, e.g. times, helvetica, etc.
46
47     The value of a weight property is a symbol representing weight
48     information, e.g. normal, bold, etc.
49
50     The value of a style property is a symbol representing slant
51     information, e.g. normal, italic, etc.
52
53     The value of a stretch property is a symbol representing width
54     information, e.g. normal, semicondensed, etc.
55
56     The value of an adstyle property is a symbol representing abstract
57     font family information, e.g. serif, sans-serif, etc.
58
59     The value of a registry property is a symbol representing registry
60     information, e.g. iso10646-1, iso8895-1, etc.
61
62     The value of a size property is an integer representing design
63     size in the unit of 1/10 point.
64
65     The value of a resolution property is an integer representing
66     assumed device resolution in the unit of dots per inch (dpi).
67
68     The value of a type property is a symbol indicating a font driver;
69     currently Mx or Mfreetype.
70
71     The m17n library uses font objects for two purposes: to receive
72     font specification from an application program, and to present
73     available fonts to an application program.  When the m17n library
74     presents an available font to an application program, all font
75     properties have a concrete value.
76
77     The m17n library supports three kinds of fonts: Window system fonts,
78     FreeType fonts, and OpenType fonts.
79
80     <ul>
81
82     <li> Window system fonts
83
84     The m17n-X library supports all fonts handled by an X server and
85     an X font server.  The correspondence between XLFD fields and font
86     properties are shown below.
87
88 @verbatim
89     XLFD field                                  property
90     ---------------                             --------
91     FOUNDRY                                     foundry
92     FAMILY_NAME                                 family
93     WEIGHT_NAME                                 weight
94     SLANT                                       style
95     SETWIDTH_NAME                               stretch
96     ADD_STYLE_NAME                              adstyle
97     PIXEL_SIZE                                  size
98     RESOLUTION_Y                                resolution
99     CHARSET_REGISTRY-CHARSET_ENCODING           registry
100 @endverbatim
101
102     XLFD fields not listed in the above table are ignored.
103
104     <li> FreeType fonts
105
106     The m17n library, if configured to use the FreeType library,
107     supports all fonts that can be handled by the FreeType library.
108     The variable #mfont_freetype_path is initialized properly according
109     to the configuration of the m17n library and the environment
110     variable @c M17NDIR.  See the documentation of the variable for
111     details.
112
113     If the m17n library is configured to use the fontconfig library,
114     in addition to #mfont_freetype_path, all fonts available via
115     fontconfig are supported.
116
117     The family name of a FreeType font corresponds to the family
118     property.  Style names of FreeType fonts correspond to the weight,
119     style, and stretch properties as below.
120
121 @verbatim
122     style name          weight  style   stretch
123     ----------          ------  -----   -------
124     Regular             medium  r       normal
125     Italic              medium  i       normal
126     Bold                bold    r       normal
127     Bold Italic         bold    i       normal
128     Narrow              medium  r       condensed
129     Narrow Italic       medium  i       condensed
130     Narrow Bold         bold    r       condensed
131     Narrow Bold Italic  bold    i       condensed
132     Black               black   r       normal
133     Black Italic        black   i       normal
134     Oblique             medium  o       normal
135     BoldOblique         bold    o       normal
136 @endverbatim
137
138     Style names not listed in the above table are treated as
139     "Regular".
140
141     Combination of a platform ID and an encoding ID corresponds to the
142     registry property.  For example, if a font has the combination (1
143     1), the registry property is 1-1.  Some frequent combinations have
144     a predefined registry property as below.
145
146 @verbatim
147     platform ID         encoding ID     registry property
148     -----------         -----------     -----------------
149     0                   3               unicode-bmp
150     0                   4               unicode-full
151     1                   0               apple-roman
152     3                   1               unicode-bmp
153     3                   1               unicode-full
154 @endverbatim
155
156     Thus, a font that has two combinations (1 0) and (3 1) corresponds
157     to four font objects whose registries are 1-0, apple-roman, 3-1,
158     and unicode-bmp.
159
160     <li> OpenType fonts 
161
162     The m17n library, if configured to use both the FreeType library
163     and the OTF library, supports any OpenType fonts.  The list of
164     actually available fonts is created in the same way as in the case
165     of FreeType fonts.  If a fontset instructs to use an OpenType font
166     via an FLT (Font Layout Table), and the FLT has an OTF-related
167     command (e.g. otf:deva), the OTF library converts a character
168     sequence to a glyph code sequence according to the OpenType layout
169     tables of the font, and the FreeType library gives a bitmap image
170     for each glyph.
171
172     </ul>
173
174   */
175
176 /***ja
177     @addtogroup m17nFont
178     @brief ¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È.
179
180     m17n GUI API ¤Ï¥Õ¥©¥ó¥È¤ò @c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æɽ¸½¤¹¤ë¡£
181     ¥Õ¥©¥ó¥È¤Ï @e ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¤ë¡£Â¾¤Î¥¿¥¤¥×¤Î¥×
182     ¥í¥Ñ¥Æ¥£Æ±ÍÍ¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ê¡¢¥­¡¼¤Ï°Ê²¼¤Î¥·
183     ¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
184
185     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
186     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing
187
188     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution 
189     ¤Î¾ì¹ç¡¢ÃͤÏÀ°¿ôÃͤǤ¢¤ê¡¢¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
190
191     ¡Ö¥Õ¥©¥ó¥È F ¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx 
192     ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È¤ò´Êñ¤Ë¡ÖF ¤Î xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
193
194     foundry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢adobe, misc 
195     Åù¤Î¥Õ¥©¥ó¥È¤Î³«È¯¸µ¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
196
197     family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica 
198     Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
199
200     weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
201
202     style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic 
203     Åù¤Î¥¹¥¿¥¤¥ë¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
204
205     stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed 
206     Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
207
208     adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif
209     Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤Ë´Ø¤¹¤ë¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
210
211     registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1
212     Åù¤Î¥ì¥¸¥¹¥È¥ê¾ðÊó¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
213
214     size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹À°¿ôÃͤǤ¢¤ê¡¢
215     Ã±°Ì¤Ï1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£
216
217     resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤òɽ¤ï¤¹
218     À°¿ôÃͤǤ¢¤ê¡¢Ã±°Ì¤Ïdots per inch (dpi) ¤Ç¤¢¤ë¡£
219
220     type ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ò»Ø¼¨¤·¡¢¸½ºß Mx ¤â¤·¤¯¤Ï
221     Mfreetype ¤Ç¤¢¤ë¡£
222
223     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤Ä¤ÎÌÜŪ¤ÇÍѤ¤¤Æ¤¤¤ë¡£¥¢¥×
224     ¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¥Õ¥©¥ó¥È¤Î»ØÄê¤ò¼õ¤±¼è¤ëÌÜŪ¤È¡¢¥¢¥×¥ê¥±¡¼
225     ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤òÄ󼨤¹¤ëÌÜŪ¤Ç¤¢¤ë¡£¥¢¥×¥ê¥±¡¼
226     ¥·¥ç¥ó¥×¥í¥°¥é¥à¤ËÂФ·¤ÆÄ󼨤ò¹Ô¤¦ºÝ¤Ë¤Ï¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¤¹¤Ù
227     ¤Æ¶ñÂÎŪ¤ÊÃͤò»ý¤Ä¡£
228
229     m17n ¥é¥¤¥Ö¥é¥ê¤Ï Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¡¢FreeType¥Õ¥©¥ó¥È¡¢
230     OpenType¥Õ¥©¥ó¥È¤Î£³¼ïÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¡£
231
232     <ul>
233
234     <li> Window ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È
235
236     m17n X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢X ¥µ¡¼¥Ð¤È X ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤¬¼è¤ê°·¤¦Á´¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£
237     XLFD ¤Î³Æ¥Õ¥£¡¼¥ë¥É¤È¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ÎÂбþ¤Ï°Ê²¼¤ÎÄ̤ꡣ¤³¤Îɽ¤Ë¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤Ï̵»ë¤µ¤ì¤ë¡£
238
239 @verbatim
240     XLFD ¥Õ¥£¡¼¥ë¥É                             ¥×¥í¥Ñ¥Æ¥£
241     ---------------                             --------
242     FOUNDRY                                     foundry
243     FAMILY_NAME                                 family
244     WEIGHT_NAME                                 weight
245     SLANT                                       style
246     SETWIDTH_NAME                               stretch
247     ADD_STYLE_NAME                              adstyle
248     PIXEL_SIZE                                  size
249     RESOLUTION_Y                                resolution
250     CHARSET_REGISTRY-CHARSET_ENCODING           registry
251 @endverbatim
252
253     <li> FreeType fonts
254
255     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
256     FreeType ¤¬°·¤¦¤¹¤Ù¤Æ¤Î¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£ÊÑ¿ô 
257     #mfont_freetype_path ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤ÎÀßÄê¤È´Ä¶­ÊÑ¿ô @c M17NDIR 
258     ¤Ë±þ¤¸¤Æ½é´ü²½¤µ¤ì¤ë¡£¾ÜºÙ¤ÏÊÑ¿ô¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
259
260     ¤â¤· m17n ¥é¥¤¥Ö¥é¥ê¤¬ fontconfig ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
261     #mfont_freetype_path ¤Ë²Ã¤¨¤Æ¡¢ fontconfig ¤Ç»ÈÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤â¤¹¤Ù¤Æ¥µ¥Ý¡¼¥È¤µ¤ì¤ë¡£
262
263     FreeType ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤Ï family ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
264     FreeType ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾¤Ï¡¢²¼¤Îɽ¤Î¤è¤¦¤Ë weight, style,
265     stretch ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£
266
267 @verbatim
268     ¥¹¥¿¥¤¥ë̾          weight  style   stretch
269     ----------          ------  -----   -------
270     Regular             medium  r       normal
271     Italic              medium  i       normal
272     Bold                bold    r       normal
273     Bold Italic         bold    i       normal
274     Narrow              medium  r       condensed
275     Narrow Italic       medium  i       condensed
276     Narrow Bold         bold    r       condensed
277     Narrow Bold Italic  bold    i       condensed
278     Black               black   r       normal
279     Black Italic        black   i       normal
280     Oblique             medium  o       normal
281     BoldOblique         bold    o       normal
282 @endverbatim
283
284     ¾å¤Îɽ¤Ë¸½¤ï¤ì¤Ê¤¤¥¹¥¿¥¤¥ë̾¤Ï "Regular" ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
285
286     platform ID ¤È encoding ID ¤ÎÁȤ߹ç¤ï¤»¤¬ registry 
287     ¥×¥í¥Ñ¥Æ¥£¤ËÂбþ¤¹¤ë¡£¤¿¤È¤¨¤Ð¤¢¤ë¥Õ¥©¥ó¥È¤¬ (1 1) ¤È¤¤¤¦ ID ¤ÎÁȹ礻¤ò»ý¤Æ¤Ð¡¢
288     registry ¥×¥í¥Ñ¥Æ¥£¤Ï 1-1 ¤È¤Ê¤ë¡£ÉÑÈˤˤ¢¤é¤ï¤ì¤ëÁȹ礻¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤ÊÄêµÁºÑ¤ß
289     registry ¥×¥í¥Ñ¥Æ¥£ ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ë¡£
290
291 @verbatim
292     platform ID         encoding ID     registry ¥×¥í¥Ñ¥Æ¥£
293     -----------         -----------     -----------------
294     0                   3               unicode-bmp
295     0                   4               unicode-full
296     1                   0               apple-roman
297     3                   1               unicode-bmp
298     3                   1               unicode-full
299 @endverbatim
300
301     ¤·¤¿¤¬¤Ã¤Æ¡¢Æó¤Ä¤ÎÁȹ礻 (1 0) ¡¢(3 1) ¤ò»ý¤Ä¥Õ¥©¥ó¥È¤Ï¡¢¤½¤ì¤¾¤ì
302     registry ¥×¥í¥Ñ¥Æ¥£¤¬ 1-0, apple-roman, 3-1, unicode-bmp
303     ¤Ç¤¢¤ë£´¤Ä¤Î¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤ËÂбþ¤¹¤ë¡£
304
305     <li> OpenType ¥Õ¥©¥ó¥È
306
307     m17n ¥é¥¤¥Ö¥é¥ê¤Ï¡¢FreeType ¥é¥¤¥Ö¥é¥ê¤È OTF 
308     ¥é¥¤¥Ö¥é¥ê¤ò»ÈÍѤ¹¤ë¤è¤¦¤ËÀßÄꤹ¤ì¤Ð¡¢¤¹¤Ù¤Æ¤Î OpenType 
309     ¥Õ¥©¥ó¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡£¼ÂºÝ¤ËÍøÍѤǤ­¤ë¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤Ï FreeType
310     ¥Õ¥©¥ó¥È¤Î¾ì¹ç¤ÈƱÍͤ˺î¤é¤ì¤ë¡£OpenType ¥Õ¥©¥ó¥È¤ò FLT (Font Layout Table)
311     ·Ðͳ¤Ç»ÈÍѤ¹¤ë¤è¤¦¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ë»ØÄꤵ¤ì¤Æ¤ª¤ê¡¢FLT ¤Ë OTF 
312     ´ØÏ¢¤Î¥³¥Þ¥ó¥É (¤¿¤È¤¨¤Ð otf:deva) ¤¬¤¢¤ì¤Ð¡¢OTF ¥é¥¤¥Ö¥é¥ê¤¬¥Õ¥©¥ó¥È¤Î OpenType
313     ¥ì¥¤¥¢¥¦¥È¥Æ¡¼¥Ö¥ë¤Ë½¾¤Ã¤Æʸ»úÎó¤ò¥°¥ê¥Õ¥³¡¼¥ÉÎó¤ËÊÑ´¹¤·¡¢FreeType
314     ¥é¥¤¥Ö¥é¥ê¤¬³Æ¥°¥ê¥Õ¤Î¥Ó¥Ã¥È¥Þ¥Ã¥×¥¤¥á¡¼¥¸¤òÄ󶡤¹¤ë¡£
315
316     </ul>
317
318 */
319
320 /*=*/
321
322 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
323 /*** @addtogroup m17nInternal
324      @{ */
325
326 #include "config.h"
327
328 #include <stdio.h>
329 #include <stdlib.h>
330 #include <string.h>
331
332 #include "m17n-gui.h"
333 #include "m17n-misc.h"
334 #include "internal.h"
335 #include "mtext.h"
336 #include "symbol.h"
337 #include "plist.h"
338 #include "charset.h"
339 #include "internal-gui.h"
340 #include "font.h"
341 #include "face.h"
342 #include "fontset.h"
343
344 MPlist *mfont__driver_list;
345
346 static MSymbol M_font_capability, M_font_list, M_font_list_len;
347
348 /** Indices to font properties sorted by their priority.  */
349 static int font_score_priority[] =
350   { MFONT_SIZE,
351     MFONT_WEIGHT,
352     MFONT_STYLE,
353     MFONT_STRETCH,
354     MFONT_FAMILY,
355     MFONT_ADSTYLE,
356     MFONT_FOUNDRY
357   };
358
359 #define FONT_SCORE_PRIORITY_SIZE        \
360   (sizeof font_score_priority / sizeof font_score_priority[0])
361
362 /* Indexed by a font property MFONT_XXX, and the value is how many
363    bits to shift the difference of property values.  */
364 static int font_score_shift_bits[MFONT_SIZE + 1];
365
366 /** Predefined symbols for each font property.  The order is important
367     because the function font_score () decides how well a font matches
368     with a spec by checking how close the index is.  */
369
370 static char *common_foundry[] =
371   { "misc",
372     "adobe" };
373 static char *common_family[] =
374   { "fixed",
375     "courier",
376     "helvetica",
377     "times" };
378 static char *common_weight[] =
379   { "thin"
380     "ultralight",
381     "extralight",
382     "light",
383     "demilight",
384     "book",
385     "regular",
386     "normal",
387     "medium",
388     "demibold",
389     "semibold",
390     "bold",
391     "extrabold",
392     "ultrabold",
393     "black",
394     "heavy" };
395 static char *common_style[] =
396   { "o",
397     "i",
398     "slanted",
399     "r",
400     "rslanted",
401     "ri",
402     "ro" };
403 static char *common_stretch[] =
404   { "ultracondensed",
405     "extracondensed",
406     "condensed",
407     "narrow",
408     "semicondensed",
409     "normal",
410     "semiexpanded",
411     "expanded",
412     "extraexpanded",
413     "ultraexpanded" };
414 static char *common_adstyle[] =
415   { "serif",
416     "",
417     "sans" };
418 static char *common_registry[] =
419   { "iso8859-1" };
420
421 static unsigned short font_weight_regular;
422 static unsigned short font_weight_normal;
423 static unsigned short font_weight_medium;
424
425 /* Table containing all the data above.  */
426
427 struct MFontCommonNames
428 {
429   int num;
430   char **names;
431 };
432
433 static struct MFontCommonNames font_common_names[] =
434   {
435     { sizeof (common_foundry) / sizeof (char *), common_foundry},
436     { sizeof (common_family) / sizeof (char *), common_family},
437     { sizeof (common_weight) / sizeof (char *), common_weight},
438     { sizeof (common_style) / sizeof (char *), common_style},
439     { sizeof (common_stretch) / sizeof (char *), common_stretch},
440     { sizeof (common_adstyle) / sizeof (char *), common_adstyle},
441     { sizeof (common_registry) / sizeof (char *), common_registry}
442   };
443
444
445 /** Table of available font property names.  */
446
447 MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
448
449
450 /** Return the numeric value of SYMBOL as the Nth font property.  */
451
452 #define FONT_PROPERTY_NUMERIC(symbol, n)        \
453   ((symbol) == Mnil                             \
454    ? 0                                          \
455    : ((int) msymbol_get ((symbol), mfont__property_table[(n)].property)))
456
457
458 /** Set the numeric value of SYMBOL as the Nth font property to NUMERIC.  */
459
460 #define SET_FONT_PROPERTY_NUMERIC(symbol, n, numeric)           \
461   msymbol_put((symbol), mfont__property_table[(n)].property,    \
462               (void *) (numeric))
463
464 \f
465 /* Font selector.  */
466
467 struct MFontEncoding {
468   MFont spec;
469   MSymbol encoding_name;
470   MCharset *encoding_charset;
471   MSymbol repertory_name;
472   MCharset *repertory_charset;
473 };
474
475 static MPlist *font_encoding_list;
476 static MFontEncoding default_encoding;
477
478 /** Load font encoding table from the data <font encoding>.
479     The data has this form:
480         (FONT-SPEC ENCODING) ...
481     where FONT-SPEC has this form:
482         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
483     All elements are symbols.  */
484
485 static int
486 load_font_encoding_table ()
487 {
488   MDatabase *mdb;
489   MPlist *encoding_list, *plist, *pl, *elt;
490
491   font_encoding_list = pl = mplist ();
492
493   mdb = mdatabase_find (Mfont, msymbol ("encoding"), Mnil, Mnil);
494   if (! mdb
495       || ! (encoding_list = (MPlist *) mdatabase_load (mdb)))
496     MERROR (MERROR_FONT, -1);
497
498   MPLIST_DO (plist, encoding_list)
499     {
500       MFontEncoding *encoding;
501       MSymbol registry;
502
503       MSTRUCT_CALLOC (encoding, MERROR_FONT);
504
505       if (! MPLIST_PLIST_P (plist)
506           || (elt = MPLIST_PLIST (plist), mplist_length (elt) < 2)
507           || ! MPLIST_PLIST_P (elt))
508         MWARNING (MERROR_FONT);
509       registry = mfont__set_spec_from_plist (&encoding->spec,
510                                              MPLIST_PLIST (elt));
511       elt = MPLIST_NEXT (elt);
512       if (! MPLIST_SYMBOL_P (elt))
513         MWARNING (MERROR_FONT);
514       encoding->encoding_name = MPLIST_SYMBOL (elt);
515       elt = MPLIST_NEXT (elt);
516       if (MPLIST_TAIL_P (elt))
517         encoding->repertory_name = encoding->encoding_name;
518       else if (! MPLIST_SYMBOL_P (elt))
519         MWARNING (MERROR_FONT);
520       else
521         encoding->repertory_name = MPLIST_SYMBOL (elt);
522
523       if (registry == Mnil)
524         mplist_push (font_encoding_list, Mt, encoding);
525       else
526         pl = mplist_add (pl, registry, encoding);
527       continue;
528
529     warning:
530       free (encoding);
531     }
532
533   M17N_OBJECT_UNREF (encoding_list);
534   return 0;
535 }
536
537 typedef struct {
538   MFont spec;
539   int resize;
540 } MFontResize;
541
542 static MPlist *font_resize_list;
543
544 /** Load font size table from the data <font size>.
545     The data has this form:
546         (FONT-SPEC RESIZE-FACTOR) ...
547     where FONT-SPEC has this form:
548         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
549     All elements of FONT-SPEC are symbols.  */
550
551 static int
552 load_font_resize_table ()
553 {
554   MDatabase *mdb;
555   MPlist *size_adjust_list, *plist, *pl, *elt;
556
557   font_resize_list = pl = mplist ();
558
559   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
560   if (! mdb)
561     return -1;
562   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
563     MERROR (MERROR_FONT, -1);
564
565   MPLIST_DO (plist, size_adjust_list)
566     {
567       MFontResize *resize;
568       MSymbol registry;
569
570       MSTRUCT_CALLOC (resize, MERROR_FONT);
571
572       if (! MPLIST_PLIST_P (plist)
573           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
574           || ! MPLIST_PLIST_P (elt))
575         MWARNING (MERROR_FONT);
576       registry = mfont__set_spec_from_plist (&resize->spec,
577                                              MPLIST_PLIST (elt));
578       elt = MPLIST_NEXT (elt);
579       if (! MPLIST_INTEGER_P (elt))
580         MWARNING (MERROR_FONT);
581       resize->resize = MPLIST_INTEGER (elt);
582
583       if (registry == Mnil)
584         registry = Mt;
585       pl = mplist_add (pl, registry, resize);
586       continue;
587
588     warning:
589       free (resize);
590     }
591
592   M17N_OBJECT_UNREF (size_adjust_list);
593   return 0;
594 }
595
596 /** Return a font encoding (and repertory) of FONT.  */
597
598 static MFontEncoding *
599 find_encoding (MFont *font)
600 {
601   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
602   MFontEncoding *encoding = NULL;
603   MPlist *plist;
604
605   if (! font_encoding_list)
606     load_font_encoding_table ();
607   plist = font_encoding_list;
608   while (! MPLIST_TAIL_P (plist))
609     {
610       encoding = (MFontEncoding *) MPLIST_VAL (plist);
611       if (mfont__match_p (font, &encoding->spec, MFONT_REGISTRY))
612         {
613           if (encoding->encoding_name != Mnil
614               && ! encoding->encoding_charset)
615             {
616               encoding->encoding_charset = MCHARSET (encoding->encoding_name);
617               if (! encoding->encoding_charset)
618                 {
619                   mplist_pop (plist);
620                   continue;
621                 }
622             }
623           if (encoding->repertory_name == encoding->encoding_name)
624             encoding->repertory_charset = encoding->encoding_charset;
625           else if (encoding->repertory_name != Mnil)
626             {
627               encoding->repertory_charset
628                 = MCHARSET (encoding->repertory_name);
629               if (! encoding->repertory_charset)
630                 {
631                   mplist_pop (plist);
632                   continue;
633                 }
634             }
635           font->encoding = encoding;
636           return encoding;
637         }
638
639       if (registry && MPLIST_KEY (plist) != Mt)
640         {
641           plist = mplist_find_by_key (plist, registry);
642           if (! plist)
643             break;
644         }
645       else
646         plist = MPLIST_NEXT (plist);
647     }
648   font->encoding = &default_encoding;
649   return &default_encoding;
650 }
651
652 #ifndef HAVE_OTF
653 static OTF_Tag
654 OTF_tag (char *name)
655 {
656   unsigned char *p = (unsigned char *) name;
657
658   if (! name)
659     return (OTF_Tag) 0;
660   return (OTF_Tag) ((p[0] << 24)
661                     | (! p[1] ? 0
662                        : ((p[1] << 16)
663                           | (! p[2] ? 0
664                              : (p[2] << 8) | p[3]))));
665 }
666 #endif /* not HAVE_OTF */
667
668 static MPlist *otf_script_list;
669
670 static int
671 load_otf_script_list ()
672 {
673   MDatabase *mdb;
674   MPlist *plist, *pl;
675
676   otf_script_list = mplist ();
677   mdb = mdatabase_find (msymbol ("standard"), Mscript, msymbol ("otf"), Mnil);
678   if (! mdb
679       || ! (plist = mdatabase_load (mdb)))
680     MERROR (MERROR_FONT, -1);
681   MPLIST_DO (pl, plist)
682     {
683       MPlist *p;
684       MSymbol script, otf_script;
685       OTF_Tag tag;
686
687       if (! MPLIST_PLIST_P (pl))
688         continue;
689       p = MPLIST_PLIST (pl);
690       if (! MPLIST_SYMBOL_P (p))
691         continue;
692       script = MPLIST_SYMBOL (p);
693       p = MPLIST_NEXT (p);
694       if (! MPLIST_SYMBOL_P (p))
695         continue;
696       otf_script = MPLIST_SYMBOL (p);
697       tag = OTF_tag (MSYMBOL_NAME (otf_script));
698       mplist_push (otf_script_list, script, (void *) tag);
699     }
700   M17N_OBJECT_UNREF (plist);
701   return 0;
702 }
703
704 static MSymbol
705 find_script_from_otf_tag (OTF_Tag tag)
706 {
707   MPlist *plist;
708
709   if (! otf_script_list)
710     load_otf_script_list ();
711   plist = mplist_find_by_value (otf_script_list, (void *) tag);
712   return (plist ? MPLIST_KEY (plist) : Mnil);
713 }
714
715
716 /* XLFD parser/generator */
717
718 /** Indices to each field of split font name.  */
719
720 enum xlfd_field_idx
721   {
722     XLFD_FOUNDRY,
723     XLFD_FAMILY,
724     XLFD_WEIGHT,
725     XLFD_SLANT,
726     XLFD_SWIDTH,
727     XLFD_ADSTYLE,
728     XLFD_PIXEL,
729     XLFD_POINT,
730     XLFD_RESX,
731     XLFD_RESY,
732     XLFD_SPACING,
733     XLFD_AVGWIDTH,
734     XLFD_REGISTRY,              /* This contains ENCODING.  */
735     /* anchor */
736     XLFD_FIELD_MAX
737   };
738
739 static int
740 xlfd_parse_name (const char *name, MFont *font)
741 {
742   char *field[XLFD_FIELD_MAX];
743   unsigned short resy, avgwidth;
744   unsigned size;
745   char copy[513];
746   int i;
747   char *p;
748
749   if (name[0] != '-')
750     return -1;
751
752   field[0] = copy;
753   for (i = 1, p = copy, name++; *name; p++, name++)
754     {
755       if (p - copy > 512)
756         return -1;
757       if (*name == '-'
758           && i < XLFD_FIELD_MAX)
759         {
760           *p = '\0';
761           if (field[i - 1][0] == '*')
762             field[i - 1] = NULL;
763           field[i++] = p + 1;
764         }
765       else
766         *p = tolower (*name);
767     }
768   *p = '\0';
769   if (field[i - 1][0] == '*')
770     field[i - 1] = NULL;
771   while (i < XLFD_FIELD_MAX)
772     field[i++] = NULL;
773
774   resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
775   avgwidth = ((field[XLFD_AVGWIDTH] && isdigit (field[XLFD_AVGWIDTH][0]))
776               ? atoi (field[XLFD_AVGWIDTH]) : 1);
777   if (! avgwidth)
778     size = 0;
779   else if (! field[XLFD_PIXEL])
780     size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
781   else if (field[XLFD_PIXEL][0] == '[')
782     {
783       /* The pixel size field specifies a transformation matrix of the
784          form "[A B C D]".  The XLFD spec says that the scalar value N
785          for the pixel size is equivalent to D.  */
786       char *p0 = field[XLFD_PIXEL] + 1, *p1;
787       double d;
788
789       for (i = 0; i < 4; i++, p0 = p1)
790         d = strtod (p0, &p1);
791       size = d * 10;
792     }
793   else
794     size = atoi (field[XLFD_PIXEL]) * 10;
795
796   if (field[XLFD_FOUNDRY])
797     mfont__set_property (font, MFONT_FOUNDRY, msymbol (field[XLFD_FOUNDRY]));
798   if (field[XLFD_FAMILY])
799     mfont__set_property (font, MFONT_FAMILY, msymbol (field[XLFD_FAMILY]));
800   if (field[XLFD_WEIGHT])
801     mfont__set_property (font, MFONT_WEIGHT, msymbol (field[XLFD_WEIGHT]));
802   if (field[XLFD_SLANT])
803     mfont__set_property (font, MFONT_STYLE, msymbol (field[XLFD_SLANT]));
804   if (field[XLFD_SWIDTH])
805     mfont__set_property (font, MFONT_STRETCH, msymbol (field[XLFD_SWIDTH]));
806   if (field[XLFD_ADSTYLE])
807     mfont__set_property (font, MFONT_ADSTYLE, msymbol (field[XLFD_ADSTYLE]));
808   font->property[MFONT_RESY] = resy;
809   font->size = size;
810   if (field[XLFD_SPACING])
811     font->spacing
812       = ((field[XLFD_SPACING][0] == 'p' || field[XLFD_SPACING][0] == 'P')
813          ? MFONT_SPACING_PROPORTIONAL
814          : (field[XLFD_SPACING][0] == 'm' || field[XLFD_SPACING][0] == 'M')
815          ? MFONT_SPACING_MONO : MFONT_SPACING_CHARCELL);
816   if (field[XLFD_REGISTRY])
817     mfont__set_property (font, MFONT_REGISTRY, msymbol (field[XLFD_REGISTRY]));
818   font->type = MFONT_TYPE_SPEC;
819   font->source = MFONT_SOURCE_X;
820   return 0;
821 }
822
823 static char *
824 xlfd_unparse_name (MFont *font)
825 {
826   MSymbol prop[7];
827   char name[513];
828   char *str[7];
829   int len, i;
830   char spacing;
831   int size, resy;
832
833   prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
834   prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
835   prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
836   prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
837   prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
838   prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
839   prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
840   for (len = 0, i = 0; i < 7; i++)
841     {
842       if (prop[i] != Mnil)
843         {
844           str[i] = msymbol_name (prop[i]);
845           len += strlen (str[i]);
846         }
847       else
848         {
849           str[i] = "*";
850           len++;
851         }
852     }
853   spacing = (font->spacing == MFONT_SPACING_UNDECIDED ? '*'
854              : font->spacing == MFONT_SPACING_PROPORTIONAL ? 'p'
855              : font->spacing == MFONT_SPACING_MONO ? 'm'
856              : 'c');
857
858   if ((len
859        + 13                     /* 13 dashes */
860        + 2                      /* 2 asterisks */
861        + 30                     /* 3 integers (each 10 digits) */
862        + 1                      /* 1 spacing char */
863        + 1)                     /* '\0' terminal */
864       > 513)
865     return NULL;
866
867   resy = (int) mfont_get_prop (font, Mresolution);
868   size = font->size;
869   if (size >= 0)
870     {
871       if ((size % 10) < 5)
872         size /= 10;
873       else
874         size = size / 10 + 1;
875     }
876   else
877     size = - size;
878
879   if (font->size >= 0)
880     sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-%c-*-%s",
881              str[0], str[1], str[2], str[3], str[4], str[5],
882              size, resy, resy, spacing, str[6]);
883   else
884     sprintf (name, "-%s-%s-%s-%s-%s-%s-*-%d-%d-%d-%c-*-%s",
885              str[0], str[1], str[2], str[3], str[4], str[5],
886              size, resy, resy, spacing, str[6]);
887   return strdup (name);
888 }
889
890 /* Compare FONT with REQUEST and return how much they differs.  */
891
892 static int
893 font_score (MFont *font, MFont *request)
894 {
895   int score = 0;
896   int i = FONT_SCORE_PRIORITY_SIZE;
897
898   while (--i >= 0)
899     {
900       enum MFontProperty prop = font_score_priority[i];
901       int val;
902
903       if (prop == MFONT_SIZE)
904         {
905           if (font->size && request->size)
906             {
907               val = font->size - request->size;
908               if (val)
909                 {
910                   if (val < 0)
911                     val = - val;
912                   if (val >= 0x10000)
913                     val = 0xFFFF;
914                   score |= (val << font_score_shift_bits[MFONT_SIZE]);
915                 }
916             }
917         }
918       else if (font->property[prop] && request->property[prop]
919                && font->property[prop] != request->property[prop])
920         {
921           if (prop <= MFONT_FAMILY)
922             val = 1;
923           else if (prop == MFONT_WEIGHT)
924             {
925               unsigned short v1 = font->property[prop];
926               unsigned short v2 = request->property[prop];
927
928               if (v1 == font_weight_regular || v1 == font_weight_normal)
929                 v1 = font_weight_medium;
930               if (v2 == font_weight_regular || v2 == font_weight_normal)
931                 v2 = font_weight_medium;
932               val = v1 > v2 ? v1 - v2 : v2 - v1;
933             }
934           else
935             {
936               val = font->property[prop] - request->property[prop];
937               if (val < 0)
938                 val = - val;
939               if (val > 3)
940                 val = 3;
941             }
942           score |= val << font_score_shift_bits[prop];
943         }
944     }
945   if (request->file != Mnil && request->file != font->file)
946     score |= 40000000;
947   return score;
948 }
949
950 \f
951 /* Internal API */
952
953 MSymbol Miso8859_1, Miso10646_1, Municode_bmp, Municode_full, Mapple_roman;
954
955 int
956 mfont__init ()
957 {
958   int i, shift;
959   MSymbol regular = msymbol ("regular");
960   MSymbol normal = msymbol ("normal");
961   MSymbol medium = msymbol ("medium");
962
963   M_font_capability = msymbol_as_managing_key ("  font-capability");
964   M_font_list = msymbol_as_managing_key ("  font-list");
965   M_font_list_len = msymbol ("  font-list-len");
966
967   Mfoundry = msymbol ("foundry");
968   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
969   Mfamily = msymbol ("family");
970   mfont__property_table[MFONT_FAMILY].property = Mfamily;
971   Mweight = msymbol ("weight");
972   mfont__property_table[MFONT_WEIGHT].property = Mweight;
973   Mstyle = msymbol ("style");
974   mfont__property_table[MFONT_STYLE].property = Mstyle;
975   Mstretch = msymbol ("stretch");
976   mfont__property_table[MFONT_STRETCH].property = Mstretch;
977   Madstyle = msymbol ("adstyle");
978   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
979   Mregistry = msymbol ("registry");
980   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
981
982   Mspacing = msymbol ("spacing");
983   Msize = msymbol ("size");
984   Mresolution = msymbol ("resolution");
985   Mmax_advance = msymbol ("max-advance");
986   Mfontfile = msymbol ("fontfile");
987
988   Mfontconfig = msymbol ("fontconfig");
989
990   Mx = msymbol ("x");
991   Mfreetype = msymbol ("freetype");
992   Mxft = msymbol ("xft");
993
994   Miso8859_1 = msymbol ("iso8859-1");
995   Miso10646_1 = msymbol ("iso10646-1");
996   Municode_bmp = msymbol ("unicode-bmp");
997   Municode_full = msymbol ("unicode-full");
998   Mapple_roman = msymbol ("apple-roman");
999
1000   /* The first entry of each mfont__property_table must be Mnil so
1001      that actual properties get positive numeric numbers.  */
1002   for (i = 0; i <= MFONT_REGISTRY; i++)
1003     {
1004       MLIST_INIT1 (&mfont__property_table[i], names, 8);
1005       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
1006     }
1007
1008   /* Register predefined font property names.  */
1009   for (i = 0; i <= MFONT_REGISTRY; i++)
1010     {
1011       int j;
1012
1013       for (j = 0; j < font_common_names[i].num; j++)
1014         {
1015           MSymbol sym = msymbol (font_common_names[i].names[j]);
1016
1017           if (sym == Mnil)
1018             return -1;
1019           if (msymbol_put (sym, mfont__property_table[i].property,
1020                            (void *) (j + 1)) < 0)
1021             return -1;
1022           MLIST_APPEND1 (&mfont__property_table[i], names, sym,
1023                          MERROR_FONT);
1024           if (i == MFONT_WEIGHT)
1025             {
1026               if (sym == regular)
1027                 font_weight_regular = j + 1;
1028               else if (sym == normal)
1029                 font_weight_normal = j + 1;
1030               else if (sym == medium)
1031                 font_weight_medium = j + 1;
1032             }
1033         }
1034     }
1035
1036   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
1037      of a score is a flag for a scalable font (see the documentation
1038      of font_score).  */
1039   i = FONT_SCORE_PRIORITY_SIZE - 1;
1040   for (shift = 1; i >= 0; i--)
1041     {
1042       font_score_shift_bits[font_score_priority[i]] = shift;
1043       if (font_score_priority[i] == MFONT_SIZE)
1044         shift += 16;
1045       else if (font_score_priority[i] <= MFONT_FAMILY)
1046         shift++;
1047       else
1048         shift += 2;
1049     }
1050
1051   MFONT_INIT (&default_encoding.spec);
1052   default_encoding.encoding_name = Municode_full;
1053   default_encoding.encoding_charset = mcharset__unicode;
1054   default_encoding.repertory_name = Mnil;
1055   default_encoding.repertory_charset = NULL;
1056   {
1057     char *path, *buf;
1058     int bufsize;
1059     USE_SAFE_ALLOCA;
1060
1061     mfont_freetype_path = mplist ();
1062     bufsize = strlen (M17NDIR) + 7;
1063     SAFE_ALLOCA (buf, bufsize);
1064     sprintf (buf, "%s/fonts", M17NDIR);
1065     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
1066     path = getenv ("M17NDIR");
1067     if (path)
1068       {
1069         bufsize = strlen (path) + 7;
1070         SAFE_ALLOCA (buf, bufsize);
1071         sprintf (buf, "%s/fonts", path);
1072         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
1073       }
1074     SAFE_FREE (buf);
1075   }
1076
1077 #ifdef HAVE_FREETYPE
1078   if (mfont__ft_init () < 0)
1079     return -1;
1080 #endif /* HAVE_FREETYPE */
1081   if (mfont__flt_init () < 0)
1082     return -1;
1083
1084   return 0;
1085 }
1086
1087 void
1088 mfont__fini ()
1089 {
1090   MPlist *plist;
1091   int i;
1092
1093   mfont__flt_fini ();
1094 #ifdef HAVE_FREETYPE
1095   mfont__ft_fini ();
1096 #endif /* HAVE_FREETYPE */
1097
1098   MPLIST_DO (plist, mfont_freetype_path)
1099     free (MPLIST_VAL (plist));
1100   M17N_OBJECT_UNREF (mfont_freetype_path);
1101
1102   if (font_resize_list)
1103     {
1104       MPLIST_DO (plist, font_resize_list)
1105         free (MPLIST_VAL (plist));
1106       M17N_OBJECT_UNREF (font_resize_list);
1107       font_resize_list = NULL;
1108     }
1109   if (font_encoding_list)
1110     {
1111       MPLIST_DO (plist, font_encoding_list)
1112         free (MPLIST_VAL (plist));
1113       M17N_OBJECT_UNREF (font_encoding_list);
1114       font_encoding_list = NULL;
1115     }
1116   if (otf_script_list)
1117     {
1118       M17N_OBJECT_UNREF (otf_script_list);
1119       otf_script_list = NULL;
1120     }
1121
1122   for (i = 0; i <= MFONT_REGISTRY; i++)
1123     MLIST_FREE1 (&mfont__property_table[i], names);
1124 }
1125
1126
1127 MSymbol
1128 mfont__id (MFont *font)
1129 {
1130   char *buf, *p;
1131   int i;
1132   int file_len = (font->file == Mnil ? 0 : MSYMBOL_NAMELEN (font->file));
1133   int capability_len  = (font->capability == Mnil ? 0
1134                          : MSYMBOL_NAMELEN (font->capability));
1135   int total_len = MFONT_PROPERTY_MAX * 5 + 9 + file_len + capability_len;
1136   MSymbol id;
1137   USE_SAFE_ALLOCA;
1138
1139   SAFE_ALLOCA (buf, total_len);
1140   p = buf;
1141   if (font->property[0])
1142     p += sprintf (p, "%X", font->property[0]);
1143   for (i = 1; i < MFONT_PROPERTY_MAX; i++)
1144     {
1145       if (font->property[i])
1146         p += sprintf (p, "-%X", font->property[i]);
1147       else
1148         *p++ = '-';
1149     }
1150   if (font->size)
1151     p += sprintf (p, "-%X", font->size);
1152   if (font->spacing)
1153     p += sprintf (p, "-%X", font->spacing);
1154   if (capability_len > 0)
1155     {
1156       *p++ = '-';
1157       memcpy (p, MSYMBOL_NAME (font->capability), capability_len);
1158       p += capability_len;
1159     }
1160   if (file_len > 0)
1161     {
1162       *p++ = '-';
1163       memcpy (p, MSYMBOL_NAME (font->file), file_len);
1164       p += file_len;
1165     }      
1166   id = msymbol__with_len (buf, p - buf);
1167   SAFE_FREE (buf);
1168   return id;
1169 }
1170
1171 /** Return 1 iff FONT matches SPEC.  */
1172
1173 int
1174 mfont__match_p (MFont *font, MFont *spec, int prop)
1175 {
1176   if (spec->capability != font->capability
1177       && spec->capability != Mnil && font->capability != Mnil)
1178     return 0;
1179   if (spec->file != font->file
1180       && spec->file != Mnil && font->file != Mnil)
1181     return 0;
1182   for (; prop >= 0; prop--)
1183     if (spec->property[prop] && font->property[prop]
1184         && font->property[prop] != spec->property[prop])
1185       return 0;
1186   return 1;
1187 }
1188
1189 /* Merge SRC into DST.  If error_on_conflict is nonzero and a font
1190    property differs in SRC and DST, return -1.  */
1191
1192 int
1193 mfont__merge (MFont *dst, MFont *src, int error_on_conflict)
1194 {
1195   int i;
1196
1197   for (i = 0; i < MFONT_PROPERTY_MAX; i++)
1198     {
1199       if (! dst->property[i])
1200         dst->property[i] = src->property[i];
1201       else if (error_on_conflict
1202                && src->property[i]
1203                && dst->property[i] != src->property[i])
1204         return -1;
1205     }
1206   if (! dst->spacing)
1207     dst->spacing = src->spacing;
1208   else if (error_on_conflict
1209            && src->spacing
1210            && dst->spacing != src->spacing)
1211     return -1;
1212   if (! dst->size)
1213     dst->size = src->size;
1214   else if (error_on_conflict
1215            && src->size
1216            && dst->size != src->size)
1217     return -1;
1218   if (dst->capability == Mnil)
1219     dst->capability = src->capability;
1220   else if (error_on_conflict
1221            && src->capability
1222            && dst->capability != src->capability)
1223     return -1;
1224   if (dst->file == Mnil)
1225     dst->file = src->file;
1226   else if (error_on_conflict
1227            && src->file
1228            && dst->file != src->file)
1229     return -1;
1230   return 0;
1231 }
1232
1233 void
1234 mfont__set_spec_from_face (MFont *spec, MFace *face)
1235 {
1236   int i;
1237
1238   for (i = 0; i <= MFONT_ADSTYLE; i++)
1239     mfont__set_property (spec, i, face->property[i]);
1240   spec->property[MFONT_REGISTRY] = 0;
1241   spec->property[MFONT_RESY] = 0;
1242   spec->size = (int) (face->property[MFACE_SIZE]);
1243   spec->type = MFONT_TYPE_SPEC;
1244   spec->source = MFONT_SOURCE_UNDECIDED;
1245   spec->file = spec->capability = Mnil;
1246   spec->encoding = NULL;
1247 }
1248
1249
1250 extern MSymbol
1251 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
1252 {
1253   int i;
1254   MSymbol spec_list[MFONT_REGISTRY + 1];
1255   MSymbol registry;
1256   char *reg;
1257
1258   MFONT_INIT (spec);
1259   memset (spec_list, 0, sizeof spec_list);
1260   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
1261     {
1262       if (! MPLIST_SYMBOL_P (plist))
1263         MERROR (MERROR_FONT, Mnil);     
1264       spec_list[i] = MPLIST_SYMBOL (plist);
1265     }
1266   registry = spec_list[i - 1];
1267   if (i > 1 && registry != Mnil)
1268     {
1269       reg = MSYMBOL_NAME (registry);
1270       if (reg[0] == ':')
1271         {
1272           mfont__get_capability (registry);
1273           spec->capability = registry;
1274           registry = spec_list[i - 2];
1275           i--;
1276         }
1277     }
1278   mfont__set_property (spec, MFONT_REGISTRY, registry);
1279   for (i -= 2; i >= 0; i--)
1280     mfont__set_property (spec, i, spec_list[i]);
1281   spec->type = MFONT_TYPE_SPEC;
1282
1283   return registry;
1284 }
1285
1286
1287 MFont *
1288 mfont__select (MFrame *frame, MFont *font, int max_size)
1289 {
1290   MFontDriver *driver;
1291
1292   if (font->type == MFONT_TYPE_FAILURE)
1293     return NULL;
1294   if (font->type != MFONT_TYPE_SPEC)
1295     return font;
1296   if (font->source == MFONT_SOURCE_UNDECIDED)
1297     {
1298       if (font->file != Mnil || font->capability != Mnil)
1299         font->source = MFONT_SOURCE_FT;
1300       else if (font->property[MFONT_REGISTRY])
1301         {
1302           MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1303           char *reg = MSYMBOL_NAME (registry);
1304
1305           if (strncmp (reg, "unicode-", 8) == 0
1306               || strncmp (reg, "apple-roman", 11) == 0
1307               || (reg[0] >= '0' && reg[0] <= '9' && reg[1] == '-'))
1308             font->source = MFONT_SOURCE_FT;
1309         }
1310     }
1311   if (font->source != MFONT_SOURCE_FT)
1312     {
1313       driver = mplist_get (frame->font_driver_list, Mx);
1314       if (driver)
1315         return (driver->select) (frame, font, max_size);
1316     }
1317   driver = mplist_get (frame->font_driver_list, Mfreetype);
1318   if (! driver)
1319     return NULL;
1320   return (driver->select) (frame, font, max_size);
1321 }
1322
1323
1324 int
1325 mfont__available (MFrame *frame, MFont *font)
1326 {
1327   return -1;
1328 }
1329
1330 static int
1331 compare_font_score (const void *e1, const void *e2)
1332 {
1333   return (((MFontScore *) e1)->score > ((MFontScore *) e2)->score);
1334 }
1335
1336 void
1337 mdebug_dump_font_list (MFontList *font_list)
1338 {
1339   int i;
1340
1341   for (i = 0; i < font_list->nfonts; i++)
1342     {
1343       fprintf (stderr, "%04X - ", font_list->fonts[i].score);
1344       mdebug_dump_font (font_list->fonts[i].font);
1345       fprintf (stderr, "\n");
1346     }
1347 }
1348
1349 void
1350 mfont__free_realized (MRealizedFont *rfont)
1351 {
1352   MRealizedFont *next;
1353
1354   for (; rfont; rfont = next)
1355     {
1356       next = rfont->next;
1357       M17N_OBJECT_UNREF (rfont->info);
1358       free (rfont);
1359       rfont = next;
1360     }
1361 }
1362
1363 MFontList *
1364 mfont__list (MFrame *frame, MFont *spec, MFont *request, int max_size)
1365 {
1366   MFontList *list;
1367   MSymbol id = mfont__id (spec);
1368   MPlist *pl, *p;
1369   int num, i;
1370
1371   pl = msymbol_get (id, M_font_list);
1372   if (pl)
1373     num = (int) msymbol_get (id, M_font_list_len);
1374   else
1375     {
1376       pl = mplist ();
1377       num = 0;
1378       MPLIST_DO (p, frame->font_driver_list)
1379         {
1380           if (spec->source == MFONT_SOURCE_X ? MPLIST_KEY (p) == Mx
1381               : spec->source == MFONT_SOURCE_FT ? MPLIST_KEY (p) == Mfreetype
1382               : 1)
1383             {
1384               MFontDriver *driver = MPLIST_VAL (p);
1385               num += (driver->list) (frame, pl, spec, 0);
1386             }
1387         }
1388       msymbol_put (id, M_font_list, pl);
1389       M17N_OBJECT_UNREF (pl);
1390       msymbol_put (id, M_font_list_len, (void *) num);
1391     }
1392   
1393   if (num == 0)
1394     return NULL;
1395
1396   MSTRUCT_MALLOC (list, MERROR_FONT);
1397   MTABLE_MALLOC (list->fonts, num, MERROR_FONT);
1398   for (i = 0; num > 0; num--, pl = MPLIST_NEXT (pl))
1399     {
1400       MFont *font = MPLIST_VAL (pl);
1401
1402       if (max_size == 0
1403           || font->size == 0
1404           || font->size < max_size)
1405         {
1406           list->fonts[i].font = font;
1407           list->fonts[i].score
1408             = spec == request ? 0 : font_score (font, request);
1409           i++;
1410         }
1411     }
1412   if (i == 0)
1413     {
1414       free (list->fonts);
1415       free (list);
1416       return NULL;
1417     }
1418   list->nfonts = i;
1419   if (spec != request)
1420     qsort (list->fonts, i, sizeof (MFontScore), compare_font_score);
1421   list->object = *spec;
1422   mfont__merge (&list->object, request, 0);
1423   list->object.type = MFONT_TYPE_OBJECT;
1424   return list;
1425 }
1426
1427 /** Open a font specified in FONT.  */
1428
1429 MRealizedFont *
1430 mfont__open (MFrame *frame, MFont *font, MFont *spec)
1431 {
1432   MFontDriver *driver;
1433   MRealizedFont *rfont;
1434
1435   if (font->source == MFONT_SOURCE_UNDECIDED)
1436     MFATAL (MERROR_FONT);
1437   if (font->type != MFONT_TYPE_OBJECT)
1438     MFATAL (MERROR_FONT);
1439   for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
1440        rfont = rfont->next)
1441     {
1442       driver = rfont->driver;
1443       if (rfont->font == font
1444           && mplist_find_by_value (frame->font_driver_list, driver))
1445         break;
1446     }
1447
1448   if (! rfont)
1449     {
1450       driver = mplist_get (frame->font_driver_list,
1451                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1452       if (! driver)
1453         MFATAL (MERROR_FONT);
1454     }
1455   return (driver->open) (frame, font, spec, rfont);
1456 }
1457
1458 void
1459 mfont__resize (MFont *spec, MFont *request)
1460 {
1461   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1462   MFontResize *resize;
1463   MPlist *plist;
1464
1465   if (! font_resize_list)
1466     load_font_resize_table ();
1467   if (! MPLIST_TAIL_P (font_resize_list))
1468     while (1)
1469       {
1470         plist = font_resize_list;
1471         while (registry ? (plist = mplist_find_by_key (plist, registry))
1472                : plist)
1473           {
1474             resize = (MFontResize *) MPLIST_VAL (plist);
1475             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1476               {
1477                 request->size = request->size * resize->resize / 100;
1478                 return;
1479               }
1480             plist = MPLIST_NEXT (plist);
1481           }
1482         if (registry == Mt)
1483           break;
1484         registry = Mt;
1485       }
1486 }
1487
1488
1489 int
1490 mfont__has_char (MFrame *frame, MFont *font, MFont *spec, int c)
1491 {
1492   MFontEncoding *encoding;
1493   unsigned code;
1494   MFontDriver *driver;
1495
1496   if (font->source == MFONT_SOURCE_UNDECIDED)
1497     MFATAL (MERROR_FONT);
1498   encoding = (font->encoding ? font->encoding : find_encoding (font));
1499   if (! encoding->encoding_charset)
1500     return 0;
1501   if (encoding->repertory_charset)
1502     {
1503       code = ENCODE_CHAR (encoding->repertory_charset, c);
1504       return (code != MCHAR_INVALID_CODE);
1505     }
1506   code = ENCODE_CHAR (encoding->encoding_charset, c);
1507   if (code == MCHAR_INVALID_CODE)
1508     return 0;
1509   if (font->type == MFONT_TYPE_REALIZED)
1510     driver = ((MRealizedFont *) font)->driver;
1511   else
1512     {
1513       driver = mplist_get (frame->font_driver_list,
1514                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1515       if (! driver)
1516         MFATAL (MERROR_FONT);
1517     }
1518   return (driver->has_char) (frame, font, spec, c, code);
1519 }
1520
1521 unsigned
1522 mfont__encode_char (MFrame *frame, MFont *font, MFont *spec, int c)
1523 {
1524   MFontEncoding *encoding;
1525   unsigned code;
1526   MFontDriver *driver;
1527
1528   if (font->source == MFONT_SOURCE_UNDECIDED)
1529     MFATAL (MERROR_FONT);
1530   encoding = (font->encoding ? font->encoding : find_encoding (font));
1531   if (! encoding->encoding_charset)
1532     return MCHAR_INVALID_CODE;
1533   if (encoding->repertory_charset)
1534     return (ENCODE_CHAR (encoding->repertory_charset, c));
1535   code = ENCODE_CHAR (encoding->encoding_charset, c);
1536   if (code == MCHAR_INVALID_CODE)
1537     return MCHAR_INVALID_CODE;
1538   if (font->type == MFONT_TYPE_REALIZED)
1539     driver = ((MRealizedFont *) font)->driver;
1540   else
1541     {
1542       driver = mplist_get (frame->font_driver_list,
1543                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1544       if (! driver)
1545         MFATAL (MERROR_FONT);
1546     }
1547   return (driver->encode_char) (frame, font, spec, code);
1548 }
1549
1550 void
1551 mfont__get_metric (MGlyphString *gstring, int from, int to)
1552 {
1553   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1554   MRealizedFont *rfont = from_g->rface->rfont;
1555
1556   for (g = from_g; g != to_g; g++)
1557     if (g->rface->rfont != rfont)
1558       {
1559         int idx = GLYPH_INDEX (g);
1560
1561         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1562         from_g = g;
1563         rfont = g->rface->rfont;
1564         from = idx;
1565       }
1566   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1567 }
1568
1569
1570 /* KEY <= MFONT_REGISTRY */
1571
1572 void
1573 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1574 {
1575   int numeric;
1576
1577   if (val == Mnil)
1578     numeric = 0;
1579   else
1580     {
1581       numeric = FONT_PROPERTY_NUMERIC (val, key);
1582       if (! numeric)
1583         {
1584           numeric = mfont__property_table[key].used;
1585           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1586           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1587         }
1588     }
1589   font->property[key] = numeric;
1590 }
1591
1592 int
1593 mfont__parse_name_into_font (const char *name, MSymbol format, MFont *font)
1594 {
1595   int result = -1;
1596
1597   if (format == Mx || format == Mnil)
1598     result = xlfd_parse_name (name, font);
1599 #ifdef HAVE_FONTCONFIG
1600   if (format == Mfontconfig || (result < 0 && format == Mnil))
1601     result = mfont__ft_parse_name (name, font);
1602 #endif /* HAVE_FONTCONFIG */
1603   return result;
1604 }
1605
1606 MPlist *
1607 mfont__encoding_list (void)
1608 {
1609   if (! font_encoding_list)
1610     load_font_encoding_table ();
1611   return font_encoding_list;
1612 }
1613
1614 static void
1615 free_font_capability (void *object)
1616 {
1617   MFontCapability *cap = object;
1618   int i;
1619   
1620   if (cap->lang)
1621     free (cap->lang);
1622 #ifdef HAVE_OTF
1623   if (cap->script)
1624     for (i = 0; i < MFONT_OTT_MAX; i++)
1625       {
1626         if (cap->features[i].str)
1627           free (cap->features[i].str);
1628         if (cap->features[i].tags)
1629           free (cap->features[i].tags);
1630       }
1631 #endif /* HAVE_OTF */
1632   free (cap);
1633 }
1634
1635 MFontCapability *
1636 mfont__get_capability (MSymbol sym)
1637 {
1638   MFontCapability *cap = msymbol_get (sym, M_font_capability);
1639   char *str, *p, *endp;
1640   int i;
1641
1642   if (cap)
1643     return cap;
1644   str = MSYMBOL_NAME (sym);
1645   if (str[0] != ':')
1646     return NULL;
1647   M17N_OBJECT (cap, free_font_capability, MERROR_FONT);
1648   msymbol_put (sym, M_font_capability, cap);
1649   M17N_OBJECT_UNREF (cap);
1650   endp = str + MSYMBOL_NAMELEN (sym);
1651   while (str < endp)
1652     {
1653       if (*str++ != ':')
1654         continue;
1655 #ifdef HAVE_OTF
1656       if (str[0] == 'o' && str[1] == 't' && str[2] == 'f' && str[3] == '=')
1657         {
1658           str += 4;
1659           for (i = 0, p = str; i < 4 && p < endp; i++, p++);
1660           if (i < 4)
1661             break;
1662           cap->script_tag = OTF_tag (str);
1663           cap->script = find_script_from_otf_tag (cap->script_tag);
1664           if (*p == '/')
1665             {
1666               for (i = 0, str = ++p; i < 4 && p < endp; i++, p++);
1667               if (i < 4)
1668                 {
1669                   cap->script = Mnil;
1670                   break;
1671                 }
1672               cap->langsys_tag = OTF_tag (str);
1673             }
1674           else
1675             cap->langsys_tag = 0;
1676
1677           for (i = 0; i < MFONT_OTT_MAX; i++)
1678             cap->features[i].nfeatures = -1;
1679
1680           while (*p == '=' || *p == '+')
1681             {
1682               int idx = *p == '=' ? MFONT_OTT_GSUB : MFONT_OTT_GPOS;
1683
1684               str = ++p;
1685               while (p < endp && *p != '+') p++;
1686               if (str < p)
1687                 {
1688                   int n;
1689                   /* We never have more than (p - str) tags.  */
1690                   OTF_Tag *tags = alloca (sizeof (OTF_Tag) * (p - str));
1691                   char *p0;
1692
1693                   cap->features[idx].str = malloc (p - str + 1);
1694                   for (i = n = 0, p0 = str; str + i < p; i++)
1695                     {
1696                       cap->features[idx].str[i] = str[i];
1697                       if (str[i] == ',' || str + i + 1 == p)
1698                         {
1699                           if (*p0 == '*')
1700                             tags[n] = 0;
1701                           else if (*p0 == '~')
1702                             tags[n] = OTF_tag (p0 + 1) | 0x80000000;
1703                           else
1704                             tags[n] = OTF_tag (p0);
1705                           n++;
1706                           p0 = str + i + 1;
1707                         }
1708                     }
1709                   cap->features[idx].str[i] = '\0';
1710                   cap->features[idx].nfeatures = n;
1711                   if (n > 0)
1712                     {
1713                       int size = sizeof (OTF_Tag) * n;
1714
1715                       cap->features[idx].tags = malloc (size);
1716                       memcpy (cap->features[idx].tags, tags, size);
1717                     }
1718                 }
1719               else
1720                 {
1721                   cap->features[idx].str = NULL;
1722                   cap->features[idx].nfeatures = 0;
1723                 }
1724             }
1725
1726           for (i = 0; i < MFONT_OTT_MAX; i++)
1727             if (cap->features[i].nfeatures < 0)
1728               {
1729                 cap->features[i].str = strdup ("*");
1730                 cap->features[i].nfeatures = 1;
1731                 cap->features[i].tags = malloc (sizeof (OTF_Tag));
1732                 cap->features[i].tags[0] = 0;
1733               }
1734           str = p;
1735           continue;
1736         }
1737 #endif /* HAVE_OTF */
1738       if (str[0] == 'l' && str[1] == 'a' && str[2] == 'n' && str[3] == 'g'
1739           && str[4] == '=')
1740         {
1741           int count;
1742
1743           str += 5;
1744           for (p = str, count = 2; p < endp && *p != ':'; p++)
1745             if (*p == ',')
1746               count++;
1747           MTABLE_MALLOC (cap->lang, count, MERROR_FONT);
1748           for (p = str, count = 0; p < endp && *p != ':'; p++)
1749             if (*p == ',')
1750               {
1751                 MSymbol lang = msymbol__with_len (str, p - str), sym;
1752
1753                 if (msymbol_get (lang, Miso639_2))
1754                   cap->lang[count++] = lang;
1755                 else if ((sym = msymbol_get (lang, Miso639_1)) != Mnil)
1756                   cap->lang[count++] = sym;
1757                 else if (msymbol_get (lang, Mlanguage))
1758                   cap->lang[count++] = lang;
1759                 str = p + 1;
1760               }
1761           if (str < p)
1762             cap->lang[count++] = msymbol__with_len (str, p - str);
1763           cap->lang[count] = Mnil;
1764           str = p;
1765         }
1766       else if (str[0] == 's' && str[1] == 'c' && str[2] == 'r' && str[3] == 'i'
1767                && str[4] == 'p' && str[5] == 't' && str[6] == '=')
1768         {
1769           str += 7;
1770           for (p = str; p < endp && *p != ':'; p++);
1771           if (str < p)
1772             cap->script = msymbol__with_len (str, p - str);
1773           str = p;
1774         }
1775     }
1776   return cap;
1777 }
1778
1779 /*** @} */
1780 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1781
1782 \f
1783
1784 /* External API */
1785
1786 /*** @addtogroup m17nFont */
1787 /*** @{ */
1788 /*=*/
1789
1790 /***en @name Variables: Keys of font property.  */
1791 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1792 /*** @{ */
1793 /*=*/
1794
1795 /***en
1796     @brief Key of font property specifying foundry.
1797
1798     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1799     is used as a key of font property and face property.  The property
1800     value must be a symbol whose name is a foundry name of a font.  */
1801 /***ja
1802     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1803     
1804     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> 
1805     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1806     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1807
1808 MSymbol Mfoundry;
1809
1810 /***en
1811     @brief Key of font property specifying family.
1812
1813     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1814     used as a key of font property and face property.  The property
1815     value must be a symbol whose name is a family name of a font.  */ 
1816 /***ja
1817     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1818     
1819     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> 
1820     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1821     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1822
1823 MSymbol Mfamily;
1824
1825 /***en
1826     @brief Key of font property specifying weight.
1827
1828     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1829     used as a key of font property and face property.  The property
1830     value must be a symbol whose name is a weight name of a font (e.g
1831     "medium", "bold").  */ 
1832 /***ja
1833     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1834     
1835     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> 
1836     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1837     Ãͤϡ¢¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1838
1839 MSymbol Mweight;
1840
1841 /***en
1842     @brief Key of font property specifying style.
1843
1844     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1845     used as a key of font property and face property.  The property
1846     value must be a symbol whose name is a style name of a font (e.g
1847     "r", "i", "o").  */ 
1848 /***ja
1849     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1850     
1851     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> 
1852     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1853     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1854
1855 MSymbol Mstyle;
1856
1857 /***en
1858     @brief Key of font property specifying stretch.
1859
1860     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1861     is used as a key of font property and face property.  The property
1862     value must be a symbol whose name is a stretch name of a font (e.g
1863     "normal", "condensed").  */ 
1864 /***ja
1865     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1866     
1867     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> 
1868     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1869     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1870
1871 MSymbol Mstretch;
1872
1873 /***en
1874     @brief Key of font property specifying additional style.
1875
1876     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1877     is used as a key of font property and face property.  The property
1878     value must be a symbol whose name is an additional style name of a
1879     font (e.g "serif", "", "sans").  */ 
1880 /***ja
1881     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1882     
1883     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> 
1884     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1885     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1886
1887 MSymbol Madstyle;
1888
1889 /***en
1890     @brief Key of font property specifying spacing.
1891
1892     The variable #Madstyle is a symbol of name <tt>"spacing"</tt> and
1893     is used as a key of font property.  The property value must be a
1894     symbol whose name specifies the spacing of a font (e.g "p" for
1895     proportional, "m" for monospaced).  */ 
1896 /***ja
1897     @brief spacing ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1898     
1899     ÊÑ¿ô #Mspacing ¤Ï <tt>"spacing"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1900     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î spacing
1901     ÆÃÀ­¤ò¼¨¤¹Ì¾Á° ("p", "m" Åù)¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£  */
1902
1903 MSymbol Mspacing;
1904
1905 /***en
1906     @brief Key of font property specifying registry.
1907
1908     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1909     and is used as a key of font property.  The property value must be
1910     a symbol whose name is a registry name a font registry
1911     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1912 /***ja
1913     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1914     
1915     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> 
1916     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1917     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" 
1918     Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1919
1920 MSymbol Mregistry;
1921
1922 /***en
1923     @brief Key of font property specifying size.
1924
1925     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1926     used as a key of font property and face property.  The property
1927     value must be an integer specifying a font design size in the unit
1928     of 1/10 point (on 100 dpi display).  */ 
1929 /***ja
1930     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1931     
1932     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> 
1933     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1934     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 
1935     ¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
1936     */
1937
1938 MSymbol Msize;
1939
1940 /***en
1941     @brief Key of font property specifying file name.
1942
1943     The variable #Mfontfile is a symbol of name <tt>"fontfile"</tt>
1944     and is used as a key of font property.  The property value must be
1945     a symbol whose name is a font file name.  */ 
1946 /***ja
1947     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1948     
1949     ÊÑ¿ô #Mfontfile ¤Ï <tt>"fontfile"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1950     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤
1951     ¥ë̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¤È¤¹¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */
1952
1953 MSymbol Mfontfile;
1954
1955 /***en
1956     @brief Key of font property specifying resolution.
1957
1958     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1959     is used as a key of font property and face property.  The property
1960     value must be an integer to specifying a font resolution in the
1961     unit of dots per inch (dpi).  */ 
1962 /***ja
1963     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1964     
1965     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> 
1966     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1967     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£    */
1968
1969 MSymbol Mresolution;
1970
1971 /***en
1972     @brief Key of font property specifying max advance width.
1973
1974     The variable #Mmax_advance is a symbol of name
1975     <tt>"max-advance"</tt> and is used as a key of font property.  The
1976     property value must be an integer specifying a font's max advance
1977     value by pixels.  */ 
1978
1979 MSymbol Mmax_advance;
1980
1981
1982 /***en
1983     @brief Symbol of name "fontconfig".
1984
1985     The variable #Mfontconfig is to be used as an argument of the
1986     functions mfont_parse_name () and mfont_unparse_name ().  */
1987 /***ja
1988     @brief "fontconfig" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
1989
1990     ÊÑ¿ô #Mfontconfig ¤Ï´Ø¿ô mfont_parse_name () ¤È mfont_unparse_name ()
1991     ¤Î°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£  */
1992
1993 MSymbol Mfontconfig;
1994
1995 /***en
1996     @brief Symbol of name "x".
1997
1998     The variable #Mx is to be used for a value of <type> member of the
1999     structure #MDrawGlyph to specify the type of <fontp> member is
2000     actually (XFontStruct *).  */
2001 /***ja
2002     @brief "x" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2003
2004     ÊÑ¿ô #Mx ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2005     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XFontStruct *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹.  */
2006
2007 MSymbol Mx;
2008
2009 /***en
2010     @brief Symbol of name "freetype".
2011
2012     The variable #Mfreetype is to be used for a value of <type> member
2013     of the structure #MDrawGlyph to specify the type of <fontp> member
2014     is actually FT_Face.  */
2015 /***ja
2016     @brief "freetype" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2017
2018     ÊÑ¿ô #Mfreetype ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2019     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï FT_Face ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
2020
2021 MSymbol Mfreetype;
2022
2023 /***en
2024     @brief Symbol of name "xft".
2025
2026     The variable #Mxft is to be used for a value of <type> member of the
2027     structure #MDrawGlyph to specify the type of <fontp> member
2028     is actually (XftFont *).  */
2029 /***ja
2030     @brief  "xft" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2031
2032     ÊÑ¿ô #Mxft ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2033     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XftFont *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
2034
2035 MSymbol Mxft;
2036
2037 /*=*/
2038 /*** @} */
2039 /*=*/
2040
2041 /***en
2042     @brief List of font files and directories that contain font files.
2043
2044     The variable @c mfont_freetype_path is a plist of FreeType font
2045     files and directories that contain FreeType font files.  Key of
2046     the element is @c Mstring, and the value is a string that
2047     represents a font file or a directory.
2048
2049     The macro M17N_INIT () sets up this variable to contain the
2050     sub-directory "fonts" of the m17n database and the environment
2051     variable "M17NDIR".  The first call of mframe () creates the
2052     internal list of the actually available fonts from this variable.
2053     Thus, an application program, if necessary, must modify the
2054     variable before calling mframe ().  If it is going to add a new
2055     element, value must be a string that can be safely freed.
2056
2057     If the m17n library is not configured to use the FreeType library,
2058     this variable is not used.  */
2059 /***ja
2060     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
2061
2062     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î 
2063     plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring 
2064     ¤Ç¤¢¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
2065
2066     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ¿ô 
2067     "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
2068     mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£
2069     ¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢mframe () 
2070     ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2071     ¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2072
2073     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
2074
2075 MPlist *mfont_freetype_path;
2076
2077 /*=*/
2078
2079 /***en
2080     @brief Create a new font.
2081
2082     The mfont () function creates a new font object that has no
2083     property.
2084
2085     @return
2086     This function returns a pointer to the created font object.  */
2087 /***ja
2088     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
2089
2090     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
2091
2092     @return
2093     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
2094
2095 MFont *
2096 mfont ()
2097 {
2098   MFont *font;
2099
2100   MSTRUCT_CALLOC (font, MERROR_FONT);
2101   return font;
2102 }
2103
2104 /*=*/
2105
2106 /***en
2107     @brief Create a font by parsing a fontname.
2108
2109     The mfont_parse_name () function creates a new font object.  The
2110     properties are extracted fontname $NAME.
2111
2112     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
2113     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
2114     #Mfontconfig, $NAME is parsed as Fontconfig's textual
2115     representation of font.  If $FORMAT is #Mnil, $NAME is at first
2116     parsed as XLFD, and it it fails, parsed as Fontconfig's
2117     representation.
2118
2119     @return
2120     If the operation was successful, this function returns a pointer
2121     to the created font.  Otherwise it returns @c NULL.  */
2122
2123 /***ja
2124     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2125
2126     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ 
2127     $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
2128
2129     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
2130     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
2131     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig 
2132     ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD 
2133     ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
2134
2135     @return
2136     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () 
2137     ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
2138
2139 MFont *
2140 mfont_parse_name (const char *name, MSymbol format)
2141 {
2142   MFont template, *font;
2143   
2144   MFONT_INIT (&template);
2145   if (mfont__parse_name_into_font (name, format, &template) < 0)
2146     MERROR (MERROR_FONT, NULL);
2147   MSTRUCT_CALLOC (font, MERROR_FONT);
2148   *font = template;
2149   return font;
2150 }
2151
2152 /*=*/
2153
2154 /***en
2155     @brief Create a fontname from a font.
2156
2157     The mfont_unparse_name () function creates a fontname string
2158     from font $FONT according to $FORMAT.
2159
2160     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
2161     is in XLFD (X Logical Font Description) format.  If it is
2162     #Mfontconfig, the fontname is in the style of Fontconfig's text
2163     representation.
2164
2165     @return
2166     This function returns a newly allocated fontname string, which is
2167     not freed unless the user explicitly does so by free ().  */
2168
2169 /***ja
2170     @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
2171
2172     ´Ø¿ô mfont_unparse_name () ¤Ï ¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È $FONT 
2173     ¤ò¸µ¤Ë$FORMAT ¤Ë½¾¤Ã¤Æºî¤ë¡£
2174
2175     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤¢¤ë¡£
2176     #Mx ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£
2177     #Mfontconfig ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
2178
2179     @return 
2180     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶¤¬
2181     free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
2182
2183 char *
2184 mfont_unparse_name (MFont *font, MSymbol format)
2185 {
2186   char *name;
2187
2188   if (format == Mx)
2189     name = xlfd_unparse_name (font);
2190 #ifdef HAVE_FONTCONFIG
2191   else if (format == Mfontconfig)
2192     name = mfont__ft_unparse_name (font);
2193
2194 #endif /* HAVE_FONTCONFIG */
2195   else
2196     MERROR (MERROR_FONT, NULL);
2197   return name;
2198 }
2199
2200 /*=*/
2201
2202 /***en
2203     @brief Make a copy of a font.
2204
2205     The mfont_copy () function returns a new copy of font $FONT.  */
2206 /***ja
2207     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
2208
2209     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
2210
2211 MFont *
2212 mfont_copy (MFont *font)
2213 {
2214   MFont *copy;
2215
2216   MSTRUCT_MALLOC (copy, MERROR_FONT);
2217   *copy = *font;
2218   return copy;
2219 }
2220
2221 /*=*/
2222
2223 /***en
2224     @brief Get a property value of a font.
2225
2226     The mfont_get_prop () function gets the value of $KEY property of
2227     font $FONT.  $KEY must be one of the following symbols:
2228
2229         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c Madstyle,
2230         @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
2231
2232     If $FONT is a return value of mfont_find (), $KEY can also be one
2233     of the following symbols:
2234
2235         #Mfont_ascent, #Mfont_descent, #Mmax_advance.
2236
2237     @return If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2238     @c Madstyle, @c Mregistry, or @c Mspacing, this function returns
2239     the corresponding value as a symbol.  If the font does not have
2240     $KEY property, it returns @c Mnil.  If $KEY is @c Msize, @c
2241     Mresolution, #Mfont_ascent, Mfont_descent, or #Mmax_advance, this
2242     function returns the corresponding value as an integer.  If the
2243     font does not have $KEY property, it returns 0.  If $KEY is
2244     something else, it returns @c NULL and assigns an error code to
2245     the external variable #merror_code.  */
2246  
2247 /***ja
2248     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
2249
2250     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬
2251     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
2252     ¤Ð¤Ê¤é¤Ê¤¤¡£
2253
2254         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2255         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
2256
2257     @return $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
2258     Madstyle, @c Mregistry, @c Mspacing ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃÍ
2259     ¤ò¥·¥ó¥Ü¥ë¤È¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï
2260     @c Mnil ¤òÊÖ¤¹¡£$KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢
2261     ÁêÅö¤¹¤ëÃͤò¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤
2262     ¾ì¹ç¤Ë¤Ï 0 ¤òÊÖ¤¹¡£$KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢
2263     ³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
2264
2265 void *
2266 mfont_get_prop (MFont *font, MSymbol key)
2267 {
2268   MRealizedFont *rfont = NULL;
2269
2270   if (font->type == MFONT_TYPE_REALIZED)
2271     rfont = (MRealizedFont *) font;
2272
2273   if (key == Mfoundry)
2274     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
2275   if (key == Mfamily)
2276     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
2277   if (key == Mweight)
2278     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
2279   if (key == Mstyle)
2280     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
2281   if (key == Mstretch)
2282     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
2283   if (key == Madstyle)
2284     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
2285   if (key == Mregistry)
2286     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
2287   if (key == Msize)
2288     {
2289       int size = font->size;
2290       return (void *) size;
2291     }
2292   if (key == Mresolution)
2293     {
2294       int resy = font->property[MFONT_RESY];
2295       return (void *) resy;
2296     }
2297   if (key == Mfontfile)
2298     return (void *) font->file;
2299   if (key == Mspacing)
2300     return (font->spacing == MFONT_SPACING_UNDECIDED ? Mnil
2301             : msymbol (font->spacing == MFONT_SPACING_PROPORTIONAL ? "p"
2302                        : font->spacing == MFONT_SPACING_MONO ? "m" : "c"));
2303   if (rfont)
2304     {
2305       if (key == Mfont_ascent)
2306         return (void *) rfont->ascent;
2307       if (key == Mfont_descent)
2308         return (void *) rfont->descent;
2309       if (key == Mmax_advance)
2310         return (void *) rfont->max_advance;
2311     }
2312   MERROR (MERROR_FONT, NULL);
2313 }
2314
2315
2316 /*=*/
2317 /***en
2318     @brief Put a property value to a font.
2319
2320     The mfont_put_prop () function puts a font property whose key is
2321     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
2322     following symbols:
2323
2324         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2325         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
2326
2327     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
2328     Otherwise, $VAL must be a symbol.  */
2329  /***ja
2330     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
2331
2332     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY 
2333     ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
2334
2335         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2336         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
2337
2338     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL 
2339     ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
2340
2341 int
2342 mfont_put_prop (MFont *font, MSymbol key, void *val)
2343 {
2344   if (key == Mfoundry)
2345     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
2346   else if (key == Mfamily)
2347     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
2348   else if (key == Mweight)
2349     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
2350   else if (key == Mstyle)
2351     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
2352   else if (key == Mstretch)
2353     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
2354   else if (key == Madstyle)
2355     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
2356   else if (key == Mregistry)
2357     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
2358   else if (key == Msize)
2359     {
2360       int size = (int) val;
2361       font->size = size;
2362     }
2363   else if (key == Mresolution)
2364     {
2365       unsigned resy = (unsigned) val;
2366       font->property[MFONT_RESY] = resy;
2367     }
2368   else if (key == Mfontfile)
2369     {
2370       font->file = (MSymbol) val;
2371     }
2372   else
2373     MERROR (MERROR_FONT, -1);
2374   return 0;
2375 }
2376
2377 /*=*/
2378
2379 /***en
2380     @brief Return the font selection priority.
2381
2382     The mfont_selection_priority () function returns a newly created
2383     array of six symbols.  The elements are the following
2384     keys of font properties ordered by priority.
2385
2386         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2387         @c Madstyle, @c Msize.
2388
2389    The m17n library selects the best matching font according to the
2390    order of this array.  A font that has a different value for a
2391    property of lower priority is preferred to a font that has a
2392    different value for a property of higher priority.  */
2393 /***ja
2394     @brief ¥Õ¥©¥ó¥ÈÁªÂò¤ÎÍ¥ÀèÅÙ¤òÊÖ¤¹.
2395
2396     ´Ø¿ô mfont_selection_priority () ¤Ï 6 ¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã¤ÆÊÖ¤¹¡£
2397     ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤Ëʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
2398
2399         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2400         @c Madstyle, @c Msize.
2401
2402    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
2403    ÌÜŪ¤Î¥Õ¥©¥ó¥È¤È¡¢¤½¤ì¤¾¤ì°ã¤¦¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¤¬¤¢¤Ã¤¿¾ì¹ç¡¢Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¡ÊÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Æ¤¤¤ë¥Õ¥©¥ó¥È¡Ë¤¬ÁªÂò¤µ¤ì¤ë¡£
2404
2405    */
2406
2407 MSymbol *
2408 mfont_selection_priority ()
2409 {
2410   MSymbol *keys;
2411   int i;
2412
2413   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
2414   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
2415     {
2416       enum MFontProperty prop = font_score_priority[i];
2417
2418       if (prop == MFONT_SIZE)
2419         keys[i] = Msize;
2420       else if (prop == MFONT_ADSTYLE)
2421         keys[i] = Madstyle;
2422       else if (prop == MFONT_FAMILY)
2423         keys[i] = Mfamily;
2424       else if (prop == MFONT_WEIGHT)
2425         keys[i] = Mweight;
2426       else if (prop == MFONT_STYLE)
2427         keys[i] = Mstyle;
2428       else if (prop == MFONT_STRETCH)
2429         keys[i] = Mstretch;
2430       else
2431         keys[i] = Mfoundry;
2432     }
2433   return keys;
2434 }
2435
2436 /*=*/
2437
2438 /***en
2439     @brief Set the font selection priority.
2440
2441     The mfont_set_selection_priority () function sets font selection
2442     priority according to $KEYS, which is an array of six symbols.
2443     Each element must be one of the below.  No two elements must be
2444     the same.
2445
2446         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2447         @c Madstyle, @c Msize.
2448
2449     See the documentation of the function mfont_selection_priority ()
2450     for details.  */
2451 /***ja
2452     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
2453
2454     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
2455     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£ÇÛÎó¤Ï°Ê²¼¤Î³ÆÍ×ÁǤòŬÀÚ
2456     ¤Ê½çÈÖ¤Çʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
2457
2458         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2459         @c Madstyle, @c Msize.
2460
2461     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
2462      */
2463
2464 int
2465 mfont_set_selection_priority (MSymbol *keys)
2466 {
2467   int priority[FONT_SCORE_PRIORITY_SIZE];
2468   int i, j, shift;
2469
2470   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
2471     {
2472       enum MFontProperty prop;
2473
2474       if (*keys == Msize)
2475         prop = MFONT_SIZE;
2476       else if (*keys == Madstyle)
2477         prop = MFONT_ADSTYLE;
2478       else if (*keys == Mfamily)
2479         prop = MFONT_FAMILY;
2480       else if (*keys == Mweight)
2481         prop = MFONT_WEIGHT;
2482       else if (*keys == Mstyle)
2483         prop = MFONT_STYLE;
2484       else if (*keys == Mstretch)
2485         prop = MFONT_STRETCH;
2486       else if (*keys == Mfoundry)
2487         prop = MFONT_FOUNDRY;
2488       else
2489         /* Invalid element.  */
2490         return -1;
2491       for (j = 0; j < i; j++)
2492         if (priority[j] == prop)
2493           /* Duplicated element.  */
2494           return -1;
2495       priority[i] = prop;
2496     }
2497   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
2498     font_score_priority[i] = priority[i];
2499   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
2500      of a score is a flag for a scalable font (see the documentation
2501      of font_score).  */
2502   i = FONT_SCORE_PRIORITY_SIZE - 1;
2503   for (shift = 1; i >= 0; i--)
2504     {
2505       font_score_shift_bits[font_score_priority[i]] = shift;
2506       if (font_score_priority[i] == MFONT_SIZE)
2507         shift += 16;
2508       else if (font_score_priority[i] <= MFONT_FAMILY)
2509         shift++;
2510       else
2511         shift += 2;
2512     }
2513   return 0;
2514 }
2515
2516 /*=*/
2517
2518 /***en
2519     @brief Find a font.
2520
2521     The mfont_find () function returns a pointer to the available font
2522     that matches best the specification $SPEC on frame $FRAME.
2523
2524     $SCORE, if not NULL, must point to a place to store the score
2525     value that indicates how well the found font matches to $SPEC.  The
2526     smaller score means a better match.  */
2527 /***ja
2528     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
2529
2530     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC 
2531     ¤Ë¤â¤Ã¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
2532
2533     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC 
2534     ¤Ë¤É¤ì¤Û¤É¹ç¤Ã¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
2535     ¥¹¥³¥¢¤¬¾®¤µ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
2536     */
2537
2538 MFont *
2539 mfont_find (MFrame *frame, MFont *spec, int *score, int max_size)
2540 {
2541   MFont spec_copy;
2542   MFont *best;
2543   MFontList *list;
2544   MRealizedFont *rfont;
2545   MFont adjusted;
2546
2547   if (spec->size < 0)
2548     {
2549       double pt = - spec->size;
2550
2551       adjusted = *spec;
2552       adjusted.size = pt * frame->dpi / 72.27 + 0.5;
2553       spec = &adjusted;
2554     }
2555   MFONT_INIT (&spec_copy);
2556   spec_copy.property[MFONT_FAMILY] = spec->property[MFONT_FAMILY];
2557   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
2558   spec_copy.capability = spec->capability;
2559   spec_copy.file = spec->file;
2560
2561   list = mfont__list (frame, &spec_copy, spec, max_size);
2562   if (! list)
2563     return NULL;
2564
2565   best = list->fonts[0].font;
2566   if (score)
2567     *score = list->fonts[0].score;
2568   free (list->fonts);
2569   free (list);
2570   spec_copy = *best;
2571   mfont__merge (&spec_copy, spec, 0);
2572   rfont = mfont__open (frame, best, spec);
2573   if (! rfont)
2574     return NULL;
2575   return (MFont *) rfont;
2576 }
2577
2578 /*=*/
2579 /***en
2580     @brief Set encoding of a font.
2581
2582     The mfont_set_encoding () function sets the encoding information
2583     of font $FONT.
2584
2585     $ENCODING_NAME is a symbol representing a charset that has the
2586     same encoding as the font.
2587
2588     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
2589     has the same repertory as the font.  If it is @c Mnil, whether a
2590     specific character is supported by the font is asked to each font
2591     driver.
2592
2593     @return
2594     If the operation was successful, this function returns 0.
2595     Otherwise it returns -1 and assigns an error code to the external
2596     variable #merror_code.  */
2597 /***ja
2598     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
2599
2600     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó¤òÀßÄꤹ¤ë¡£
2601
2602     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2603
2604     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2605     @c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ»ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢³Æ¡¹¤Î¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ËÌ䤤¹ç¤ï¤»¤ë¡£
2606
2607     @return
2608     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô
2609     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
2610
2611
2612 int
2613 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
2614 {
2615   MCharset *encoding_charset = MCHARSET (encoding_name);
2616   MCharset *repertory_charset;
2617   MSymbol registry;
2618   MFontEncoding *encoding;
2619   MPlist *plist;
2620
2621   if (! encoding_charset)
2622     MERROR (MERROR_FONT, -1);
2623   if (repertory_name != Mnil)
2624     {
2625       repertory_charset = MCHARSET (repertory_name);
2626       if (! repertory_charset)
2627         MERROR (MERROR_FONT, -1);
2628     }
2629   else
2630     repertory_charset = NULL;
2631
2632   MSTRUCT_CALLOC (encoding, MERROR_FONT);
2633   encoding->spec = *font;
2634   encoding->encoding_name = encoding_name;
2635   encoding->encoding_charset = encoding_charset;
2636   encoding->repertory_name = repertory_name;
2637   encoding->repertory_charset = repertory_charset;
2638   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
2639   if (registry == Mnil)
2640     registry = Mt;
2641   if (! font_encoding_list)
2642     load_font_encoding_table ();
2643   mplist_push (font_encoding_list, registry, encoding);
2644   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
2645     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
2646                   sizeof (MFont)))
2647       {
2648         mplist_pop (plist);
2649         break;
2650       }
2651   return 0;
2652 }
2653
2654 /*=*/
2655
2656 /***en
2657     @brief Create a fontname from a font.
2658
2659     This function is obsolete.   Use mfont_unparse_name instead. */
2660 /***ja
2661     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2662
2663     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2664
2665 char *
2666 mfont_name (MFont *font)
2667 {
2668   return mfont_unparse_name (font, Mx);
2669 }
2670
2671 /*=*/
2672
2673 /***en
2674     @brief Create a new font from fontname.
2675
2676     This function is obsolete.  Use mfont_parse_name () instead.  */
2677
2678 /***ja
2679     @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
2680
2681     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2682
2683 MFont *
2684 mfont_from_name (const char *name)
2685 {
2686   return mfont_parse_name (name, Mx);
2687 }
2688
2689 /*=*/
2690
2691 /***en
2692     @brief Get resize information of a font.
2693
2694     The mfont_resize_ratio () function lookups the m17n database
2695     \<font, reisize\> and returns a resizing ratio (in percentage) of
2696     FONT.  For instance, if the return value is 150, that means that
2697     the m17n library uses an 1.5 time bigger font than a specified
2698     size.  */
2699
2700 /***ja
2701     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
2702
2703     ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> 
2704     ¤ò¸¡º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë
2705     ¤òÊÖ¤¹¡£¤¿¤È¤¨¤ÐÊÖ¤¹Ãͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 
2706     ÇܤΥե©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
2707
2708 int
2709 mfont_resize_ratio (MFont *font)
2710 {
2711   MFont request = *font;
2712
2713   mfont__resize (font, &request);
2714   return (font->size * 100 / request.size);
2715 }
2716
2717 /*=*/
2718
2719 /***en
2720     @brief Get a list of fonts.
2721
2722     The mfont_list () functions returns a list of fonts available on
2723     frame $FRAME.  $FONT, if not NULL, limits fonts to ones
2724     that match with $FONT.  $LANGUAGE, if not @c Mnil, limits fonts to
2725     ones that support $LANGUAGE.  $MAXNUM, if greater than 0, limits
2726     the number of fonts.
2727
2728     @return
2729     This function returns a plist whose keys are family names and
2730     values are pointers to the object MFont.  The plist must be freed
2731     by m17n_object_unref ().  If no font is found, it returns
2732     NULL.  */
2733
2734 /***ja
2735     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
2736
2737     ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2738     $FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2739     $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2740     $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
2741
2742     @return 
2743     ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê
2744     plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () 
2745     ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£  */
2746
2747 MPlist *
2748 mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
2749 {
2750   MPlist *plist, *pl;
2751   MFontList *font_list;
2752   int i;
2753   MFont spec = *font;
2754   
2755   if (spec.size < 0)
2756     {
2757       double pt = - spec.size;
2758
2759       spec.size = pt * frame->dpi / 72.27 + 0.5;
2760     }
2761
2762   if (language != Mnil)
2763     {
2764       /* ":lang=XXX" */
2765       char *buf = alloca (MSYMBOL_NAMELEN (language) + 7);
2766
2767       sprintf (buf, ":lang=%s", MSYMBOL_NAME (language));
2768       spec.capability = msymbol (buf);
2769     }
2770
2771   font_list = mfont__list (frame, &spec, &spec, 0);
2772   if (! font_list)
2773     return NULL;
2774   if (font_list->nfonts == 0)
2775     {
2776       free (font_list);
2777       return NULL;
2778     }
2779
2780   plist = pl = mplist ();
2781   for (i = 0; i < font_list->nfonts; i++)
2782     {
2783       MSymbol family = FONT_PROPERTY (font_list->fonts[i].font, MFONT_FAMILY);
2784
2785       if (family != Mnil)
2786         pl = mplist_add (pl, family, font_list->fonts[i].font);
2787     }
2788   free (font_list);
2789   return plist;
2790 }
2791
2792
2793 /*=*/
2794
2795 /***en
2796     @brief Check the usability of a font.
2797
2798     The function mfont_check () checkes if $FONT can be used for
2799     $SCRIPT and RLANGUAGE in $FONTSET on $FRAME.
2800
2801     @return If the font is usable, return 1.  Otherwise return 0.
2802  */
2803
2804 int
2805 mfont_check (MFrame *frame, MFontset *fontset, MFont *font,
2806              MSymbol script, MSymbol language)
2807 {
2808   MFont spec;
2809   MPlist *plist, *pl;
2810   int result = 0;
2811   int orig_size;
2812
2813   if (! fontset)
2814     fontset = frame->face->property[MFACE_FONTSET];
2815
2816   plist = mfontset_lookup (fontset, script, Mt, Mnil);
2817   if (script != Mnil)
2818     {
2819       if (language == Mnil)
2820         {
2821           if (! mplist_find_by_key (plist, Mt))
2822             /* No fallback fonts.  */
2823             language = MPLIST_KEY (plist);
2824         }
2825       else if (! mplist_find_by_key (plist, language))
2826         {
2827           /* Try fallback fonts. */
2828           if (mplist_find_by_key (plist, Mt))
2829             language = Mnil;
2830           else
2831             /* No fallback fonts.  */
2832             language = MPLIST_KEY (plist);
2833         }
2834
2835       M17N_OBJECT_UNREF (plist);
2836       plist = mfontset_lookup (fontset, script, language, Mnil);
2837     }
2838   orig_size = font->size;
2839   if (orig_size < 0)
2840     {
2841       double pt = - orig_size;
2842
2843       font->size = pt * frame->dpi / 72.27 + 0.5;
2844     }
2845   MPLIST_DO (pl, plist)
2846     {
2847       spec = *(MFont *) MPLIST_VAL (pl);          
2848       if (mfont__merge (&spec, font, 1) >= 0
2849           && mfont__select (frame, &spec, 0))
2850         {
2851           result = 1;
2852           break;
2853         }
2854     }
2855   font->size = orig_size;
2856   M17N_OBJECT_UNREF (plist);
2857   return result;
2858 }
2859
2860 /*** @} */
2861
2862 /*** @addtogroup m17nDebug */
2863 /*=*/
2864 /*** @{ */
2865
2866 /***en
2867     @brief Dump a font.
2868
2869     The mdebug_dump_font () function prints font $FONT in a human readable
2870     way to the stderr.
2871
2872     @return
2873     This function returns $FONT.  */
2874 /***ja
2875     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2876
2877     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr 
2878     ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£
2879
2880     @return
2881     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2882
2883 MFont *
2884 mdebug_dump_font (MFont *font)
2885 {
2886   char *name;
2887   
2888   name = mfont_unparse_name (font, Mx);
2889   if (name)
2890     {
2891       fprintf (stderr, "%s", name);
2892       free (name);
2893     }
2894   return font;
2895 }
2896
2897 /*** @} */
2898
2899 /*
2900   Local Variables:
2901   coding: euc-japan
2902   End:
2903 */