3ddac5363dbdc24d7f5388c665bf69f4a212bd96
[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 Xft librray, in
110     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 ¥é¥¤¥Ö¥é¥ê¤¬ Xft ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤¿¾ì¹ç¤Ë¤Ï¡¢
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 MFontDriver *mfont__driver_list[MFONT_TYPE_MAX];
339
340 /** Indices to font properties sorted by their priority.  */
341 static int font_score_priority[] =
342   { MFONT_SIZE,
343     MFONT_ADSTYLE,
344     MFONT_FAMILY,
345     MFONT_WEIGHT,
346     MFONT_STYLE,
347     MFONT_STRETCH,
348     MFONT_FOUNDRY
349   };
350
351 #define FONT_SCORE_PRIORITY_SIZE        \
352   (sizeof font_score_priority / sizeof font_score_priority[0])
353
354 /* Indexed by a font property MFONT_XXX, and the value is how many
355    bits to shift the difference of property values.  */
356 static int font_score_shift_bits[MFONT_PROPERTY_MAX];
357
358 /** Predefined symbols for each font property.  The order is important
359     because the function score_font () decides how well a font matches
360     with a spec by checking how close the index is.  */
361
362 static char *common_foundry[] =
363   { "misc",
364     "adobe" };
365 static char *common_family[] =
366   { "fixed",
367     "courier",
368     "helvetica",
369     "times" };
370 static char *common_weight[] =
371   { "ultralight",
372     "extralight",
373     "light",
374     "demilight",
375     "book",
376     "normal",
377     "medium",
378     "regular",
379     "demibold",
380     "bold",
381     "extrabold",
382     "ultrabold",
383     "black" };
384 static char *common_style[] =
385   { "o",
386     "i",
387     "r",
388     "ri",
389     "ro" };
390 static char *common_stretch[] =
391   { "condensed",
392     "narrow",
393     "semicondensed",
394     "normal",
395     "semiexpanded",
396     "expanded" };
397 static char *common_adstyle[] =
398   { "serif",
399     "",
400     "sans" };
401 static char *common_registry[] =
402   { "iso8859-1" };
403
404 /* Table containing all the data above.  */
405
406 struct MFontCommonNames
407 {
408   int num;
409   char **names;
410 };
411
412 static struct MFontCommonNames font_common_names[] =
413   {
414     { sizeof (common_foundry) / sizeof (char *), common_foundry},
415     { sizeof (common_family) / sizeof (char *), common_family},
416     { sizeof (common_weight) / sizeof (char *), common_weight},
417     { sizeof (common_style) / sizeof (char *), common_style},
418     { sizeof (common_stretch) / sizeof (char *), common_stretch},
419     { sizeof (common_adstyle) / sizeof (char *), common_adstyle},
420     { sizeof (common_registry) / sizeof (char *), common_registry}
421   };
422
423
424 /** Table of available font property names.  */
425
426 MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
427
428
429 /** Return the numeric value of SYMBOL as the Nth font property.  */
430
431 #define FONT_PROPERTY_NUMERIC(symbol, n)        \
432   ((symbol) == Mnil                             \
433    ? 0                                          \
434    : ((int) msymbol_get ((symbol), mfont__property_table[(n)].property)))
435
436
437 /** Set the numeric value of SYMBOL as the Nth font property to NUMERIC.  */
438
439 #define SET_FONT_PROPERTY_NUMERIC(symbol, n, numeric)           \
440   msymbol_put((symbol), mfont__property_table[(n)].property,    \
441               (void *) (numeric))
442
443 static char *
444 gen_font_name (char *buf, MFont *font)
445 {
446   char size[16];
447   int i;
448
449   buf[0] = '\0';
450   for (i = 0; i <= MFONT_REGISTRY; i++)
451     if (FONT_PROPERTY (font, i) != Mnil)
452       {
453         char *name = msymbol_name (FONT_PROPERTY (font, i));
454
455         if (name[0])
456           {
457             if (i > 0)
458               strcat (buf, ",");
459             strcat (buf, name);
460           }
461       }
462   sprintf (size, ",%d", font->property[MFONT_SIZE] / 10);
463   strcat (buf, size);
464   return buf;
465 }
466
467
468 \f
469 /* Font selector.  */
470
471 struct MFontEncoding {
472   MFont spec;
473   MSymbol encoding_name;
474   MCharset *encoding_charset;
475   MSymbol repertory_name;
476   MCharset *repertory_charset;
477 };
478
479 static MPlist *font_encoding_list;
480 static MFontEncoding default_encoding;
481
482 /** Load font encoding table from the data <font encoding>.
483     The data has this form:
484         (FONT-SPEC ENCODING) ...
485     where FONT-SPEC has this form:
486         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
487     All elements are symbols.  */
488
489 static int
490 load_font_encoding_table ()
491 {
492   MDatabase *mdb;
493   MPlist *encoding_list, *plist, *pl, *elt;
494
495   font_encoding_list = pl = mplist ();
496
497   mdb = mdatabase_find (Mfont, msymbol ("encoding"), Mnil, Mnil);
498   if (! mdb
499       || ! (encoding_list = (MPlist *) mdatabase_load (mdb)))
500     MERROR (MERROR_FONT, -1);
501
502   MPLIST_DO (plist, encoding_list)
503     {
504       MFontEncoding *encoding;
505       MSymbol registry;
506
507       MSTRUCT_CALLOC (encoding, MERROR_FONT);
508
509       if (! MPLIST_PLIST_P (plist)
510           || (elt = MPLIST_PLIST (plist), mplist_length (elt) < 2)
511           || ! MPLIST_PLIST_P (elt))
512         MWARNING (MERROR_FONT);
513       registry = mfont__set_spec_from_plist (&encoding->spec,
514                                              MPLIST_PLIST (elt));
515       elt = MPLIST_NEXT (elt);
516       if (! MPLIST_SYMBOL_P (elt))
517         MWARNING (MERROR_FONT);
518       encoding->encoding_name = MPLIST_SYMBOL (elt);
519       elt = MPLIST_NEXT (elt);
520       if (MPLIST_TAIL_P (elt))
521         encoding->repertory_name = encoding->encoding_name;
522       else if (! MPLIST_SYMBOL_P (elt))
523         MWARNING (MERROR_FONT);
524       else
525         encoding->repertory_name = MPLIST_SYMBOL (elt);
526
527       if (registry == Mnil)
528         registry = Mt;
529       pl = mplist_add (pl, registry, encoding);
530       continue;
531
532     warning:
533       free (encoding);
534     }
535
536   M17N_OBJECT_UNREF (encoding_list);
537   return 0;
538 }
539
540 typedef struct {
541   MFont spec;
542   int resize;
543 } MFontResize;
544
545 static MPlist *font_resize_list;
546
547 /** Load font size table from the data <font size>.
548     The data has this form:
549         (FONT-SPEC RESIZE-FACTOR) ...
550     where FONT-SPEC has this form:
551         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
552     All elements of FONT-SPEC are symbols.  */
553
554 static int
555 load_font_resize_table ()
556 {
557   MDatabase *mdb;
558   MPlist *size_adjust_list, *plist, *pl, *elt;
559
560   font_resize_list = pl = mplist ();
561
562   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
563   if (! mdb)
564     return -1;
565   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
566     MERROR (MERROR_FONT, -1);
567
568   MPLIST_DO (plist, size_adjust_list)
569     {
570       MFontResize *resize;
571       MSymbol registry;
572
573       MSTRUCT_CALLOC (resize, MERROR_FONT);
574
575       if (! MPLIST_PLIST_P (plist)
576           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
577           || ! MPLIST_PLIST_P (elt))
578         MWARNING (MERROR_FONT);
579       registry = mfont__set_spec_from_plist (&resize->spec,
580                                              MPLIST_PLIST (elt));
581       elt = MPLIST_NEXT (elt);
582       if (! MPLIST_INTEGER_P (elt))
583         MWARNING (MERROR_FONT);
584       resize->resize = MPLIST_INTEGER (elt);
585
586       if (registry == Mnil)
587         registry = Mt;
588       pl = mplist_add (pl, registry, resize);
589       continue;
590
591     warning:
592       free (resize);
593     }
594
595   M17N_OBJECT_UNREF (size_adjust_list);
596   return 0;
597 }
598
599 /** Return a font encoding (and repertory) of FONT.  */
600
601 static MFontEncoding *
602 find_encoding (MFont *font)
603 {
604   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
605   MFontEncoding *encoding = NULL;
606   MPlist *plist;
607
608   if (! font_encoding_list)
609     load_font_encoding_table ();
610   if (! MPLIST_TAIL_P (font_encoding_list))
611     while (1)
612       {
613         plist = font_encoding_list;
614         while (registry ? (plist = mplist_find_by_key (plist, registry))
615                : plist)
616           {
617             encoding = (MFontEncoding *) MPLIST_VAL (plist);
618             if (mfont__match_p (font, &encoding->spec, MFONT_ADSTYLE))
619               {
620                 if (! encoding->encoding_charset)
621                   encoding->encoding_charset
622                     = MCHARSET (encoding->encoding_name);
623                 if (! encoding->encoding_charset)
624                   {
625                     mplist_pop (plist);
626                     continue;
627                   }
628                 if (encoding->repertory_name == encoding->encoding_name)
629                   encoding->repertory_charset = encoding->encoding_charset;
630                 else if (encoding->repertory_name != Mnil)
631                   {
632                     encoding->repertory_charset
633                       = MCHARSET (encoding->repertory_name);
634                     if (! encoding->repertory_charset)
635                       {
636                         mplist_pop (plist);
637                         continue;
638                       }
639                   }
640                 return encoding;
641               }
642             else
643               plist = MPLIST_NEXT (plist);
644           }
645         if (registry == Mnil || registry == Mt)
646           break;
647         registry = Mt;
648       }
649   return &default_encoding;
650 }
651
652
653 \f
654 /* Internal API */
655
656 int
657 mfont__init ()
658 {
659   int i, shift;
660
661   Mfoundry = msymbol ("foundry");
662   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
663   Mfamily = msymbol ("family");
664   mfont__property_table[MFONT_FAMILY].property = Mfamily;
665   Mweight = msymbol ("weight");
666   mfont__property_table[MFONT_WEIGHT].property = Mweight;
667   Mstyle = msymbol ("style");
668   mfont__property_table[MFONT_STYLE].property = Mstyle;
669   Mstretch = msymbol ("stretch");
670   mfont__property_table[MFONT_STRETCH].property = Mstretch;
671   Madstyle = msymbol ("adstyle");
672   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
673   Mregistry = msymbol ("registry");
674   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
675
676   Msize = msymbol ("size");
677   Mresolution = msymbol ("resolution");
678
679   /* The first entry of each mfont__property_table must be Mnil so
680      that actual properties get positive numeric numbers.  */
681   for (i = 0; i <= MFONT_REGISTRY; i++)
682     {
683       MLIST_INIT1 (&mfont__property_table[i], names, 8);
684       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
685     }
686
687   /* Register predefined font property names.  */
688   for (i = 0; i <= MFONT_REGISTRY; i++)
689     {
690       int j;
691
692       for (j = 0; j < font_common_names[i].num; j++)
693         {
694           MSymbol sym = msymbol (font_common_names[i].names[j]);
695
696           if (sym == Mnil)
697             return -1;
698           if (msymbol_put(sym, mfont__property_table[i].property,
699                           (void *) (j + 1)) < 0)
700             return -1;
701           MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
702         }
703     }
704
705   memset (mfont__driver_list, 0, sizeof mfont__driver_list);
706
707   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
708      of a score is a flag for a scalable font (see the documentation
709      of mfont_score).  */
710   i = FONT_SCORE_PRIORITY_SIZE - 1;
711   for (shift = 1; i >= 0; i--)
712     {
713       font_score_shift_bits[font_score_priority[i]] = shift;
714       if (font_score_priority[i] == MFONT_SIZE)
715         shift += 16;
716       else
717         shift += 2;
718     }
719
720   MFONT_INIT (&default_encoding.spec);
721   default_encoding.encoding_name = Mnil;
722   default_encoding.encoding_charset = NULL;
723   default_encoding.repertory_name = Mnil;
724   default_encoding.repertory_charset = NULL;
725   {
726     char *path, *buf;
727     int bufsize;
728
729     mfont_freetype_path = mplist ();
730     bufsize = strlen (M17NDIR) + 7;
731     buf = alloca (bufsize);
732     sprintf (buf, "%s/fonts", M17NDIR);
733     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
734     path = getenv ("M17NDIR");
735     if (path)
736       {
737         i = strlen (path) + 7;
738         if (i > bufsize)
739           buf = alloca (i);
740         sprintf (buf, "%s/fonts", path);
741         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
742       }
743   }
744
745 #ifdef HAVE_FREETYPE
746   if (mfont__ft_init () < 0)
747     return -1;
748 #endif /* HAVE_FREETYPE */
749   if (mfont__flt_init () < 0)
750     return -1;
751
752   return 0;
753 }
754
755 void
756 mfont__fini ()
757 {
758   MPlist *plist;
759   int i;
760
761   mfont__flt_fini ();
762 #ifdef HAVE_FREETYPE
763   mfont__ft_fini ();
764 #endif /* HAVE_FREETYPE */
765
766   MPLIST_DO (plist, mfont_freetype_path)
767     free (MPLIST_VAL (plist));
768   M17N_OBJECT_UNREF (mfont_freetype_path);
769
770   if (font_resize_list)
771     {
772       MPLIST_DO (plist, font_resize_list)
773         free (MPLIST_VAL (plist));
774       M17N_OBJECT_UNREF (font_resize_list);
775       font_resize_list = NULL;
776     }
777   if (font_encoding_list)
778     {
779       MPLIST_DO (plist, font_encoding_list)
780         free (MPLIST_VAL (plist));
781       M17N_OBJECT_UNREF (font_encoding_list);
782       font_encoding_list = NULL;
783     }
784   for (i = 0; i <= MFONT_REGISTRY; i++)
785     MLIST_FREE1 (&mfont__property_table[i], names);
786 }
787
788 void
789 mfont__free_realized (MRealizedFont *rfont)
790 {
791   if (rfont->info)
792     M17N_OBJECT_UNREF (rfont->info);
793   free (rfont);
794 }
795
796
797 /* Compare FONT with REQUEST and return how much they differs.  If
798    FONT does not match with SPEC, return -1.  */
799
800 int
801 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
802 {
803   int score = 0;
804   int i = FONT_SCORE_PRIORITY_SIZE;
805
806   while (--i >= 0)
807     {
808       enum MFontProperty prop = font_score_priority[i];
809
810       if (request->property[prop] != 0)
811         {
812           int val = 0;
813
814           if (spec->property[prop] && font->property[prop]
815               && font->property[prop] != spec->property[prop])
816             return -1;
817           if (font->property[prop])
818             val = abs (font->property[prop] - request->property[prop]);
819           if (prop == MFONT_SIZE)
820             {
821               if (font->property[MFONT_RESY] == 0)
822                 /* This is a scalable font.  We prefer a bitmap font
823                    if the size matches exactly.  */
824                 score |= 1;
825               else
826                 score |= (val << font_score_shift_bits[MFONT_SIZE]
827                           | ((limited_size && val > 0) ? 0x400000 : 0));
828             }
829           else
830             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
831         }
832     }
833   return score;
834 }
835
836
837 /** Return 1 iff FONT matches SPEC.  */
838
839 int
840 mfont__match_p (MFont *font, MFont *spec, int prop)
841 {
842   for (; prop >= 0; prop--)
843     if (spec->property[prop] && font->property[prop]
844         && font->property[prop] != spec->property[prop])
845       return 0;
846   return 1;
847 }
848
849
850 void
851 mfont__set_spec_from_face (MFont *spec, MFace *face)
852 {
853   int i;
854
855   for (i = 0; i <= MFONT_ADSTYLE; i++)
856     mfont__set_property (spec, i, face->property[i]);
857   /* The value 1 is "iso8859-1".  */
858   spec->property[MFONT_REGISTRY] = 1;
859   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
860   spec->property[MFONT_RESY] = 0;
861   spec->property[MFONT_TYPE] = 0;
862 }
863
864
865 extern MSymbol
866 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
867 {
868   int i;
869   MSymbol spec_list[MFONT_REGISTRY + 1];
870   MSymbol registry;
871
872   MFONT_INIT (spec);
873   memset (spec_list, 0, sizeof spec_list);
874   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
875     {
876       if (! MPLIST_SYMBOL_P (plist))
877         MERROR (MERROR_FONT, Mnil);     
878       spec_list[i] = MPLIST_SYMBOL (plist);
879     }
880   registry = spec_list[i - 1];
881   mfont__set_property (spec, MFONT_REGISTRY, registry);
882   for (i -= 2; i >= 0; i--)
883     mfont__set_property (spec, i, spec_list[i]);
884   return registry;
885 }
886
887 MRealizedFont *
888 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
889                MSymbol layouter)
890 {
891   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
892   MPlist *realized_font_list;
893   MRealizedFont *best_font[MFONT_TYPE_MAX], *best;
894   int best_index;
895   int i;
896   int mdebug_mask = MDEBUG_FONT;
897
898   if (registry == Mnil)
899     registry = Mt;
900
901   MPLIST_DO (realized_font_list, frame->realized_font_list)
902     {
903       best = MPLIST_VAL (realized_font_list);
904       if (MPLIST_KEY (realized_font_list) == registry
905           && ! memcmp (&best->spec, spec, sizeof (MFont))
906           && ! memcmp (&best->request, request, sizeof (MFont)))
907         {
908           if (best->layouter != layouter)
909             {
910               MRealizedFont *copy;
911
912               MSTRUCT_MALLOC (copy, MERROR_FONT);
913               *copy = *best;
914               copy->layouter = layouter;
915               if (copy->info)
916                 M17N_OBJECT_REF (copy->info);
917               mplist_add (frame->realized_font_list, registry, copy);
918               best = copy;
919             }
920           return best;
921         }
922     }
923
924   MDEBUG_PUSH_TIME ();
925   best = NULL;
926   best_index = -1;
927   for (i = 0; i < MFONT_TYPE_MAX; i++)
928     {
929       MFontDriver *driver = mfont__driver_list[i];
930
931       best_font[i] = (driver
932                       ? (driver->select) (frame, spec, request, limited_size)
933                       : NULL);
934       if (best_font[i]
935           && (best_index < 0
936               || best_font[best_index]->score < best_font[i]->score))
937         best_index = i;
938     }
939   for (i = 0; i < MFONT_TYPE_MAX; i++)
940     {
941       if (i == best_index)
942         best = best_font[i];
943       else if (best_font[i])
944         free (best_font[i]);
945     }
946
947   if (mdebug__flag & mdebug_mask)
948     {
949       char buf1[256], buf2[256];
950       MFont font = *spec;
951
952       for (i = 0; i < MFONT_PROPERTY_MAX; i++)
953         if (! font.property[i])
954           font.property[i] = request->property[i];
955       gen_font_name (buf2, &font);
956
957       if (best)
958         MDEBUG_PRINT_TIME ("FONT", 
959                            (stderr, " to select <%s> from <%s>.",
960                             gen_font_name (buf1, &best->font),
961                             buf2));
962       else
963         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
964       MDEBUG_POP_TIME ();
965     }
966
967   if (! best)
968     return NULL;
969   best->layouter = layouter;
970   mplist_add (frame->realized_font_list, registry, best);
971   return best;
972 }
973
974
975 /** Open a font specified in RFONT.  Return 0 if successfully
976     opened, otherwise return -1.  */
977
978 int
979 mfont__open (MRealizedFont *rfont)
980 {
981   MPlist *realized_font_list;
982   MSymbol registry = FONT_PROPERTY (&rfont->font, MFONT_REGISTRY);
983
984   if (rfont->status)
985     mdebug_hook ();
986
987   MPLIST_DO (realized_font_list, rfont->frame->realized_font_list)
988     {
989       MRealizedFont *this_rfont = MPLIST_VAL (realized_font_list);
990
991       if (this_rfont->status != 0
992           && MPLIST_KEY (realized_font_list) == registry
993           && ! memcmp (&this_rfont->font, &rfont->font, sizeof (MFont)))
994         {
995           if (rfont->info)
996             M17N_OBJECT_UNREF (rfont->info);
997           rfont->info = this_rfont->info;
998           M17N_OBJECT_REF (this_rfont->info);
999           rfont->status = this_rfont->status;
1000           return (this_rfont->status > 0 ? 0 : -1);
1001         }
1002     }
1003
1004   return (rfont->driver->open) (rfont);
1005 }
1006
1007 void
1008 mfont__close (MRealizedFont *rfont)
1009 {
1010   (rfont->driver->close) (rfont);
1011 }
1012
1013 void
1014 mfont__resize (MFont *spec, MFont *request)
1015 {
1016   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
1017   MFontResize *resize;
1018   MPlist *plist;
1019
1020   if (! font_resize_list)
1021     load_font_resize_table ();
1022   if (! MPLIST_TAIL_P (font_resize_list))
1023     while (1)
1024       {
1025         plist = font_resize_list;
1026         while (registry ? (plist = mplist_find_by_key (plist, registry))
1027                : plist)
1028           {
1029             resize = (MFontResize *) MPLIST_VAL (plist);
1030             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
1031               {
1032                 request->property[MFONT_SIZE]
1033                   = request->property[MFONT_SIZE] * resize->resize / 100;
1034                 return;
1035               }
1036             plist = MPLIST_NEXT (plist);
1037           }
1038         if (registry == Mt)
1039           break;
1040         registry = Mt;
1041       }
1042 }
1043
1044 /* Return 1 if C is encodable, 0, if C is not encodable, -1 if it
1045    can't be decided now.  */
1046
1047 int
1048 mfont__encodable_p (MRealizedFont *rfont, MSymbol layouter_name, int c)
1049 {
1050   MFontEncoding *encoding;
1051
1052   if (layouter_name != Mnil)
1053     return (mfont__flt_encode_char (layouter_name, c)
1054             != MCHAR_INVALID_CODE);
1055   if (! rfont->encoding)
1056     rfont->encoding = find_encoding (&rfont->spec);
1057   encoding = rfont->encoding;
1058   if (! encoding->repertory_charset)
1059     return -1;
1060   return (ENCODE_CHAR (encoding->repertory_charset, c) != MCHAR_INVALID_CODE);
1061 }
1062
1063 unsigned
1064 mfont__encode_char (MRealizedFont *rfont, int c)
1065 {
1066   MFontEncoding *encoding;
1067   unsigned code;
1068
1069   if (rfont->layouter != Mnil)
1070     return mfont__flt_encode_char (rfont->layouter, c);
1071   if (! rfont->encoding)
1072     rfont->encoding = find_encoding (&rfont->font);
1073   encoding = rfont->encoding;
1074   if (! encoding->encoding_charset)
1075     return MCHAR_INVALID_CODE;
1076   code = ENCODE_CHAR (encoding->encoding_charset, c);
1077   if (code == MCHAR_INVALID_CODE)
1078     return MCHAR_INVALID_CODE;
1079   if (! encoding->repertory_charset)
1080     return (rfont->driver->encode_char) (rfont, c, code);
1081   if (ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
1082     return MCHAR_INVALID_CODE;
1083   return code;
1084 }
1085
1086 void
1087 mfont__get_metric (MGlyphString *gstring, int from, int to)
1088 {
1089   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
1090   MRealizedFont *rfont = from_g->rface->rfont;
1091
1092   for (g = from_g; g != to_g; g++)
1093     if (g->rface->rfont != rfont)
1094       {
1095         int idx = GLYPH_INDEX (g);
1096
1097         (rfont->driver->find_metric) (rfont, gstring, from, idx);
1098         from_g = g;
1099         rfont = g->rface->rfont;
1100         from = idx;
1101       }
1102   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
1103 }
1104
1105
1106 void
1107 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1108 {
1109   int numeric;
1110
1111   if (val == Mnil)
1112     numeric = 0;
1113   else
1114     {
1115       numeric = FONT_PROPERTY_NUMERIC (val, key);
1116       if (! numeric)
1117         {
1118           numeric = mfont__property_table[key].used;
1119           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1120           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1121         }
1122     }
1123   font->property[key] = numeric;
1124 }
1125
1126 void
1127 mfont__set_spec (MFont *font, MSymbol *attrs,
1128                  unsigned short size, unsigned short resy)
1129 {
1130   int i;
1131
1132   for (i = 0; i <= MFONT_REGISTRY; i++)
1133     mfont__set_property (font, i, attrs[i]);
1134   font->property[MFONT_SIZE] = size;
1135   font->property[MFONT_RESY] = resy;
1136 }
1137
1138 /*** @} */
1139 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1140
1141 \f
1142
1143 /* External API */
1144
1145 /*** @addtogroup m17nFont */
1146 /*** @{ */
1147 /*=*/
1148
1149 /***en @name Variables: Keys of font property.  */
1150 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1151 /*** @{ */
1152 /*=*/
1153
1154 /***en
1155     @brief Key of font property specifying foundry.
1156
1157     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1158     is used as a key of font property and face property.  The property
1159     value must be a symbol whose name is a foundry name of a font.  */
1160 /***ja
1161     @brief ³«È¯¸µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1162     
1163     ÊÑ¿ô #Mfoundry ¤Ï <tt>"fonudry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1164     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1165     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î³«È¯¸µÌ¾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1166     */
1167
1168 MSymbol Mfoundry;
1169
1170 /***en
1171     @brief Key of font property specifying family.
1172
1173     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1174     used as a key of font property and face property.  The property
1175     value must be a symbol whose name is a family name of a font.  */ 
1176 /***ja
1177     @brief ¥Õ¥¡¥ß¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1178     
1179     ÊÑ¿ô #Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1180     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1181     ¥Õ¥©¥ó¥È¤Î¥Õ¥¡¥ß¥ê̾¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1182     */
1183
1184 MSymbol Mfamily;
1185
1186 /***en
1187     @brief Key of font property specifying weight.
1188
1189     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1190     used as a key of font property and face property.  The property
1191     value must be a symbol whose name is a weight name of a font (e.g
1192     "medium", "bold").  */ 
1193 /***ja
1194     @brief ÂÀ¤µ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1195     
1196     ÊÑ¿ô #Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1197     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1198     ¥Õ¥©¥ó¥È¤ÎÂÀ¤µÌ¾ ( "medium", "bold" Åù) ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1199     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1200     */
1201
1202 MSymbol Mweight;
1203
1204 /***en
1205     @brief Key of font property specifying style.
1206
1207     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1208     used as a key of font property and face property.  The property
1209     value must be a symbol whose name is a style name of a font (e.g
1210     "r", "i", "o").  */ 
1211 /***ja
1212     @brief ¥¹¥¿¥¤¥ë¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1213     
1214     ÊÑ¿ô #Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
1215     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1216     ¥Õ¥©¥ó¥È¤Î¥¹¥¿¥¤¥ë̾ ("r", "i", "o" Åù)¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç
1217     ¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1218     */
1219
1220 MSymbol Mstyle;
1221
1222 /***en
1223     @brief Key of font property specifying stretch.
1224
1225     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1226     is used as a key of font property and face property.  The property
1227     value must be a symbol whose name is a stretch name of a font (e.g
1228     "normal", "condensed").  */ 
1229 /***ja
1230     @brief Éý¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1231     
1232     ÊÑ¿ô #Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1233     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1234     Ãͤϡ¢¥Õ¥©¥ó¥È¤Îʸ»úÉý̾ ( "normal", "condensed" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1235     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1236     */
1237
1238 MSymbol Mstretch;
1239
1240 /***en
1241     @brief Key of font property specifying additional style.
1242
1243     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1244     is used as a key of font property and face property.  The property
1245     value must be a symbol whose name is an additional style name of a
1246     font (e.g "serif", "", "sans").  */ 
1247 /***ja
1248     @brief adstyle ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1249     
1250     ÊÑ¿ô #Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢
1251     ¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£
1252     Ãͤϡ¢¥Õ¥©¥ó¥È¤Î adstyle Ì¾("serif", "", "sans" Åù)¤ò̾Á°¤È¤·¤Æ»ý
1253     ¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1254     */
1255
1256 MSymbol Madstyle;
1257
1258 /***en
1259     @brief Key of font property specifying registry.
1260
1261     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1262     and is used as a key of font property.  The property value must be
1263     a symbol whose name is a registry name a font registry
1264     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1265 /***ja
1266     @brief ¥ì¥¸¥¹¥È¥ê¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1267     
1268     ÊÑ¿ô #Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó
1269     ¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢¥Õ¥©
1270     ¥ó¥È¤Î¥ì¥¸¥¹¥È¥ê̾ ( "iso8859-1", "jisx0208.1983-0" Åù) ¤ò̾Á°¤È¤·
1271     ¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1272     */
1273
1274 MSymbol Mregistry;
1275
1276 /***en
1277     @brief Key of font property specifying size.
1278
1279     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1280     used as a key of font property and face property.  The property
1281     value must be an integer specifying a font design size in the unit
1282     of 1/10 point (on 100 dpi display).  */ 
1283 /***ja
1284     @brief ¥µ¥¤¥º¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1285     
1286     ÊÑ¿ô #Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢¥Õ¥©
1287     ¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£Ãͤϡ¢
1288     100 dpi ¤Î¥Ç¥£¥¹¥×¥ì¥¤¾å¤Ç¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤ò 1/10 ¥Ý¥¤¥ó
1289     ¥Èñ°Ì¤Ç¼¨¤¹À°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1290     */
1291
1292 MSymbol Msize;
1293
1294 /***en
1295     @brief Key of font property specifying resolution.
1296
1297     The variable #Mresolution is a symbol of name <tt>"resolution"</tt> and
1298     is used as a key of font property and face property.  The property
1299     value must be an integer to specifying a font resolution in the
1300     unit of dots per inch (dpi).  */ 
1301 /***ja
1302     @brief ²òÁüÅÙ¤ò»ØÄꤹ¤ë¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼.
1303     
1304     ÊÑ¿ô #Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¥·¥ó¥Ü
1305     ¥ë¤Ç¤¢¤ê¡¢¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤È¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤ÆÍѤ¤¤é
1306     ¤ì¤ë¡£Ãͤϡ¢¥Õ¥©¥ó¥È¤Î²òÁüÅÙ¤ò dots per inch (dpi) Ã±°Ì¤Ç¼¨¤¹À°¿ô
1307     ÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1308     */
1309
1310 MSymbol Mresolution;
1311
1312 /*=*/
1313 /*** @} */
1314 /*=*/
1315
1316 /***en
1317     @brief List of font files and directories that contain font files.
1318
1319     The variable @c mfont_freetype_path is a plist of FreeType font
1320     files and directories that contain FreeType font files.  Key of
1321     the element is @c Mstring, and the value is a string that
1322     represents a font file or a directory.
1323
1324     The macro M17N_INIT () sets up this variable to contain the
1325     sub-directory "fonts" of the m17n database and the environment
1326     variable "M17NDIR".  The first call of mframe () creates the
1327     internal list of the actually available fonts from this variable.
1328     Thus, an application program, if necessary, must modify the
1329     variable before calling mframe ().  If it is going to add a new
1330     element, value must be a string that can be safely freed.
1331
1332     If the m17n library is not configured to use the FreeType library,
1333     this variable is not used.  */
1334 /***ja
1335     @brief ¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ê¥¹¥È.
1336
1337     ÊÑ¿ô @c mfont_freetype_path ¤Ï¡¢¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë¤È¥Õ¥©¥ó¥È¥Õ¥¡¥¤¥ë
1338     ¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê¤Î plist ¤Ç¤¢¤ë¡£³ÆÍ×ÁǤΥ­¡¼¤Ï @c Mstring ¤Ç¤¢
1339     ¤ê¡¢Ãͤϥե©¥ó¥È¥Õ¥¡¥¤¥ë¤«¥Ç¥£¥ì¥¯¥È¥ê¤ò¼¨¤¹Ê¸»úÎó¤Ç¤¢¤ë¡£
1340
1341     ¥Þ¥¯¥í M17N_INIT () ¤Ë¤è¤Ã¤Æ¡¢¤³¤ÎÊÑ¿ô¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤È´Ä¶­ÊÑ
1342      ¿ô "M17NDIR" ÁÐÊý¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê "fonts" ¤ò´Þ¤à¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
1343      mframe () ¤ÎºÇ½é¤Î¸Æ¤Ó½Ð¤·¤ÎºÝ¤Ë¡¢¤³¤ÎÊÑ¿ô¤«¤é¼ÂºÝ¤Ë»ÈÍѤǤ­¤ë¥Õ¥©
1344      ¥ó¥È¤ÎÆâÉô¥ê¥¹¥È¤¬ºî¤é¤ì¤ë¡£¤½¤³¤Ç¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢
1345      mframe () ¤ò¸Æ¤ÖÁ°¤Ë¡ÊɬÍפʤé¤Ð¡Ë¤³¤ÎÊÑ¿ô¤òÊѹ¹¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê
1346      ¤¤¡£¿·¤·¤¤Í×ÁǤòÄɲ乤ë¾ì¹ç¤Ë¤Ï¡¢¤½¤ÎÃͤϰÂÁ´¤Ë³«Êü¤Ç¤­¤ëʸ»úÎó
1347      ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1348
1349     m17n ¥é¥¤¥Ö¥é¥ê¤¬ FreeType ¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤Ê¤¤¾ì
1350     ¹ç¤Ë¤Ï¡¢¤³¤ÎÊÑ¿ô¤ÏÍѤ¤¤é¤ì¤Ê¤¤¡£ */
1351
1352 MPlist *mfont_freetype_path;
1353
1354 /*=*/
1355
1356 /***en
1357     @brief Create a new font.
1358
1359     The mfont () function creates a new font object that has no
1360     property.
1361
1362     @return
1363     This function returns a pointer to the created font object.  */
1364 /***ja
1365     @brief ¿·¤·¤¤¥Õ¥©¥ó¥È¤òºî¤ë.
1366
1367     ´Ø¿ô mfont () ¤Ï¥×¥í¥Ñ¥Æ¥£¤ò°ìÀÚ»ý¤¿¤Ê¤¤¿·¤·¤¤¥Õ¥©¥ó¥È¤ò¥ª¥Ö¥¸¥§¥¯
1368     ¥È¤òºî¤ë¡£
1369
1370     @return
1371     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1372
1373 MFont *
1374 mfont ()
1375 {
1376   MFont *font;
1377
1378   MSTRUCT_CALLOC (font, MERROR_FONT);
1379   return font;
1380 }
1381
1382 /*=*/
1383
1384 /***en
1385     @brief Create a new font from fontname.
1386
1387     The mfont_from_name () function creates a new font object.  The
1388     properties are extracted fontname $NAME.
1389
1390     How to extract properties is window system dependent.  The m17n-X
1391     library parses $NAME as XLFD (X Logical Font Description).
1392
1393     @return
1394     If the operation was successful, this function returns a pointer
1395     to the created font.  Otherwise it returns @c NULL.  */
1396
1397 /***ja
1398     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1399
1400     ´Ø¿ô mfont_from_name () ¤Ï¡¢¥Õ¥©¥ó¥È̾ $NAME ¤«¤é¼è¤ê½Ð¤µ¤ì¤¿¥×¥í¥Ñ
1401     ¥Æ¥£¤ò»ý¤Ä¡¢¿·¤·¤¤¥Õ¥©¥ó¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë¡£
1402
1403     ¤É¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤ò¼è¤ê½Ð¤¹¤«¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£
1404     m17n-X ¥é¥¤¥Ö¥é¥ê¤Î¾ì¹ç¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤Ã¤Æ
1405     $NAME ¤ò²òÀϤ¹¤ë¡£
1406
1407     @return
1408     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_from_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1409     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£  */
1410
1411 MFont *
1412 mfont_from_name (char *name)
1413 {
1414   MFont template, *font;
1415
1416   if (mwin__parse_font_name (name, &template) < 0)
1417     return NULL;
1418   MSTRUCT_CALLOC (font, MERROR_FONT);
1419   *font = template;
1420   return font;
1421 }
1422
1423 /*=*/
1424
1425 /***en
1426     @brief Make a copy of a font.
1427
1428     The mfont_copy () function returns a new copy of font $FONT.  */
1429 /***ja
1430     @brief ¥Õ¥©¥ó¥È¤Î¥³¥Ô¡¼¤òºî¤ë.
1431
1432     ´Ø¿ô Mfont_copy () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥³¥Ô¡¼¤òºî¤ê¡¢¤½¤ì¤òÊÖ¤¹¡£ */
1433
1434 MFont *
1435 mfont_copy (MFont *font)
1436 {
1437   MFont *copy;
1438
1439   MSTRUCT_MALLOC (copy, MERROR_FONT);
1440   *copy = *font;
1441   return copy;
1442 }
1443
1444 /*=*/
1445
1446 /***en
1447     @brief Create a fontname from a font.
1448
1449     The mfont_name () function creates a fontname string created from
1450     font $FONT.
1451
1452     The syntax of fontname is window system dependent.  The m17n-X
1453     library returns a fontname conforming to XLFD (X Logical Font
1454     Description).
1455
1456     @return
1457     This function returns the created fontname string, which is not freed
1458     unless the user explicitly does so by free ().  */
1459 /***ja
1460     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë.
1461
1462     ´Ø¿ô mfont_name () ¤Ï¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤ò¥Õ¥©¥ó¥È
1463     $FONT ¤ò¸µ¤Ëºî¤ë¡£
1464
1465     ¥Õ¥©¥ó¥È̾¤Îʸˡ¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£m17n-X ¥é¥¤¥Ö¥é¥ê
1466     ¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¥Õ¥©¥ó¥È̾¤òÊÖ¤¹¡£
1467
1468     @return 
1469     ¤³¤Î´Ø¿ô¤Ïºî¤Ã¤¿¥Õ¥©¥ó¥È̾¤Îʸ»úÎó¤òÊÖ¤¹¡£Ê¸»úÎó¤Ï¡¢¥æ¡¼¥¶
1470     ¤¬ free () ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë²òÊü¤·¤Ê¤¤¸Â¤ê²òÊü¤µ¤ì¤Ê¤¤¡£  */
1471
1472 char *
1473 mfont_name (MFont *font)
1474 {
1475   return mwin__build_font_name (font);
1476 }
1477
1478 /*=*/
1479
1480 /***en
1481     @brief Get a property value of a font.
1482
1483     The mfont_get_prop () function gets the value of $KEY property of
1484     font $FONT.  $KEY must be one of the following symbols:
1485
1486         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1487         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1488
1489     @return
1490     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1491     Madstyle, or @c Mregistry, this function returns the
1492     corresponding value as a symbol.  If the font does not have $KEY
1493     property, it returns @c Mnil.
1494     If $KEY is @c Msize or @c Mresolution, this function returns the
1495     corresponding value as an integer.  If the font does not have $KEY
1496     property, it returns 0.
1497     If $KEY is something else, it returns @c NULL and assigns an error
1498     code to the external variable #merror_code.  */
1499
1500 /***ja
1501     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1502
1503     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1504     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1505     ¤Ð¤Ê¤é¤Ê¤¤¡£
1506
1507         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1508         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1509
1510     @return 
1511     $KEY ¤¬ @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1512     Madstyle, @c Mregistry ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ì¤Ð¡¢ÁêÅö¤¹¤ëÃͤò¥·¥ó¥Ü¥ë¤È
1513     ¤·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï @c Mnil ¤òÊÖ¤¹¡£
1514     $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¤Ë¤Ï¡¢ÁêÅö¤¹¤ëÃͤò
1515     ¤ÏÀ°¿ôÃͤȤ·¤ÆÊÖ¤¹¡£¥Õ¥©¥ó¥È¤¬¤½¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤¿¤Ê¤¤¾ì¹ç¤Ë¤Ï 0 ¤ò
1516     ÊÖ¤¹¡£
1517     $KEY ¤¬¤½¤ì°Ê³°¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢@c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô 
1518     #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1519
1520 void *
1521 mfont_get_prop (MFont *font, MSymbol key)
1522 {
1523   if (key == Mfoundry)
1524     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1525   if (key == Mfamily)
1526     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1527   if (key == Mweight)
1528     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1529   if (key == Mstyle)
1530     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1531   if (key == Mstretch)
1532     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1533   if (key == Madstyle)
1534     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1535   if (key == Mregistry)
1536     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1537   if (key == Msize)
1538     {
1539       int size = font->property[MFONT_SIZE];
1540       return (void *) size;
1541     }
1542   if (key == Mresolution)
1543     {
1544       int resy = font->property[MFONT_RESY];
1545       return (void *) resy;
1546     }
1547
1548   MERROR (MERROR_FONT, NULL);
1549 }
1550
1551
1552 /*=*/
1553 /***en
1554     @brief Put a property value to a font.
1555
1556     The mfont_put_prop () function puts a font property whose key is
1557     $KEY and value is $VAL to font $FONT.  $KEY must be one of the
1558     following symbols:
1559
1560         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1561         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1562
1563     If $KEY is @c Msize or @c Mresolution, $VAL must be an integer.
1564     Otherwise, $VAL must be a symbol.  */
1565 /***ja
1566     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë.
1567
1568     ´Ø¿ô mfont_put_prop () ¤Ï¡¢¥Õ¥©¥ó¥È $FONT ¤Î¥­¡¼¤¬$KEY ¤Ç¤¢¤ë¥×¥í
1569     ¥Ñ¥Æ¥£¤ÎÃͤò $VAL ¤ËÀßÄꤹ¤ë¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤¢
1570     ¤ë¡£
1571
1572         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1573         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1574
1575     $KEY ¤¬ @c Msize ¤« @c Mresolution ¤Ç¤¢¤ì¤Ð $VAL ¤ÏÀ°¿ôÃͤǤʤ¯¤Æ
1576     ¤Ï¤é¤Ê¤¤¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢$VAL ¤Ï¥·¥ó¥Ü¥ë¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£*/
1577
1578 int
1579 mfont_put_prop (MFont *font, MSymbol key, void *val)
1580 {
1581   if (key == Mfoundry)
1582     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1583   else if (key == Mfamily)
1584     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1585   else if (key == Mweight)
1586     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1587   else if (key == Mstyle)
1588     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1589   else if (key == Mstretch)
1590     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1591   else if (key == Madstyle)
1592     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1593   else if (key == Mregistry)
1594     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1595   else if (key == Msize)
1596     {
1597       unsigned size = (unsigned) val;
1598       font->property[MFONT_SIZE] = size;
1599     }
1600   else if (key == Mresolution)
1601     {
1602       unsigned resy = (unsigned) val;
1603       font->property[MFONT_RESY] =  resy;
1604     }
1605   else
1606     MERROR (MERROR_FONT, -1);
1607   return 0;
1608 }
1609
1610 /*=*/
1611
1612 /***en
1613     @brief Return the font selection priority.
1614
1615     The mfont_selection_priority () function returns a newly created
1616     array of six symbols.  The elements are the following
1617     keys of font properties ordered by priority.
1618
1619         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1620         @c Madstyle, @c Msize.
1621
1622    The m17n library selects the best matching font according to the
1623    order of this array.  A font that has a different value for a
1624    property of lower priority is preferred to a font that has a
1625    different value for a property of higher priority.  */
1626 /***ja
1627     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÊÖ¤¹.
1628
1629     ´Ø¿ô mfont_selection_priority () ¤Ï6¤Ä¤Î¥·¥ó¥Ü¥ë¤«¤é¤Ê¤ëÇÛÎó¤òºî¤Ã
1630     ¤ÆÊÖ¤¹¡£ÇÛÎó¤ÎÍ×ÁǤϡ¢°Ê²¼¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤òÍ¥ÀèÅÙ½ç¤ËÊÂ
1631     ¤Ù¤¿¤â¤Î¤Ç¤¢¤ë¡£
1632
1633         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1634         @c Madstyle, @c Msize.
1635
1636    m17n ¥é¥¤¥Ö¥é¥ê¤Ï¤³¤ÎÇÛÎó¤Ë½¾¤Ã¤Æ¡¢ºÇ¤â¹çÃפ¹¤ë¥Õ¥©¥ó¥È¤òÁªÂò¤¹¤ë¡£
1637    Í¥ÀèÅÙ¤ÎÄ㤤¥×¥í¥Ñ¥Æ¥£¤ÎÃͤ¬°ã¤¦¥Õ¥©¥ó¥È¤ÈÍ¥ÀèÅ٤ι⤤¥×¥í¥Ñ¥Æ¥£¤Î
1638    Ãͤ¬°ã¤¦¥Õ¥©¥ó¥È¤¬¤¢¤ë¾ì¹ç¡¢Á°¼Ô¤¬ÁªÂò¤µ¤ì¤ë¡£
1639    */
1640
1641 MSymbol *
1642 mfont_selection_priority ()
1643 {
1644   MSymbol *keys;
1645   int i;
1646
1647   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1648   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1649     {
1650       enum MFontProperty prop = font_score_priority[i];
1651
1652       if (prop == MFONT_SIZE)
1653         keys[i] = Msize;
1654       else if (prop == MFONT_ADSTYLE)
1655         keys[i] = Madstyle;
1656       else if (prop == MFONT_FAMILY)
1657         keys[i] = Mfamily;
1658       else if (prop == MFONT_WEIGHT)
1659         keys[i] = Mweight;
1660       else if (prop == MFONT_STYLE)
1661         keys[i] = Mstyle;
1662       else if (prop == MFONT_STRETCH)
1663         keys[i] = Mstretch;
1664       else
1665         keys[i] = Mfoundry;
1666     }
1667   return keys;
1668 }
1669
1670 /*=*/
1671
1672 /***en
1673     @brief Set the font selection priority.
1674
1675     The mfont_set_selection_priority () function sets font selection
1676     priority according to $KEYS, which is an array of six symbols.
1677     Each element must be one of the below.  No two elements must be
1678     the same.
1679
1680         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1681         @c Madstyle, @c Msize.
1682
1683     See the documentation of the function mfont_selection_priority ()
1684     for details.  */
1685 /***ja
1686     @brief ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë.
1687
1688     ´Ø¿ô mfont_set_selection_priority () ¤Ï¡¢6¤Ä¤Î¥·¥ó¥Ü¥ë¤ÎÇÛÎó $KEYS 
1689     ¤Ë¤·¤¿¤¬¤Ã¤Æ¥Õ¥©¥ó¥ÈÁªÂòÍ¥ÀèÅÙ¤òÀßÄꤹ¤ë¡£³ÆÍ×ÁǤϰʲ¼¤Î¤¦¤Á¤Î¤É¤ì
1690     ¤«¤Ç¤¢¤ê¡¢Á´¤Æ°Û¤Ê¤Ã¤Æ¤¤¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£
1691
1692         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1693         @c Madstyle, @c Msize.
1694
1695     ¾ÜºÙ¤Ï´Ø¿ô mfont_selection_priority () ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
1696      */
1697
1698 int
1699 mfont_set_selection_priority (MSymbol *keys)
1700 {
1701   int priority[FONT_SCORE_PRIORITY_SIZE];
1702   int i, j;
1703
1704   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1705     {
1706       enum MFontProperty prop;
1707
1708       if (*keys == Msize)
1709         prop = MFONT_SIZE;
1710       else if (*keys == Madstyle)
1711         prop = MFONT_ADSTYLE;
1712       else if (*keys == Mfamily)
1713         prop = MFONT_FAMILY;
1714       else if (*keys == Mweight)
1715         prop = MFONT_WEIGHT;
1716       else if (*keys == Mstyle)
1717         prop = MFONT_STYLE;
1718       else if (*keys == Mstretch)
1719         prop = MFONT_STRETCH;
1720       else if (*keys == Mfoundry)
1721         prop = MFONT_FOUNDRY;
1722       else
1723         /* Invalid element.  */
1724         return -1;
1725       for (j = 0; j < i; j++)
1726         if (priority[j] == prop)
1727           /* Duplicated element.  */
1728           return -1;
1729       priority[i] = prop;
1730     }
1731   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1732     font_score_priority[i] = priority[i];
1733   return 0;
1734 }
1735
1736 /*=*/
1737
1738 /***en
1739     @brief Find a font.
1740
1741     The mfont_find () function returns a pointer to the available font
1742     that matches best the specification $SPEC on frame $FRAME.
1743
1744     $SCORE, if not NULL, must point to a place to store the score
1745     value that indicates how well the found font matches to $SPEC.  The
1746     smaller score means a better match.  */
1747 /***ja
1748     @brief ¥Õ¥©¥ó¥È¤òõ¤¹.
1749
1750     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1751     ¤È¤â¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  
1752
1753     $SCORE ¤Ï NULL ¤Ç¤¢¤ë¤«¡¢¸«¤Ä¤«¤Ã¤¿¥Õ¥©¥ó¥È¤¬ $SPEC ¤Ë¤É¤ì¤Û¤É¹ç¤Ã
1754     ¤Æ¤¤¤ë¤«¤ò¼¨¤¹¥¹¥³¥¢¤òÊݸ¤¹¤ë¾ì½ê¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¥¹¥³¥¢¤¬¾®¤µ
1755     ¤¤¤Û¤ÉÎɤ¯¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
1756     */
1757
1758 MFont *
1759 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1760 {
1761   MFont spec_copy;
1762   MRealizedFont *rfont;
1763
1764   MFONT_INIT (&spec_copy);
1765   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1766
1767   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1768   if (!rfont)
1769     return NULL;
1770   if (score)
1771     *score = rfont->score;
1772   return &rfont->font;
1773 }
1774
1775 /*=*/
1776 /***en
1777     @brief Set encoding of a font.
1778
1779     The mfont_set_encoding () function sets the encoding information
1780     of font $FONT.
1781
1782     $ENCODING_NAME is a symbol representing a charset that has the
1783     same encoding as the font.
1784
1785     $REPERTORY_NAME is @c Mnil or a symbol representing a charset that
1786     has the same repertory as the font.  If it is @c Mnil, whether a
1787     specific character is supported by the font is asked to each font
1788     driver.
1789
1790     @return
1791     If the operation was successful, this function returns 0.
1792     Otherwise it returns -1 and assigns an error code to the external
1793     variable #merror_code.  */
1794 /***ja
1795     @brief ¥Õ¥©¥ó¥È¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÀßÄꤹ¤ë.
1796
1797     ´Ø¿ô mfont_set_encoding () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¾ðÊó
1798     ¤òÀßÄꤹ¤ë¡£
1799
1800     $ENCODING_NAME ¤Ï¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò
1801     ¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£
1802
1803     $REPERTORY_NAME ¤Ï @c Mnil ¤Ç¤¢¤ë¤«¡¢¥Õ¥©¥ó¥È¤ÈƱ¤¸¥¨¥ó¥³¡¼¥Ç¥£¥ó
1804     ¥°¤ò»ý¤Äʸ»ú¥»¥Ã¥È¤ò¼¨¤¹¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£@c Mnil ¤Ç¤¢¤ì¤Ð¡¢¸Ä¡¹¤Îʸ
1805     »ú¤¬¤½¤Î¥Õ¥©¥ó¥È¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢¥Õ¥©¥ó¥È¥É¥é¥¤¥Ð¤Ë
1806     Ì䤤¹ç¤ï¤»¤ë¡£
1807
1808     @return
1809     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï 0 ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð -1 ¤òÊÖ¤·¡¢³°
1810     ÉôÊÑ¿ô #merror_code ¤Ë¥¨¥é¡¼¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1811
1812
1813 int
1814 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1815 {
1816   MCharset *encoding_charset = MCHARSET (encoding_name);
1817   MCharset *repertory_charset;
1818   MSymbol registry;
1819   MFontEncoding *encoding;
1820   MPlist *plist;
1821
1822   if (! encoding_charset)
1823     MERROR (MERROR_FONT, -1);
1824   if (repertory_name != Mnil)
1825     {
1826       repertory_charset = MCHARSET (repertory_name);
1827       if (! repertory_charset)
1828         MERROR (MERROR_FONT, -1);
1829     }
1830   else
1831     repertory_charset = NULL;
1832
1833   MSTRUCT_CALLOC (encoding, MERROR_FONT);
1834   encoding->spec = *font;
1835   encoding->encoding_name = encoding_name;
1836   encoding->encoding_charset = encoding_charset;
1837   encoding->repertory_name = repertory_name;
1838   encoding->repertory_charset = repertory_charset;
1839   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1840   if (registry == Mnil)
1841     registry = Mt;
1842   if (! font_encoding_list)
1843     load_font_encoding_table ();
1844   mplist_push (font_encoding_list, registry, encoding);
1845   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
1846     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
1847                   sizeof (MFont)))
1848       {
1849         mplist_pop (plist);
1850         break;
1851       }
1852   return 0;
1853 }
1854
1855 /*** @} */
1856
1857 /*** @addtogroup m17nDebug */
1858 /*=*/
1859 /*** @{ */
1860
1861 /***en
1862     @brief Dump a font.
1863
1864     The mdebug_dump_font () function prints font $FONT in a human readable
1865     way to the stderr.
1866
1867     @return
1868     This function returns $FONT.  */
1869 /***ja
1870     @brief ¥Õ¥©¥ó¥È¤ò¥À¥ó¥×¤¹¤ë.
1871
1872     ´Ø¿ô mdebug_dump_font () ¤Ï¥Õ¥©¥ó¥È $FONT ¤ò stderr ¤Ë¿Í´Ö¤Ë²ÄÆɤÊ
1873     ·Á¤Ç°õºþ¤¹¤ë¡£
1874
1875     @return
1876     ¤³¤Î´Ø¿ô¤Ï $FONT ¤òÊÖ¤¹¡£  */
1877
1878 MFont *
1879 mdebug_dump_font (MFont *font)
1880 {
1881   char *name = mwin__build_font_name (font);
1882
1883   fprintf (stderr, "%s", name);
1884   free (name);
1885   return font;
1886 }
1887
1888 /*** @} */
1889
1890 /*
1891   Local Variables:
1892   coding: euc-japan
1893   End:
1894 */