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