(OTF_tag): Delete it.
[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 #ifdef HAVE_OTF
653 static MPlist *otf_script_list;
654
655 static int
656 load_otf_script_list ()
657 {
658   MDatabase *mdb;
659   MPlist *plist, *pl;
660
661   otf_script_list = mplist ();
662   mdb = mdatabase_find (msymbol ("standard"), Mscript, msymbol ("otf"), Mnil);
663   if (! mdb
664       || ! (plist = mdatabase_load (mdb)))
665     MERROR (MERROR_FONT, -1);
666   MPLIST_DO (pl, plist)
667     {
668       MPlist *p;
669       MSymbol script, otf_script;
670       OTF_Tag tag;
671
672       if (! MPLIST_PLIST_P (pl))
673         continue;
674       p = MPLIST_PLIST (pl);
675       if (! MPLIST_SYMBOL_P (p))
676         continue;
677       script = MPLIST_SYMBOL (p);
678       p = MPLIST_NEXT (p);
679       if (! MPLIST_SYMBOL_P (p))
680         continue;
681       otf_script = MPLIST_SYMBOL (p);
682       tag = OTF_tag (MSYMBOL_NAME (otf_script));
683       mplist_push (otf_script_list, script, (void *) tag);
684     }
685   M17N_OBJECT_UNREF (plist);
686   return 0;
687 }
688
689 static MSymbol
690 find_script_from_otf_tag (OTF_Tag tag)
691 {
692   MPlist *plist;
693
694   if (! otf_script_list)
695     load_otf_script_list ();
696   plist = mplist_find_by_value (otf_script_list, (void *) tag);
697   return (plist ? MPLIST_KEY (plist) : Mnil);
698 }
699 #endif  /* HAVE_OTF */
700
701 /* XLFD parser/generator */
702
703 /** Indices to each field of split font name.  */
704
705 enum xlfd_field_idx
706   {
707     XLFD_FOUNDRY,
708     XLFD_FAMILY,
709     XLFD_WEIGHT,
710     XLFD_SLANT,
711     XLFD_SWIDTH,
712     XLFD_ADSTYLE,
713     XLFD_PIXEL,
714     XLFD_POINT,
715     XLFD_RESX,
716     XLFD_RESY,
717     XLFD_SPACING,
718     XLFD_AVGWIDTH,
719     XLFD_REGISTRY,              /* This contains ENCODING.  */
720     /* anchor */
721     XLFD_FIELD_MAX
722   };
723
724 static int
725 xlfd_parse_name (const char *name, MFont *font)
726 {
727   char *field[XLFD_FIELD_MAX];
728   unsigned short resy, avgwidth;
729   unsigned size;
730   char copy[513];
731   int i;
732   char *p;
733
734   if (name[0] != '-')
735     return -1;
736
737   field[0] = copy;
738   for (i = 1, p = copy, name++; *name; p++, name++)
739     {
740       if (p - copy > 512)
741         return -1;
742       if (*name == '-'
743           && i < XLFD_FIELD_MAX)
744         {
745           *p = '\0';
746           if (field[i - 1][0] == '*')
747             field[i - 1] = NULL;
748           field[i++] = p + 1;
749         }
750       else
751         *p = tolower (*name);
752     }
753   *p = '\0';
754   if (field[i - 1][0] == '*')
755     field[i - 1] = NULL;
756   while (i < XLFD_FIELD_MAX)
757     field[i++] = NULL;
758
759   resy = field[XLFD_RESY] ? atoi (field[XLFD_RESY]) : 0;
760   avgwidth = ((field[XLFD_AVGWIDTH] && isdigit (field[XLFD_AVGWIDTH][0]))
761               ? atoi (field[XLFD_AVGWIDTH]) : 1);
762   if (! avgwidth)
763     size = 0;
764   else if (! field[XLFD_PIXEL])
765     size = field[XLFD_POINT] ? atoi (field[XLFD_POINT]) * resy / 72 : 0;
766   else if (field[XLFD_PIXEL][0] == '[')
767     {
768       /* The pixel size field specifies a transformation matrix of the
769          form "[A B C D]".  The XLFD spec says that the scalar value N
770          for the pixel size is equivalent to D.  */
771       char *p0 = field[XLFD_PIXEL] + 1, *p1;
772       double d;
773
774       for (i = 0; i < 4; i++, p0 = p1)
775         d = strtod (p0, &p1);
776       size = d * 10;
777     }
778   else
779     size = atoi (field[XLFD_PIXEL]) * 10;
780
781   if (field[XLFD_FOUNDRY])
782     mfont__set_property (font, MFONT_FOUNDRY, msymbol (field[XLFD_FOUNDRY]));
783   if (field[XLFD_FAMILY])
784     mfont__set_property (font, MFONT_FAMILY, msymbol (field[XLFD_FAMILY]));
785   if (field[XLFD_WEIGHT])
786     mfont__set_property (font, MFONT_WEIGHT, msymbol (field[XLFD_WEIGHT]));
787   if (field[XLFD_SLANT])
788     mfont__set_property (font, MFONT_STYLE, msymbol (field[XLFD_SLANT]));
789   if (field[XLFD_SWIDTH])
790     mfont__set_property (font, MFONT_STRETCH, msymbol (field[XLFD_SWIDTH]));
791   if (field[XLFD_ADSTYLE])
792     mfont__set_property (font, MFONT_ADSTYLE, msymbol (field[XLFD_ADSTYLE]));
793   font->property[MFONT_RESY] = resy;
794   font->size = size;
795   if (field[XLFD_SPACING])
796     font->spacing
797       = ((field[XLFD_SPACING][0] == 'p' || field[XLFD_SPACING][0] == 'P')
798          ? MFONT_SPACING_PROPORTIONAL
799          : (field[XLFD_SPACING][0] == 'm' || field[XLFD_SPACING][0] == 'M')
800          ? MFONT_SPACING_MONO : MFONT_SPACING_CHARCELL);
801   if (field[XLFD_REGISTRY])
802     mfont__set_property (font, MFONT_REGISTRY, msymbol (field[XLFD_REGISTRY]));
803   font->type = MFONT_TYPE_SPEC;
804   font->source = MFONT_SOURCE_X;
805   return 0;
806 }
807
808 static char *
809 xlfd_unparse_name (MFont *font, int full_xlfd)
810 {
811   MSymbol prop[7];
812   char name[513];
813   char *str[7];
814   int len, i;
815   char spacing;
816   int size, resy;
817
818   prop[0] = (MSymbol) mfont_get_prop (font, Mfoundry);
819   prop[1] = (MSymbol) mfont_get_prop (font, Mfamily);
820   prop[2] = (MSymbol) mfont_get_prop (font, Mweight);
821   prop[3] = (MSymbol) mfont_get_prop (font, Mstyle);
822   prop[4] = (MSymbol) mfont_get_prop (font, Mstretch);
823   prop[5] = (MSymbol) mfont_get_prop (font, Madstyle);
824   prop[6] = (MSymbol) mfont_get_prop (font, Mregistry);
825   for (len = 0, i = 0; i < 7; i++)
826     {
827       if (prop[i] != Mnil)
828         {
829           str[i] = msymbol_name (prop[i]);
830           len += strlen (str[i]);
831         }
832       else
833         {
834           str[i] = "*";
835           len++;
836         }
837     }
838   spacing = (font->spacing == MFONT_SPACING_UNDECIDED ? '*'
839              : font->spacing == MFONT_SPACING_PROPORTIONAL ? 'p'
840              : font->spacing == MFONT_SPACING_MONO ? 'm'
841              : 'c');
842
843   if ((len
844        + 13                     /* 13 dashes */
845        + 2                      /* 2 asterisks */
846        + 30                     /* 3 integers (each 10 digits) */
847        + 1                      /* 1 spacing char */
848        + 1)                     /* '\0' terminal */
849       > 513)
850     return NULL;
851
852   resy = (int) mfont_get_prop (font, Mresolution);
853   size = font->size;
854   if (size >= 0)
855     {
856       if ((size % 10) < 5)
857         size /= 10;
858       else
859         size = size / 10 + 1;
860     }
861   else
862     size = - size;
863
864   if (full_xlfd)
865     {
866       if (font->size >= 0)
867         sprintf (name, "-%s-%s-%s-%s-%s-%s-%d-*-%d-%d-%c-*-%s",
868                  str[0], str[1], str[2], str[3], str[4], str[5],
869                  size, resy, resy, spacing, str[6]);
870       else
871         sprintf (name, "-%s-%s-%s-%s-%s-%s-*-%d-%d-%d-%c-*-%s",
872                  str[0], str[1], str[2], str[3], str[4], str[5],
873                  size, resy, resy, spacing, str[6]);
874     }
875   else
876     {
877       char *p = name;
878
879       p += sprintf (p, "-%s", str[0]);
880       for (i = 1; i < 6; i++)
881         if (p[-1] != '*' || str[i][0] != '*')
882           p += sprintf (p, "-%s", str[i]);
883       if (p[-1] != '*' || font->size > 0)
884         {
885           if (font->size > 0)
886             p += sprintf (p, "-%d-*", size);
887           else
888             p += sprintf (p, "-*");
889         }
890       if (str[6][0] != '*')
891         sprintf (p, "-%s", str[6]);
892     }
893
894   return strdup (name);
895 }
896
897 /* Compare FONT with REQUEST and return how much they differs.  */
898
899 static int
900 font_score (MFont *font, MFont *request)
901 {
902   int score = 0;
903   int i = FONT_SCORE_PRIORITY_SIZE;
904
905   while (--i >= 0)
906     {
907       enum MFontProperty prop = font_score_priority[i];
908       int val;
909
910       if (prop == MFONT_SIZE)
911         {
912           if (font->size && request->size)
913             {
914               val = font->size - request->size;
915               if (val)
916                 {
917                   if (val < 0)
918                     val = - val;
919                   if (val >= 0x10000)
920                     val = 0xFFFF;
921                   score |= (val << font_score_shift_bits[MFONT_SIZE]);
922                 }
923             }
924         }
925       else if (font->property[prop] && request->property[prop]
926                && font->property[prop] != request->property[prop])
927         {
928           if (prop <= MFONT_FAMILY)
929             val = 1;
930           else if (prop == MFONT_WEIGHT)
931             {
932               unsigned short v1 = font->property[prop];
933               unsigned short v2 = request->property[prop];
934
935               if (v1 == font_weight_regular || v1 == font_weight_normal)
936                 v1 = font_weight_medium;
937               if (v2 == font_weight_regular || v2 == font_weight_normal)
938                 v2 = font_weight_medium;
939               val = v1 > v2 ? v1 - v2 : v2 - v1;
940             }
941           else
942             {
943               val = font->property[prop] - request->property[prop];
944               if (val < 0)
945                 val = - val;
946               if (val > 3)
947                 val = 3;
948             }
949           score |= val << font_score_shift_bits[prop];
950         }
951     }
952   if (request->file != Mnil && request->file != font->file)
953     score |= 40000000;
954   return score;
955 }
956
957 \f
958 /* Internal API */
959
960 MSymbol Miso8859_1, Miso10646_1, Municode_bmp, Municode_full, Mapple_roman;
961
962 int
963 mfont__init ()
964 {
965   int i, shift;
966   MSymbol regular = msymbol ("regular");
967   MSymbol normal = msymbol ("normal");
968   MSymbol medium = msymbol ("medium");
969
970   M_font_capability = msymbol_as_managing_key ("  font-capability");
971   M_font_list = msymbol_as_managing_key ("  font-list");
972   M_font_list_len = msymbol ("  font-list-len");
973
974   Mfoundry = msymbol ("foundry");
975   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
976   Mfamily = msymbol ("family");
977   mfont__property_table[MFONT_FAMILY].property = Mfamily;
978   Mweight = msymbol ("weight");
979   mfont__property_table[MFONT_WEIGHT].property = Mweight;
980   Mstyle = msymbol ("style");
981   mfont__property_table[MFONT_STYLE].property = Mstyle;
982   Mstretch = msymbol ("stretch");
983   mfont__property_table[MFONT_STRETCH].property = Mstretch;
984   Madstyle = msymbol ("adstyle");
985   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
986   Mregistry = msymbol ("registry");
987   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
988
989   Mspacing = msymbol ("spacing");
990   Msize = msymbol ("size");
991   Mresolution = msymbol ("resolution");
992   Mmax_advance = msymbol ("max-advance");
993   Mfontfile = msymbol ("fontfile");
994
995   Mfontconfig = msymbol ("fontconfig");
996
997   Mx = msymbol ("x");
998   Mfreetype = msymbol ("freetype");
999   Mxft = msymbol ("xft");
1000
1001   Miso8859_1 = msymbol ("iso8859-1");
1002   Miso10646_1 = msymbol ("iso10646-1");
1003   Municode_bmp = msymbol ("unicode-bmp");
1004   Municode_full = msymbol ("unicode-full");
1005   Mapple_roman = msymbol ("apple-roman");
1006
1007   /* The first entry of each mfont__property_table must be Mnil so
1008      that actual properties get positive numeric numbers.  */
1009   for (i = 0; i <= MFONT_REGISTRY; i++)
1010     {
1011       MLIST_INIT1 (&mfont__property_table[i], names, 8);
1012       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
1013     }
1014
1015   /* Register predefined font property names.  */
1016   for (i = 0; i <= MFONT_REGISTRY; i++)
1017     {
1018       int j;
1019
1020       for (j = 0; j < font_common_names[i].num; j++)
1021         {
1022           MSymbol sym = msymbol (font_common_names[i].names[j]);
1023
1024           if (sym == Mnil)
1025             return -1;
1026           if (msymbol_put (sym, mfont__property_table[i].property,
1027                            (void *) (j + 1)) < 0)
1028             return -1;
1029           MLIST_APPEND1 (&mfont__property_table[i], names, sym,
1030                          MERROR_FONT);
1031           if (i == MFONT_WEIGHT)
1032             {
1033               if (sym == regular)
1034                 font_weight_regular = j + 1;
1035               else if (sym == normal)
1036                 font_weight_normal = j + 1;
1037               else if (sym == medium)
1038                 font_weight_medium = j + 1;
1039             }
1040         }
1041     }
1042
1043   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
1044      of a score is a flag for a scalable font (see the documentation
1045      of font_score).  */
1046   i = FONT_SCORE_PRIORITY_SIZE - 1;
1047   for (shift = 1; i >= 0; i--)
1048     {
1049       font_score_shift_bits[font_score_priority[i]] = shift;
1050       if (font_score_priority[i] == MFONT_SIZE)
1051         shift += 16;
1052       else if (font_score_priority[i] <= MFONT_FAMILY)
1053         shift++;
1054       else
1055         shift += 2;
1056     }
1057
1058   MFONT_INIT (&default_encoding.spec);
1059   default_encoding.encoding_name = Municode_full;
1060   default_encoding.encoding_charset = mcharset__unicode;
1061   default_encoding.repertory_name = Mnil;
1062   default_encoding.repertory_charset = NULL;
1063   {
1064     char *path, *buf;
1065     int bufsize;
1066     USE_SAFE_ALLOCA;
1067
1068     mfont_freetype_path = mplist ();
1069     bufsize = strlen (M17NDIR) + 7;
1070     SAFE_ALLOCA (buf, bufsize);
1071     sprintf (buf, "%s/fonts", M17NDIR);
1072     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
1073     path = getenv ("M17NDIR");
1074     if (path)
1075       {
1076         bufsize = strlen (path) + 7;
1077         SAFE_ALLOCA (buf, bufsize);
1078         sprintf (buf, "%s/fonts", path);
1079         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
1080       }
1081     SAFE_FREE (buf);
1082   }
1083
1084 #ifdef HAVE_FREETYPE
1085   if (mfont__ft_init () < 0)
1086     return -1;
1087 #endif /* HAVE_FREETYPE */
1088   if (mfont__flt_init () < 0)
1089     return -1;
1090
1091   return 0;
1092 }
1093
1094 void
1095 mfont__fini ()
1096 {
1097   MPlist *plist;
1098   int i;
1099
1100   mfont__flt_fini ();
1101 #ifdef HAVE_FREETYPE
1102   mfont__ft_fini ();
1103 #endif /* HAVE_FREETYPE */
1104
1105   MPLIST_DO (plist, mfont_freetype_path)
1106     free (MPLIST_VAL (plist));
1107   M17N_OBJECT_UNREF (mfont_freetype_path);
1108
1109   if (font_resize_list)
1110     {
1111       MPLIST_DO (plist, font_resize_list)
1112         free (MPLIST_VAL (plist));
1113       M17N_OBJECT_UNREF (font_resize_list);
1114       font_resize_list = NULL;
1115     }
1116   if (font_encoding_list)
1117     {
1118       MPLIST_DO (plist, font_encoding_list)
1119         free (MPLIST_VAL (plist));
1120       M17N_OBJECT_UNREF (font_encoding_list);
1121       font_encoding_list = NULL;
1122     }
1123 #ifdef HAVE_OTF
1124   if (otf_script_list)
1125     {
1126       M17N_OBJECT_UNREF (otf_script_list);
1127       otf_script_list = NULL;
1128     }
1129 #endif  /* HAVE_OTF */
1130
1131   for (i = 0; i <= MFONT_REGISTRY; i++)
1132     MLIST_FREE1 (&mfont__property_table[i], names);
1133 }
1134
1135
1136 MSymbol
1137 mfont__id (MFont *font)
1138 {
1139   char *buf, *p;
1140   int i;
1141   int file_len = (font->file == Mnil ? 0 : MSYMBOL_NAMELEN (font->file));
1142   int capability_len  = (font->capability == Mnil ? 0
1143                          : MSYMBOL_NAMELEN (font->capability));
1144   int total_len = MFONT_PROPERTY_MAX * 5 + 9 + file_len + capability_len;
1145   MSymbol id;
1146   USE_SAFE_ALLOCA;
1147
1148   SAFE_ALLOCA (buf, total_len);
1149   p = buf;
1150   if (font->property[0])
1151     p += sprintf (p, "%X", font->property[0]);
1152   for (i = 1; i < MFONT_PROPERTY_MAX; i++)
1153     {
1154       if (font->property[i])
1155         p += sprintf (p, "-%X", font->property[i]);
1156       else
1157         *p++ = '-';
1158     }
1159   if (font->size)
1160     p += sprintf (p, "-%X", font->size);
1161   if (font->spacing)
1162     p += sprintf (p, "-%X", font->spacing);
1163   if (capability_len > 0)
1164     {
1165       *p++ = '-';
1166       memcpy (p, MSYMBOL_NAME (font->capability), capability_len);
1167       p += capability_len;
1168     }
1169   if (file_len > 0)
1170     {
1171       *p++ = '-';
1172       memcpy (p, MSYMBOL_NAME (font->file), file_len);
1173       p += file_len;
1174     }      
1175   id = msymbol__with_len (buf, p - buf);
1176   SAFE_FREE (buf);
1177   return id;
1178 }
1179
1180 /** Return 1 iff FONT matches SPEC.  */
1181
1182 int
1183 mfont__match_p (MFont *font, MFont *spec, int prop)
1184 {
1185   if (spec->capability != font->capability
1186       && spec->capability != Mnil && font->capability != Mnil)
1187     return 0;
1188   if (spec->file != font->file
1189       && spec->file != Mnil && font->file != Mnil)
1190     return 0;
1191   for (; prop >= 0; prop--)
1192     if (spec->property[prop] && font->property[prop]
1193         && font->property[prop] != spec->property[prop])
1194       return 0;
1195   return 1;
1196 }
1197
1198 /* Merge SRC into DST.  If error_on_conflict is nonzero and a font
1199    property differs in SRC and DST, return -1.  */
1200
1201 int
1202 mfont__merge (MFont *dst, MFont *src, int error_on_conflict)
1203 {
1204   int i;
1205
1206   for (i = 0; i < MFONT_PROPERTY_MAX; i++)
1207     {
1208       if (! dst->property[i])
1209         dst->property[i] = src->property[i];
1210       else if (error_on_conflict
1211                && src->property[i]
1212                && dst->property[i] != src->property[i])
1213         return -1;
1214     }
1215   if (! dst->spacing)
1216     dst->spacing = src->spacing;
1217   else if (error_on_conflict
1218            && src->spacing
1219            && dst->spacing != src->spacing)
1220     return -1;
1221   if (! dst->size)
1222     dst->size = src->size;
1223   else if (error_on_conflict
1224            && src->size
1225            && dst->size != src->size)
1226     return -1;
1227   if (dst->capability == Mnil)
1228     dst->capability = src->capability;
1229   else if (error_on_conflict
1230            && src->capability
1231            && dst->capability != src->capability)
1232     return -1;
1233   if (dst->file == Mnil)
1234     dst->file = src->file;
1235   else if (error_on_conflict
1236            && src->file
1237            && dst->file != src->file)
1238     return -1;
1239   return 0;
1240 }
1241
1242 void
1243 mfont__set_spec_from_face (MFont *spec, MFace *face)
1244 {
1245   int i;
1246
1247   for (i = 0; i <= MFONT_ADSTYLE; i++)
1248     mfont__set_property (spec, i, face->property[i]);
1249   spec->property[MFONT_REGISTRY] = 0;
1250   spec->property[MFONT_RESY] = 0;
1251   spec->size = (int) (face->property[MFACE_SIZE]);
1252   spec->type = MFONT_TYPE_SPEC;
1253   spec->source = MFONT_SOURCE_UNDECIDED;
1254   spec->file = spec->capability = Mnil;
1255   spec->encoding = NULL;
1256 }
1257
1258
1259 extern MSymbol
1260 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
1261 {
1262   int i;
1263   MSymbol spec_list[MFONT_REGISTRY + 1];
1264   MSymbol registry;
1265   char *reg;
1266
1267   MFONT_INIT (spec);
1268   memset (spec_list, 0, sizeof spec_list);
1269   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
1270     {
1271       if (! MPLIST_SYMBOL_P (plist))
1272         MERROR (MERROR_FONT, Mnil);     
1273       spec_list[i] = MPLIST_SYMBOL (plist);
1274     }
1275   registry = spec_list[i - 1];
1276   if (i > 1 && registry != Mnil)
1277     {
1278       reg = MSYMBOL_NAME (registry);
1279       if (reg[0] == ':')
1280         {
1281           mfont__get_capability (registry);
1282           spec->capability = registry;
1283           registry = spec_list[i - 2];
1284           i--;
1285         }
1286     }
1287   mfont__set_property (spec, MFONT_REGISTRY, registry);
1288   for (i -= 2; i >= 0; i--)
1289     mfont__set_property (spec, i, spec_list[i]);
1290   spec->type = MFONT_TYPE_SPEC;
1291
1292   return registry;
1293 }
1294
1295
1296 MFont *
1297 mfont__select (MFrame *frame, MFont *font, int max_size)
1298 {
1299   MFontDriver *driver;
1300
1301   if (font->type == MFONT_TYPE_FAILURE)
1302     return NULL;
1303   if (font->type != MFONT_TYPE_SPEC)
1304     return font;
1305   if (font->source == MFONT_SOURCE_UNDECIDED)
1306     {
1307       if (font->file != Mnil || font->capability != Mnil)
1308         font->source = MFONT_SOURCE_FT;
1309       else if (font->property[MFONT_REGISTRY])
1310         {
1311           MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1312           char *reg = MSYMBOL_NAME (registry);
1313
1314           if (strncmp (reg, "unicode-", 8) == 0
1315               || strncmp (reg, "apple-roman", 11) == 0
1316               || (reg[0] >= '0' && reg[0] <= '9' && reg[1] == '-'))
1317             font->source = MFONT_SOURCE_FT;
1318         }
1319     }
1320   if (font->source != MFONT_SOURCE_FT)
1321     {
1322       driver = mplist_get (frame->font_driver_list, Mx);
1323       if (driver)
1324         return (driver->select) (frame, font, max_size);
1325     }
1326   driver = mplist_get (frame->font_driver_list, Mfreetype);
1327   if (! driver)
1328     return NULL;
1329   return (driver->select) (frame, font, max_size);
1330 }
1331
1332
1333 int
1334 mfont__available (MFrame *frame, MFont *font)
1335 {
1336   return -1;
1337 }
1338
1339 static int
1340 compare_font_score (const void *e1, const void *e2)
1341 {
1342   MFontScore *s1 = (MFontScore *) e1, *s2 = (MFontScore *) e2;
1343
1344   return (s1->font->for_full_width == s2->font->for_full_width
1345           ? s1->score > s2->score
1346           : s1->font->for_full_width);
1347 }
1348
1349 void
1350 mdebug_dump_font_list (MFontList *font_list)
1351 {
1352   int i;
1353
1354   for (i = 0; i < font_list->nfonts; i++)
1355     {
1356       fprintf (stderr, "%04X - ", font_list->fonts[i].score);
1357       mdebug_dump_font (font_list->fonts[i].font);
1358       fprintf (stderr, "\n");
1359     }
1360 }
1361
1362 void
1363 mfont__free_realized (MRealizedFont *rfont)
1364 {
1365   MRealizedFont *next;
1366
1367   for (; rfont; rfont = next)
1368     {
1369       next = rfont->next;
1370       M17N_OBJECT_UNREF (rfont->info);
1371       free (rfont);
1372       rfont = next;
1373     }
1374 }
1375
1376 MFontList *
1377 mfont__list (MFrame *frame, MFont *spec, MFont *request, int max_size)
1378 {
1379   MFontList *list;
1380   MSymbol id = mfont__id (spec);
1381   MPlist *pl, *p;
1382   int num, i;
1383
1384   pl = msymbol_get (id, M_font_list);
1385   if (pl)
1386     num = (int) msymbol_get (id, M_font_list_len);
1387   else
1388     {
1389       pl = mplist ();
1390       num = 0;
1391       MPLIST_DO (p, frame->font_driver_list)
1392         {
1393           if (spec->source == MFONT_SOURCE_X ? MPLIST_KEY (p) == Mx
1394               : spec->source == MFONT_SOURCE_FT ? MPLIST_KEY (p) == Mfreetype
1395               : 1)
1396             {
1397               MFontDriver *driver = MPLIST_VAL (p);
1398               num += (driver->list) (frame, pl, spec, 0);
1399             }
1400         }
1401       msymbol_put (id, M_font_list, pl);
1402       M17N_OBJECT_UNREF (pl);
1403       msymbol_put (id, M_font_list_len, (void *) num);
1404     }
1405   
1406   if (num == 0)
1407     return NULL;
1408
1409   MSTRUCT_MALLOC (list, MERROR_FONT);
1410   MTABLE_MALLOC (list->fonts, num, MERROR_FONT);
1411   for (i = 0; num > 0; num--, pl = MPLIST_NEXT (pl))
1412     {
1413       MFont *font = MPLIST_VAL (pl);
1414
1415       if (max_size == 0
1416           || font->size == 0
1417           || font->size < max_size)
1418         {
1419           list->fonts[i].font = font;
1420           list->fonts[i].score
1421             = spec == request ? 0 : font_score (font, request);
1422           i++;
1423         }
1424     }
1425   if (i == 0)
1426     {
1427       free (list->fonts);
1428       free (list);
1429       return NULL;
1430     }
1431   list->nfonts = i;
1432   if (spec != request)
1433     qsort (list->fonts, i, sizeof (MFontScore), compare_font_score);
1434   list->object = *spec;
1435   mfont__merge (&list->object, request, 0);
1436   list->object.type = MFONT_TYPE_OBJECT;
1437   return list;
1438 }
1439
1440 /** Open a font specified in FONT.  */
1441
1442 MRealizedFont *
1443 mfont__open (MFrame *frame, MFont *font, MFont *spec)
1444 {
1445   MFontDriver *driver;
1446   MRealizedFont *rfont;
1447
1448   if (font->source == MFONT_SOURCE_UNDECIDED)
1449     MFATAL (MERROR_FONT);
1450   if (font->type != MFONT_TYPE_OBJECT)
1451     MFATAL (MERROR_FONT);
1452   for (rfont = MPLIST_VAL (frame->realized_font_list); rfont;
1453        rfont = rfont->next)
1454     {
1455       driver = rfont->driver;
1456       if (rfont->font == font
1457           && mplist_find_by_value (frame->font_driver_list, driver))
1458         break;
1459     }
1460
1461   if (! rfont)
1462     {
1463       driver = mplist_get (frame->font_driver_list,
1464                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1465       if (! driver)
1466         MFATAL (MERROR_FONT);
1467     }
1468   return (driver->open) (frame, font, spec, rfont);
1469 }
1470
1471 void
1472 mfont__resize (MFont *spec, MFont *request)
1473 {
1474   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1475   MFontResize *resize;
1476   MPlist *plist;
1477
1478   if (! font_resize_list)
1479     load_font_resize_table ();
1480   if (! MPLIST_TAIL_P (font_resize_list))
1481     while (1)
1482       {
1483         plist = font_resize_list;
1484         while (registry ? (plist = mplist_find_by_key (plist, registry))
1485                : plist)
1486           {
1487             resize = (MFontResize *) MPLIST_VAL (plist);
1488             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1489               {
1490                 request->size = request->size * resize->resize / 100;
1491                 return;
1492               }
1493             plist = MPLIST_NEXT (plist);
1494           }
1495         if (registry == Mt)
1496           break;
1497         registry = Mt;
1498       }
1499 }
1500
1501
1502 int
1503 mfont__has_char (MFrame *frame, MFont *font, MFont *spec, int c)
1504 {
1505   MFontEncoding *encoding;
1506   unsigned code;
1507   MFontDriver *driver;
1508
1509   if (font->source == MFONT_SOURCE_UNDECIDED)
1510     MFATAL (MERROR_FONT);
1511   encoding = (font->encoding ? font->encoding : find_encoding (font));
1512   if (! encoding->encoding_charset)
1513     return 0;
1514   if (encoding->repertory_charset)
1515     {
1516       code = ENCODE_CHAR (encoding->repertory_charset, c);
1517       return (code != MCHAR_INVALID_CODE);
1518     }
1519   code = ENCODE_CHAR (encoding->encoding_charset, c);
1520   if (code == MCHAR_INVALID_CODE)
1521     return 0;
1522   if (font->type == MFONT_TYPE_REALIZED)
1523     driver = ((MRealizedFont *) font)->driver;
1524   else
1525     {
1526       driver = mplist_get (frame->font_driver_list,
1527                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1528       if (! driver)
1529         MFATAL (MERROR_FONT);
1530     }
1531   return (driver->has_char) (frame, font, spec, c, code);
1532 }
1533
1534 unsigned
1535 mfont__encode_char (MFrame *frame, MFont *font, MFont *spec, int c)
1536 {
1537   MFontEncoding *encoding;
1538   unsigned code;
1539   MFontDriver *driver;
1540
1541   if (font->source == MFONT_SOURCE_UNDECIDED)
1542     MFATAL (MERROR_FONT);
1543   encoding = (font->encoding ? font->encoding : find_encoding (font));
1544   if (! encoding->encoding_charset)
1545     return MCHAR_INVALID_CODE;
1546   if (font->source == MFONT_SOURCE_X && encoding->repertory_charset)
1547     return (ENCODE_CHAR (encoding->repertory_charset, c));
1548   code = ENCODE_CHAR (encoding->encoding_charset, c);
1549   if (code == MCHAR_INVALID_CODE)
1550     return MCHAR_INVALID_CODE;
1551   if (font->type == MFONT_TYPE_REALIZED)
1552     driver = ((MRealizedFont *) font)->driver;
1553   else
1554     {
1555       driver = mplist_get (frame->font_driver_list,
1556                            font->source == MFONT_SOURCE_X ? Mx : Mfreetype);
1557       if (! driver)
1558         MFATAL (MERROR_FONT);
1559     }
1560   return (driver->encode_char) (frame, font, spec, code);
1561 }
1562
1563 void
1564 mfont__get_metric (MGlyphString *gstring, int from, int to)
1565 {
1566   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1567   MRealizedFont *rfont = from_g->rface->rfont;
1568
1569   for (g = from_g; g != to_g; g++)
1570     if (g->rface->rfont != rfont)
1571       {
1572         int idx = GLYPH_INDEX (g);
1573
1574         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1575         from_g = g;
1576         rfont = g->rface->rfont;
1577         from = idx;
1578       }
1579   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1580 }
1581
1582
1583 /* KEY <= MFONT_REGISTRY */
1584
1585 void
1586 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1587 {
1588   int numeric;
1589
1590   if (val == Mnil)
1591     numeric = 0;
1592   else
1593     {
1594       numeric = FONT_PROPERTY_NUMERIC (val, key);
1595       if (! numeric)
1596         {
1597           numeric = mfont__property_table[key].used;
1598           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1599           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1600         }
1601     }
1602   font->property[key] = numeric;
1603 }
1604
1605 int
1606 mfont__parse_name_into_font (const char *name, MSymbol format, MFont *font)
1607 {
1608   int result = -1;
1609
1610   if (format == Mx || format == Mnil)
1611     result = xlfd_parse_name (name, font);
1612 #ifdef HAVE_FONTCONFIG
1613   if (format == Mfontconfig || (result < 0 && format == Mnil))
1614     result = mfont__ft_parse_name (name, font);
1615 #endif /* HAVE_FONTCONFIG */
1616   return result;
1617 }
1618
1619 MPlist *
1620 mfont__encoding_list (void)
1621 {
1622   if (! font_encoding_list)
1623     load_font_encoding_table ();
1624   return font_encoding_list;
1625 }
1626
1627 static void
1628 free_font_capability (void *object)
1629 {
1630   MFontCapability *cap = object;
1631   
1632   if (cap->lang)
1633     free (cap->lang);
1634 #ifdef HAVE_OTF
1635   if (cap->script)
1636     {
1637       int i;
1638       for (i = 0; i < MFONT_OTT_MAX; i++)
1639         {
1640           if (cap->features[i].str)
1641             free (cap->features[i].str);
1642           if (cap->features[i].tags)
1643             free (cap->features[i].tags);
1644         }
1645     }
1646 #endif /* HAVE_OTF */
1647   free (cap);
1648 }
1649
1650 MFontCapability *
1651 mfont__get_capability (MSymbol sym)
1652 {
1653   MFontCapability *cap = msymbol_get (sym, M_font_capability);
1654   char *str, *p, *endp;
1655
1656   if (cap)
1657     return cap;
1658   str = MSYMBOL_NAME (sym);
1659   if (str[0] != ':')
1660     return NULL;
1661   M17N_OBJECT (cap, free_font_capability, MERROR_FONT);
1662   msymbol_put (sym, M_font_capability, cap);
1663   M17N_OBJECT_UNREF (cap);
1664   endp = str + MSYMBOL_NAMELEN (sym);
1665   while (str < endp)
1666     {
1667       if (*str++ != ':')
1668         continue;
1669 #ifdef HAVE_OTF
1670       if (str[0] == 'o' && str[1] == 't' && str[2] == 'f' && str[3] == '=')
1671         {
1672           int i;
1673
1674           str += 4;
1675           for (i = 0, p = str; i < 4 && p < endp; i++, p++);
1676           if (i < 4)
1677             break;
1678           cap->script_tag = OTF_tag (str);
1679           cap->script = find_script_from_otf_tag (cap->script_tag);
1680           if (*p == '/')
1681             {
1682               for (i = 0, str = ++p; i < 4 && p < endp; i++, p++);
1683               if (i < 4)
1684                 {
1685                   cap->script = Mnil;
1686                   break;
1687                 }
1688               cap->langsys_tag = OTF_tag (str);
1689             }
1690           else
1691             cap->langsys_tag = 0;
1692
1693           for (i = 0; i < MFONT_OTT_MAX; i++)
1694             cap->features[i].nfeatures = -1;
1695
1696           while (*p == '=' || *p == '+')
1697             {
1698               int idx = *p == '=' ? MFONT_OTT_GSUB : MFONT_OTT_GPOS;
1699
1700               str = ++p;
1701               while (p < endp && *p != '+') p++;
1702               if (str < p)
1703                 {
1704                   int n;
1705                   /* We never have more than (p - str) tags.  */
1706                   OTF_Tag *tags = alloca (sizeof (OTF_Tag) * (p - str));
1707                   char *p0;
1708
1709                   cap->features[idx].str = malloc (p - str + 1);
1710                   for (i = n = 0, p0 = str; str + i < p; i++)
1711                     {
1712                       cap->features[idx].str[i] = str[i];
1713                       if (str[i] == ',' || str + i + 1 == p)
1714                         {
1715                           if (*p0 == '*')
1716                             tags[n] = 0;
1717                           else if (*p0 == '~')
1718                             tags[n] = OTF_tag (p0 + 1) | 0x80000000;
1719                           else
1720                             tags[n] = OTF_tag (p0);
1721                           n++;
1722                           p0 = str + i + 1;
1723                         }
1724                     }
1725                   cap->features[idx].str[i] = '\0';
1726                   cap->features[idx].nfeatures = n;
1727                   if (n > 0)
1728                     {
1729                       int size = sizeof (OTF_Tag) * n;
1730
1731                       cap->features[idx].tags = malloc (size);
1732                       memcpy (cap->features[idx].tags, tags, size);
1733                     }
1734                 }
1735               else
1736                 {
1737                   cap->features[idx].str = NULL;
1738                   cap->features[idx].nfeatures = 0;
1739                 }
1740             }
1741
1742           for (i = 0; i < MFONT_OTT_MAX; i++)
1743             if (cap->features[i].nfeatures < 0)
1744               {
1745                 cap->features[i].str = strdup ("*");
1746                 cap->features[i].nfeatures = 1;
1747                 cap->features[i].tags = malloc (sizeof (OTF_Tag));
1748                 cap->features[i].tags[0] = 0;
1749               }
1750           str = p;
1751           continue;
1752         }
1753 #endif /* HAVE_OTF */
1754       if (str[0] == 'l' && str[1] == 'a' && str[2] == 'n' && str[3] == 'g'
1755           && str[4] == '=')
1756         {
1757           int count;
1758
1759           str += 5;
1760           for (p = str, count = 2; p < endp && *p != ':'; p++)
1761             if (*p == ',')
1762               count++;
1763           MTABLE_MALLOC (cap->lang, count, MERROR_FONT);
1764           for (p = str, count = 0; p < endp && *p != ':'; p++)
1765             if (*p == ',')
1766               {
1767                 MSymbol lang = msymbol__with_len (str, p - str), sym;
1768
1769                 if (msymbol_get (lang, Miso639_2))
1770                   cap->lang[count++] = lang;
1771                 else if ((sym = msymbol_get (lang, Miso639_1)) != Mnil)
1772                   cap->lang[count++] = sym;
1773                 else if (msymbol_get (lang, Mlanguage))
1774                   cap->lang[count++] = lang;
1775                 str = p + 1;
1776               }
1777           if (str < p)
1778             cap->lang[count++] = msymbol__with_len (str, p - str);
1779           cap->lang[count] = Mnil;
1780           str = p;
1781         }
1782       else if (str[0] == 's' && str[1] == 'c' && str[2] == 'r' && str[3] == 'i'
1783                && str[4] == 'p' && str[5] == 't' && str[6] == '=')
1784         {
1785           str += 7;
1786           for (p = str; p < endp && *p != ':'; p++);
1787           if (str < p)
1788             cap->script = msymbol__with_len (str, p - str);
1789           str = p;
1790         }
1791     }
1792   return cap;
1793 }
1794
1795 /*** @} */
1796 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1797
1798 \f
1799
1800 /* External API */
1801
1802 /*** @addtogroup m17nFont */
1803 /*** @{ */
1804 /*=*/
1805
1806 /***en @name Variables: Keys of font property.  */
1807 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1808 /*** @{ */
1809 /*=*/
1810
1811 /***en
1812     @brief Key of font property specifying foundry.
1813
1814     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1815     is used as a key of font property and face property.  The property
1816     value must be a symbol whose name is a foundry name of a font.  */
1817 /***ja
1818     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1819     
1820     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> 
1821     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1822     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1823
1824 MSymbol Mfoundry;
1825
1826 /***en
1827     @brief Key of font property specifying family.
1828
1829     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1830     used as a key of font property and face property.  The property
1831     value must be a symbol whose name is a family name of a font.  */ 
1832 /***ja
1833     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1834     
1835     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> 
1836     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1837     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1838
1839 MSymbol Mfamily;
1840
1841 /***en
1842     @brief Key of font property specifying weight.
1843
1844     The variable #Mweight is a symbol of name <tt>"weight"</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 weight name of a font (e.g
1847     "medium", "bold").  */ 
1848 /***ja
1849     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1850     
1851     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> 
1852     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1853     Ãͤϡ¢¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1854
1855 MSymbol Mweight;
1856
1857 /***en
1858     @brief Key of font property specifying style.
1859
1860     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1861     used as a key of font property and face property.  The property
1862     value must be a symbol whose name is a style name of a font (e.g
1863     "r", "i", "o").  */ 
1864 /***ja
1865     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1866     
1867     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> 
1868     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1869     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1870
1871 MSymbol Mstyle;
1872
1873 /***en
1874     @brief Key of font property specifying stretch.
1875
1876     The variable #Mstretch is a symbol of name <tt>"stretch"</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 a stretch name of a font (e.g
1879     "normal", "condensed").  */ 
1880 /***ja
1881     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1882     
1883     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> 
1884     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1885     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1886
1887 MSymbol Mstretch;
1888
1889 /***en
1890     @brief Key of font property specifying additional style.
1891
1892     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1893     is used as a key of font property and face property.  The property
1894     value must be a symbol whose name is an additional style name of a
1895     font (e.g "serif", "", "sans").  */ 
1896 /***ja
1897     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1898     
1899     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> 
1900     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1901     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1902
1903 MSymbol Madstyle;
1904
1905 /***en
1906     @brief Key of font property specifying spacing.
1907
1908     The variable #Madstyle is a symbol of name <tt>"spacing"</tt> and
1909     is used as a key of font property.  The property value must be a
1910     symbol whose name specifies the spacing of a font (e.g "p" for
1911     proportional, "m" for monospaced).  */ 
1912 /***ja
1913     @brief spacing ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1914     
1915     ÊÑ¿ô #Mspacing ¤Ï <tt>"spacing"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1916     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î spacing
1917     ÆÃÀ­¤ò¼¨¤¹Ì¾Á° ("p", "m" Åù)¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£  */
1918
1919 MSymbol Mspacing;
1920
1921 /***en
1922     @brief Key of font property specifying registry.
1923
1924     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1925     and is used as a key of font property.  The property value must be
1926     a symbol whose name is a registry name a font registry
1927     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1928 /***ja
1929     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1930     
1931     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> 
1932     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1933     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" 
1934     Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£    */
1935
1936 MSymbol Mregistry;
1937
1938 /***en
1939     @brief Key of font property specifying size.
1940
1941     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1942     used as a key of font property and face property.  The property
1943     value must be an integer specifying a font design size in the unit
1944     of 1/10 point (on 100 dpi display).  */ 
1945 /***ja
1946     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1947     
1948     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> 
1949     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1950     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 
1951     ¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£
1952     */
1953
1954 MSymbol Msize;
1955
1956 /***en
1957     @brief Key of font property specifying file name.
1958
1959     The variable #Mfontfile is a symbol of name <tt>"fontfile"</tt>
1960     and is used as a key of font property.  The property value must be
1961     a symbol whose name is a font file name.  */ 
1962 /***ja
1963     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1964     
1965     ÊÑ¿ô #Mfontfile ¤Ï <tt>"fontfile"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1966     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤
1967     ¥ë̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¤È¤¹¤ë¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£ */
1968
1969 MSymbol Mfontfile;
1970
1971 /***en
1972     @brief Key of font property specifying resolution.
1973
1974     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1975     is used as a key of font property and face property.  The property
1976     value must be an integer to specifying a font resolution in the
1977     unit of dots per inch (dpi).  */ 
1978 /***ja
1979     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1980     
1981     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> 
1982     ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1983     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ôÃͤǤ¢¤ë¡£    */
1984
1985 MSymbol Mresolution;
1986
1987 /***en
1988     @brief Key of font property specifying max advance width.
1989
1990     The variable #Mmax_advance is a symbol of name
1991     <tt>"max-advance"</tt> and is used as a key of font property.  The
1992     property value must be an integer specifying a font's max advance
1993     value by pixels.  */ 
1994
1995 MSymbol Mmax_advance;
1996
1997
1998 /***en
1999     @brief Symbol of name "fontconfig".
2000
2001     The variable #Mfontconfig is to be used as an argument of the
2002     functions mfont_parse_name () and mfont_unparse_name ().  */
2003 /***ja
2004     @brief "fontconfig" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2005
2006     ÊÑ¿ô #Mfontconfig ¤Ï´Ø¿ô mfont_parse_name () ¤È mfont_unparse_name ()
2007     ¤Î°ú¿ô¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£  */
2008
2009 MSymbol Mfontconfig;
2010
2011 /***en
2012     @brief Symbol of name "x".
2013
2014     The variable #Mx is to be used for a value of <type> member of the
2015     structure #MDrawGlyph to specify the type of <fontp> member is
2016     actually (XFontStruct *).  */
2017 /***ja
2018     @brief "x" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2019
2020     ÊÑ¿ô #Mx ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2021     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XFontStruct *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹.  */
2022
2023 MSymbol Mx;
2024
2025 /***en
2026     @brief Symbol of name "freetype".
2027
2028     The variable #Mfreetype is to be used for a value of <type> member
2029     of the structure #MDrawGlyph to specify the type of <fontp> member
2030     is actually FT_Face.  */
2031 /***ja
2032     @brief "freetype" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2033
2034     ÊÑ¿ô #Mfreetype ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2035     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï FT_Face ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
2036
2037 MSymbol Mfreetype;
2038
2039 /***en
2040     @brief Symbol of name "xft".
2041
2042     The variable #Mxft is to be used for a value of <type> member of the
2043     structure #MDrawGlyph to specify the type of <fontp> member
2044     is actually (XftFont *).  */
2045 /***ja
2046     @brief  "xft" ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë.
2047
2048     ÊÑ¿ô #Mxft ¤Ï¹½Â¤ #MDrawGlyph ¤Î¥á¥ó¥Ð <type> 
2049     ¤ÎÃͤȤ·¤ÆÍѤ¤¤é¤ì¡¢¥á¥ó¥Ð <fontp> ¤Î·¿¤¬¼ÂºÝ¤Ë¤Ï (XftFont *) ¤Ç¤¢¤ë¤³¤È¤òɽ¤¹¡£  */
2050
2051 MSymbol Mxft;
2052
2053 /*=*/
2054 /*** @} */
2055 /*=*/
2056
2057 /***en
2058     @brief List of font files and directories that contain font files.
2059
2060     The variable @c mfont_freetype_path is a plist of FreeType font
2061     files and directories that contain FreeType font files.  Key of
2062     the element is @c Mstring, and the value is a string that
2063     represents a font file or a directory.
2064
2065     The macro M17N_INIT () sets up this variable to contain the
2066     sub-directory "fonts" of the m17n database and the environment
2067     variable "M17NDIR".  The first call of mframe () creates the
2068     internal list of the actually available fonts from this variable.
2069     Thus, an application program, if necessary, must modify the
2070     variable before calling mframe ().  If it is going to add a new
2071     element, value must be a string that can be safely freed.
2072
2073     If the m17n library is not configured to use the FreeType library,
2074     this variable is not used.  */
2075 /***ja
2076     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
2077
2078     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î 
2079     plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring 
2080     ¤Ç¤¢¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
2081
2082     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ¿ô 
2083     "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
2084     mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£
2085     ¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢mframe () 
2086     ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2087     ¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
2088
2089     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
2090
2091 MPlist *mfont_freetype_path;
2092
2093 /*=*/
2094
2095 /***en
2096     @brief Create a new font.
2097
2098     The mfont () function creates a new font object that has no
2099     property.
2100
2101     @return
2102     This function returns a pointer to the created font object.  */
2103 /***ja
2104     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
2105
2106     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
2107
2108     @return
2109     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
2110
2111 MFont *
2112 mfont ()
2113 {
2114   MFont *font;
2115
2116   MSTRUCT_CALLOC (font, MERROR_FONT);
2117   return font;
2118 }
2119
2120 /*=*/
2121
2122 /***en
2123     @brief Create a font by parsing a fontname.
2124
2125     The mfont_parse_name () function creates a new font object.  The
2126     properties are extracted fontname $NAME.
2127
2128     $FORMAT specifies the format of $NAME.  If $FORMAT is #Mx, $NAME
2129     is parsed as XLFD (X Logical Font Description).  If $FORMAT is
2130     #Mfontconfig, $NAME is parsed as Fontconfig's textual
2131     representation of font.  If $FORMAT is #Mnil, $NAME is at first
2132     parsed as XLFD, and it it fails, parsed as Fontconfig's
2133     representation.
2134
2135     @return
2136     If the operation was successful, this function returns a pointer
2137     to the created font.  Otherwise it returns @c NULL.  */
2138
2139 /***ja
2140     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2141
2142     ´Ø¿ô mfont_parse_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ 
2143     $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
2144
2145     $FORMAT ¤Ï $NAME ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ØÄꤹ¤ë¡£$FORMAT ¤¬ #Mx ¤Ç¤¢¤ì¤Ð¡¢
2146     $NAME ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
2147     $FORMAT ¤¬ #Mfontconfig ¤Ç¤¢¤ì¤Ð $NAME ¤Ï Fontfonfig 
2148     ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£$FORMAT ¤¬ #Mnil ¤Ç¤¢¤ì¤Ð¡¢¤Þ¤º XLFD 
2149     ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¡¢¤½¤ì¤Ë¼ºÇÔ¤·¤¿¤é Fontconfig ¤Ë½¾¤Ã¤Æ²òÀϤµ¤ì¤ë¡£
2150
2151     @return
2152     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_parse_name () 
2153     ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
2154
2155 MFont *
2156 mfont_parse_name (const char *name, MSymbol format)
2157 {
2158   MFont template, *font;
2159   
2160   MFONT_INIT (&template);
2161   if (mfont__parse_name_into_font (name, format, &template) < 0)
2162     MERROR (MERROR_FONT, NULL);
2163   MSTRUCT_CALLOC (font, MERROR_FONT);
2164   *font = template;
2165   return font;
2166 }
2167
2168 /*=*/
2169
2170 /***en
2171     @brief Create a fontname from a font.
2172
2173     The mfont_unparse_name () function creates a fontname string
2174     from font $FONT according to $FORMAT.
2175
2176     $FORMAT must be #Mx or #Mfontconfig.  If it is #Mx, the fontname
2177     is in XLFD (X Logical Font Description) format.  If it is
2178     #Mfontconfig, the fontname is in the style of Fontconfig's text
2179     representation.
2180
2181     @return
2182     This function returns a newly allocated fontname string, which is
2183     not freed unless the user explicitly does so by free ().  */
2184
2185 /***ja
2186     @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
2187
2188     ´Ø¿ô mfont_unparse_name () ¤Ï ¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È $FONT 
2189     ¤ò¸µ¤Ë$FORMAT ¤Ë½¾¤Ã¤Æºî¤ë¡£
2190
2191     $FORMAT ¤Ï #Mx ¤Þ¤¿¤Ï #Mfontconfig ¤Ç¤¢¤ë¡£
2192     #Mx ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£
2193     #Mfontconfig ¤Ê¤é¤Ð¥Õ¥©¥ó¥È̾¤Ï Fontconfig ¤Î¥Õ¥©¥ó¥È¥Æ¥­¥¹¥Èɽ¸½¤Ë½¾¤¦¡£
2194
2195     @return 
2196     ¤³¤Î´Ø¿ô¤Ï¿·¤¿¤Ë¥¢¥í¥±¡¼¥È¤·¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶¤¬
2197     free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
2198
2199 char *
2200 mfont_unparse_name (MFont *font, MSymbol format)
2201 {
2202   char *name;
2203
2204   if (format == Mx)
2205     name = xlfd_unparse_name (font, 1);
2206 #ifdef HAVE_FONTCONFIG
2207   else if (format == Mfontconfig)
2208     name = mfont__ft_unparse_name (font);
2209
2210 #endif /* HAVE_FONTCONFIG */
2211   else
2212     MERROR (MERROR_FONT, NULL);
2213   return name;
2214 }
2215
2216 /*=*/
2217
2218 /***en
2219     @brief Make a copy of a font.
2220
2221     The mfont_copy () function returns a new copy of font $FONT.  */
2222 /***ja
2223     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
2224
2225     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
2226
2227 MFont *
2228 mfont_copy (MFont *font)
2229 {
2230   MFont *copy;
2231
2232   MSTRUCT_MALLOC (copy, MERROR_FONT);
2233   *copy = *font;
2234   return copy;
2235 }
2236
2237 /*=*/
2238
2239 /***en
2240     @brief Get a property value of a font.
2241
2242     The mfont_get_prop () function gets the value of $KEY property of
2243     font $FONT.  $KEY must be one of the following symbols:
2244
2245         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c Madstyle,
2246         @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
2247
2248     If $FONT is a return value of mfont_find (), $KEY can also be one
2249     of the following symbols:
2250
2251         #Mfont_ascent, #Mfont_descent, #Mmax_advance.
2252
2253     @return If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2254     @c Madstyle, @c Mregistry, or @c Mspacing, this function returns
2255     the corresponding value as a symbol.  If the font does not have
2256     $KEY property, it returns @c Mnil.  If $KEY is @c Msize, @c
2257     Mresolution, #Mfont_ascent, Mfont_descent, or #Mmax_advance, this
2258     function returns the corresponding value as an integer.  If the
2259     font does not have $KEY property, it returns 0.  If $KEY is
2260     something else, it returns @c NULL and assigns an error code to
2261     the external variable #merror_code.  */
2262  
2263 /***ja
2264     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
2265
2266     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬
2267     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
2268     ¤Ð¤Ê¤é¤Ê¤¤¡£
2269
2270         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2271         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution, @c Mspacing.
2272
2273     @return $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
2274     Madstyle, @c Mregistry, @c Mspacing ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃÍ
2275     ¤ò¥·¥ó¥Ü¥ë¤È¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï
2276     @c Mnil ¤òÊÖ¤¹¡£$KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢
2277     ÁêÅö¤¹¤ëÃͤò¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤
2278     ¾ì¹ç¤Ë¤Ï 0 ¤òÊÖ¤¹¡£$KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢
2279     ³°ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
2280
2281 void *
2282 mfont_get_prop (MFont *font, MSymbol key)
2283 {
2284   MRealizedFont *rfont = NULL;
2285
2286   if (font->type == MFONT_TYPE_REALIZED)
2287     rfont = (MRealizedFont *) font;
2288
2289   if (key == Mfoundry)
2290     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
2291   if (key == Mfamily)
2292     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
2293   if (key == Mweight)
2294     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
2295   if (key == Mstyle)
2296     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
2297   if (key == Mstretch)
2298     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
2299   if (key == Madstyle)
2300     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
2301   if (key == Mregistry)
2302     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
2303   if (key == Msize)
2304     {
2305       int size = font->size;
2306       return (void *) size;
2307     }
2308   if (key == Mresolution)
2309     {
2310       int resy = font->property[MFONT_RESY];
2311       return (void *) resy;
2312     }
2313   if (key == Mfontfile)
2314     return (void *) font->file;
2315   if (key == Mspacing)
2316     return (font->spacing == MFONT_SPACING_UNDECIDED ? Mnil
2317             : msymbol (font->spacing == MFONT_SPACING_PROPORTIONAL ? "p"
2318                        : font->spacing == MFONT_SPACING_MONO ? "m" : "c"));
2319   if (rfont)
2320     {
2321       if (key == Mfont_ascent)
2322         return (void *) rfont->ascent;
2323       if (key == Mfont_descent)
2324         return (void *) rfont->descent;
2325       if (key == Mmax_advance)
2326         return (void *) rfont->max_advance;
2327     }
2328   MERROR (MERROR_FONT, NULL);
2329 }
2330
2331
2332 /*=*/
2333 /***en
2334     @brief Put a property value to a font.
2335
2336     The mfont_put_prop () function puts a font property whose key is
2337     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
2338     following symbols:
2339
2340         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2341         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
2342
2343     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
2344     Otherwise, $VAL must be a symbol.  */
2345  /***ja
2346     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
2347
2348     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY 
2349     ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
2350
2351         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2352         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
2353
2354     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL 
2355     ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
2356
2357 int
2358 mfont_put_prop (MFont *font, MSymbol key, void *val)
2359 {
2360   if (key == Mfoundry)
2361     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
2362   else if (key == Mfamily)
2363     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
2364   else if (key == Mweight)
2365     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
2366   else if (key == Mstyle)
2367     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
2368   else if (key == Mstretch)
2369     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
2370   else if (key == Madstyle)
2371     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
2372   else if (key == Mregistry)
2373     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
2374   else if (key == Msize)
2375     {
2376       int size = (int) val;
2377       font->size = size;
2378     }
2379   else if (key == Mresolution)
2380     {
2381       unsigned resy = (unsigned) val;
2382       font->property[MFONT_RESY] = resy;
2383     }
2384   else if (key == Mlanguage)
2385     {
2386       char *langname = MSYMBOL_NAME ((MSymbol) val);
2387       int len = MSYMBOL_NAMELEN ((MSymbol) val);
2388       
2389       if (len <= 3)
2390         {
2391           char buf[10];
2392
2393           sprintf (buf, ":lang=%s", langname);
2394           font->capability = msymbol (buf);
2395         }
2396     }
2397   else if (key == Mfontfile)
2398     {
2399       font->file = (MSymbol) val;
2400     }
2401   else
2402     MERROR (MERROR_FONT, -1);
2403   return 0;
2404 }
2405
2406 /*=*/
2407
2408 /***en
2409     @brief Return the font selection priority.
2410
2411     The mfont_selection_priority () function returns a newly created
2412     array of six symbols.  The elements are the following
2413     keys of font properties ordered by priority.
2414
2415         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2416         @c Madstyle, @c Msize.
2417
2418    The m17n library selects the best matching font according to the
2419    order of this array.  A font that has a different value for a
2420    property of lower priority is preferred to a font that has a
2421    different value for a property of higher priority.  */
2422 /***ja
2423     @brief ¥Õ¥©¥ó¥ÈÁªÂò¤ÎÍ¥ÀèÅÙ¤òÊÖ¤¹.
2424
2425     ´Ø¿ô mfont_selection_priority () ¤Ï 6 ¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã¤ÆÊÖ¤¹¡£
2426     ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤Ëʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
2427
2428         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2429         @c Madstyle, @c Msize.
2430
2431    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
2432    ÌÜŪ¤Î¥Õ¥©¥ó¥È¤È¡¢¤½¤ì¤¾¤ì°ã¤¦¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¤¬¤¢¤Ã¤¿¾ì¹ç¡¢Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Ê¤¤¥Õ¥©¥ó¥È¡ÊÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬¹çÃפ·¤Æ¤¤¤ë¥Õ¥©¥ó¥È¡Ë¤¬ÁªÂò¤µ¤ì¤ë¡£
2433
2434    */
2435
2436 MSymbol *
2437 mfont_selection_priority ()
2438 {
2439   MSymbol *keys;
2440   int i;
2441
2442   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
2443   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
2444     {
2445       enum MFontProperty prop = font_score_priority[i];
2446
2447       if (prop == MFONT_SIZE)
2448         keys[i] = Msize;
2449       else if (prop == MFONT_ADSTYLE)
2450         keys[i] = Madstyle;
2451       else if (prop == MFONT_FAMILY)
2452         keys[i] = Mfamily;
2453       else if (prop == MFONT_WEIGHT)
2454         keys[i] = Mweight;
2455       else if (prop == MFONT_STYLE)
2456         keys[i] = Mstyle;
2457       else if (prop == MFONT_STRETCH)
2458         keys[i] = Mstretch;
2459       else
2460         keys[i] = Mfoundry;
2461     }
2462   return keys;
2463 }
2464
2465 /*=*/
2466
2467 /***en
2468     @brief Set the font selection priority.
2469
2470     The mfont_set_selection_priority () function sets font selection
2471     priority according to $KEYS, which is an array of six symbols.
2472     Each element must be one of the below.  No two elements must be
2473     the same.
2474
2475         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2476         @c Madstyle, @c Msize.
2477
2478     See the documentation of the function mfont_selection_priority ()
2479     for details.  */
2480 /***ja
2481     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
2482
2483     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
2484     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£ÇÛÎó¤Ï°Ê²¼¤Î³ÆÍ×ÁǤòŬÀÚ
2485     ¤Ê½çÈÖ¤Çʤ٤¿¤â¤Î¤Ç¤¢¤ë¡£
2486
2487         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
2488         @c Madstyle, @c Msize.
2489
2490     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
2491      */
2492
2493 int
2494 mfont_set_selection_priority (MSymbol *keys)
2495 {
2496   int priority[FONT_SCORE_PRIORITY_SIZE];
2497   int i, j, shift;
2498
2499   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
2500     {
2501       enum MFontProperty prop;
2502
2503       if (*keys == Msize)
2504         prop = MFONT_SIZE;
2505       else if (*keys == Madstyle)
2506         prop = MFONT_ADSTYLE;
2507       else if (*keys == Mfamily)
2508         prop = MFONT_FAMILY;
2509       else if (*keys == Mweight)
2510         prop = MFONT_WEIGHT;
2511       else if (*keys == Mstyle)
2512         prop = MFONT_STYLE;
2513       else if (*keys == Mstretch)
2514         prop = MFONT_STRETCH;
2515       else if (*keys == Mfoundry)
2516         prop = MFONT_FOUNDRY;
2517       else
2518         /* Invalid element.  */
2519         return -1;
2520       for (j = 0; j < i; j++)
2521         if (priority[j] == prop)
2522           /* Duplicated element.  */
2523           return -1;
2524       priority[i] = prop;
2525     }
2526   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
2527     font_score_priority[i] = priority[i];
2528   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
2529      of a score is a flag for a scalable font (see the documentation
2530      of font_score).  */
2531   i = FONT_SCORE_PRIORITY_SIZE - 1;
2532   for (shift = 1; i >= 0; i--)
2533     {
2534       font_score_shift_bits[font_score_priority[i]] = shift;
2535       if (font_score_priority[i] == MFONT_SIZE)
2536         shift += 16;
2537       else if (font_score_priority[i] <= MFONT_FAMILY)
2538         shift++;
2539       else
2540         shift += 2;
2541     }
2542   return 0;
2543 }
2544
2545 /*=*/
2546
2547 /***en
2548     @brief Find a font.
2549
2550     The mfont_find () function returns a pointer to the available font
2551     that matches best the specification $SPEC on frame $FRAME.
2552
2553     $SCORE, if not NULL, must point to a place to store the score
2554     value that indicates how well the found font matches to $SPEC.  The
2555     smaller score means a better match.  */
2556 /***ja
2557     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
2558
2559     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC 
2560     ¤Ë¤â¤Ã¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
2561
2562     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC 
2563     ¤Ë¤É¤ì¤Û¤É¹ç¤Ã¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£
2564     ¥¹¥³¥¢¤¬¾®¤µ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
2565     */
2566
2567 MFont *
2568 mfont_find (MFrame *frame, MFont *spec, int *score, int max_size)
2569 {
2570   MFont spec_copy;
2571   MFont *best;
2572   MFontList *list;
2573   MRealizedFont *rfont;
2574   MFont adjusted;
2575
2576   if (spec->size < 0)
2577     {
2578       double pt = - spec->size;
2579
2580       adjusted = *spec;
2581       adjusted.size = pt * frame->dpi / 72.27 + 0.5;
2582       spec = &adjusted;
2583     }
2584   MFONT_INIT (&spec_copy);
2585   spec_copy.property[MFONT_FAMILY] = spec->property[MFONT_FAMILY];
2586   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
2587   spec_copy.capability = spec->capability;
2588   spec_copy.file = spec->file;
2589
2590   list = mfont__list (frame, &spec_copy, spec, max_size);
2591   if (! list)
2592     return NULL;
2593
2594   best = list->fonts[0].font;
2595   if (score)
2596     *score = list->fonts[0].score;
2597   free (list->fonts);
2598   free (list);
2599   spec_copy = *best;
2600   mfont__merge (&spec_copy, spec, 0);
2601   rfont = mfont__open (frame, best, spec);
2602   if (! rfont)
2603     return NULL;
2604   return (MFont *) rfont;
2605 }
2606
2607 /*=*/
2608 /***en
2609     @brief Set encoding of a font.
2610
2611     The mfont_set_encoding () function sets the encoding information
2612     of font $FONT.
2613
2614     $ENCODING_NAME is a symbol representing a charset that has the
2615     same encoding as the font.
2616
2617     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
2618     has the same repertory as the font.  If it is @c Mnil, whether a
2619     specific character is supported by the font is asked to each font
2620     driver.
2621
2622     @return
2623     If the operation was successful, this function returns 0.
2624     Otherwise it returns -1 and assigns an error code to the external
2625     variable #merror_code.  */
2626 /***ja
2627     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
2628
2629     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó¤òÀßÄꤹ¤ë¡£
2630
2631     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2632
2633     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
2634     @c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ»ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢³Æ¡¹¤Î¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤ËÌ䤤¹ç¤ï¤»¤ë¡£
2635
2636     @return
2637     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô
2638     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
2639
2640
2641 int
2642 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
2643 {
2644   MCharset *encoding_charset = MCHARSET (encoding_name);
2645   MCharset *repertory_charset;
2646   MSymbol registry;
2647   MFontEncoding *encoding;
2648   MPlist *plist;
2649
2650   if (! encoding_charset)
2651     MERROR (MERROR_FONT, -1);
2652   if (repertory_name != Mnil)
2653     {
2654       repertory_charset = MCHARSET (repertory_name);
2655       if (! repertory_charset)
2656         MERROR (MERROR_FONT, -1);
2657     }
2658   else
2659     repertory_charset = NULL;
2660
2661   MSTRUCT_CALLOC (encoding, MERROR_FONT);
2662   encoding->spec = *font;
2663   encoding->encoding_name = encoding_name;
2664   encoding->encoding_charset = encoding_charset;
2665   encoding->repertory_name = repertory_name;
2666   encoding->repertory_charset = repertory_charset;
2667   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
2668   if (registry == Mnil)
2669     registry = Mt;
2670   if (! font_encoding_list)
2671     load_font_encoding_table ();
2672   mplist_push (font_encoding_list, registry, encoding);
2673   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
2674     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
2675                   sizeof (MFont)))
2676       {
2677         mplist_pop (plist);
2678         break;
2679       }
2680   return 0;
2681 }
2682
2683 /*=*/
2684
2685 /***en
2686     @brief Create a fontname from a font.
2687
2688     This function is obsolete.   Use mfont_unparse_name instead. */
2689 /***ja
2690     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
2691
2692     ¤³¤Î´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_unparse_name () ¤ò»ÈÍѤΤ³¤È¡£ */
2693
2694 char *
2695 mfont_name (MFont *font)
2696 {
2697   return mfont_unparse_name (font, Mx);
2698 }
2699
2700 /*=*/
2701
2702 /***en
2703     @brief Create a new font from fontname.
2704
2705     This function is obsolete.  Use mfont_parse_name () instead.  */
2706
2707 /***ja
2708     @brief ¥Õ¥©¥ó¥È¤«¤é¥Õ¥©¥ó¥È̾¤òºî¤ë.
2709
2710     ¤³¤ì¤Ï´Ø¿ô¤ÏÇÑ»ßͽÄê¤Ç¤¢¤ë¡£ mfont_parse_name () ¤ò»ÈÍѤΤ³¤È¡£  */
2711
2712 MFont *
2713 mfont_from_name (const char *name)
2714 {
2715   return mfont_parse_name (name, Mx);
2716 }
2717
2718 /*=*/
2719
2720 /***en
2721     @brief Get resize information of a font.
2722
2723     The mfont_resize_ratio () function lookups the m17n database
2724     \<font, reisize\> and returns a resizing ratio (in percentage) of
2725     FONT.  For instance, if the return value is 150, that means that
2726     the m17n library uses an 1.5 time bigger font than a specified
2727     size.  */
2728
2729 /***ja
2730     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥µ¥¤¥º¾ðÊó¤òÆÀ¤ë
2731
2732     ´Ø¿ô mfont_resize_ratio ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹ \<font, reisize\> 
2733     ¤ò¸¡º÷¤·¡¢¥Õ¥©¥ó¥È FONT ¤Î¥ê¥µ¥¤¥º¤ÎÈæΨ¡Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¡Ë
2734     ¤òÊÖ¤¹¡£¤¿¤È¤¨¤ÐÊÖ¤¹Ãͤ¬ 150 ¤Ç¤¢¤ì¤Ð¡¢m17n ¥é¥¤¥Ö¥é¥ê¤Ï»ØÄꤵ¤ì¤¿¥µ¥¤¥º¤Î 1.5 
2735     ÇܤΥե©¥ó¥È¤ò»ÈÍѤ¹¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£ */
2736
2737 int
2738 mfont_resize_ratio (MFont *font)
2739 {
2740   MFont request = *font;
2741
2742   mfont__resize (font, &request);
2743   return (font->size * 100 / request.size);
2744 }
2745
2746 /*=*/
2747
2748 /***en
2749     @brief Get a list of fonts.
2750
2751     The mfont_list () functions returns a list of fonts available on
2752     frame $FRAME.  $FONT, if not NULL, limits fonts to ones
2753     that match with $FONT.  $LANGUAGE, if not @c Mnil, limits fonts to
2754     ones that support $LANGUAGE.  $MAXNUM, if greater than 0, limits
2755     the number of fonts.
2756
2757     @return
2758     This function returns a plist whose keys are family names and
2759     values are pointers to the object MFont.  The plist must be freed
2760     by m17n_object_unref ().  If no font is found, it returns
2761     NULL.  */
2762
2763 /***ja
2764     @brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
2765
2766     ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2767     $FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2768     $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
2769     $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礭¤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
2770
2771     @return 
2772     ¤³¤Î´Ø¿ô¤Ï¥­¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê
2773     plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () 
2774     ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£  */
2775
2776 MPlist *
2777 mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
2778 {
2779   MPlist *plist, *pl;
2780   MFontList *font_list;
2781   int i;
2782   MFont spec;
2783   
2784   if (font)
2785     spec = *font;
2786   else
2787     MFONT_INIT (&spec);
2788
2789   if (spec.size < 0)
2790     {
2791       double pt = - spec.size;
2792
2793       spec.size = pt * frame->dpi / 72.27 + 0.5;
2794     }
2795
2796   if (language != Mnil)
2797     {
2798       /* ":lang=XXX" */
2799       char *buf = alloca (MSYMBOL_NAMELEN (language) + 7);
2800
2801       sprintf (buf, ":lang=%s", MSYMBOL_NAME (language));
2802       spec.capability = msymbol (buf);
2803     }
2804
2805   font_list = mfont__list (frame, &spec, &spec, 0);
2806   if (! font_list)
2807     return NULL;
2808   if (font_list->nfonts == 0)
2809     {
2810       free (font_list);
2811       return NULL;
2812     }
2813
2814   plist = pl = mplist ();
2815   for (i = 0; i < font_list->nfonts; i++)
2816     {
2817       MSymbol family = FONT_PROPERTY (font_list->fonts[i].font, MFONT_FAMILY);
2818
2819       if (family != Mnil)
2820         pl = mplist_add (pl, family, font_list->fonts[i].font);
2821     }
2822   free (font_list);
2823   return plist;
2824 }
2825
2826
2827 /*=*/
2828
2829 /***en
2830     @brief Check the usability of a font.
2831
2832     The function mfont_check () checkes if $FONT can be used for
2833     $SCRIPT and RLANGUAGE in $FONTSET on $FRAME.
2834
2835     @return If the font is usable, return 1.  Otherwise return 0.
2836  */
2837
2838 int
2839 mfont_check (MFrame *frame, MFontset *fontset, MFont *font,
2840              MSymbol script, MSymbol language)
2841 {
2842   MFont spec;
2843   MPlist *plist, *pl;
2844   int result = 0;
2845   int orig_size;
2846
2847   if (! fontset)
2848     fontset = frame->face->property[MFACE_FONTSET];
2849
2850   plist = mfontset_lookup (fontset, script, Mt, Mnil);
2851   if (script != Mnil)
2852     {
2853       if (language == Mnil)
2854         {
2855           if (! mplist_find_by_key (plist, Mt))
2856             /* No fallback fonts.  */
2857             language = MPLIST_KEY (plist);
2858         }
2859       else if (! mplist_find_by_key (plist, language))
2860         {
2861           /* Try fallback fonts. */
2862           if (mplist_find_by_key (plist, Mt))
2863             language = Mnil;
2864           else
2865             /* No fallback fonts.  */
2866             language = MPLIST_KEY (plist);
2867         }
2868
2869       M17N_OBJECT_UNREF (plist);
2870       plist = mfontset_lookup (fontset, script, language, Mnil);
2871     }
2872   orig_size = font->size;
2873   if (orig_size < 0)
2874     {
2875       double pt = - orig_size;
2876
2877       font->size = pt * frame->dpi / 72.27 + 0.5;
2878     }
2879   MPLIST_DO (pl, plist)
2880     {
2881       spec = *(MFont *) MPLIST_VAL (pl);          
2882       if (mfont__merge (&spec, font, 1) >= 0
2883           && mfont__select (frame, &spec, 0))
2884         {
2885           result = 1;
2886           break;
2887         }
2888     }
2889   font->size = orig_size;
2890   M17N_OBJECT_UNREF (plist);
2891   return result;
2892 }
2893
2894 /*** @} */
2895
2896 /*** @addtogroup m17nDebug */
2897 /*=*/
2898 /*** @{ */
2899
2900 /***en
2901     @brief Dump a font.
2902
2903     The mdebug_dump_font () function prints font $FONT in a human readable
2904     way to the stderr.
2905
2906     @return
2907     This function returns $FONT.  */
2908 /***ja
2909     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
2910
2911     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr 
2912     ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£
2913
2914     @return
2915     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
2916
2917 MFont *
2918 mdebug_dump_font (MFont *font)
2919 {
2920   char *name;
2921   
2922   name = xlfd_unparse_name (font, 0);
2923   if (name)
2924     {
2925       fprintf (stderr, "%s", name);
2926       free (name);
2927     }
2928   if (font->file != Mnil)
2929     {
2930       char *file = MSYMBOL_NAME (font->file);
2931       char *lastslash = file, *p;
2932
2933       for (p = file; *p; p++)
2934         if (*p == '/')
2935           lastslash = p;
2936       if (name)
2937         fprintf (stderr, ",");
2938       fprintf (stderr, "%s", lastslash + 1);
2939     }
2940   if (font->capability != Mnil)
2941     fprintf (stderr, "%s", MSYMBOL_NAME (font->capability));
2942   return font;
2943 }
2944
2945 /*** @} */
2946
2947 /*
2948   Local Variables:
2949   coding: euc-japan
2950   End:
2951 */