(make_charset): Set charset->fully_loaded and
[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 accoding
105     to the configuration of the m17n librayr and the environment
106     variable @c M17NDIR.  See the documentation of the variable for
107     details.
108
109     The family name of a FreeType font corresponds to the family
110     property.  Style names of FreeType fonts correspond to the weight,
111     style, and stretch properties as below.
112
113 @verbatim
114     style name          weight  style   stretch
115     ----------          ------  -----   -------
116     Regular             medium  r       normal
117     Italic              medium  i       normal
118     Bold                bold    r       normal
119     Bold Italic         bold    i       normal
120     Narrow              medium  r       condensed
121     Narrow Italic       medium  i       condensed
122     Narrow Bold         bold    r       condensed
123     Narrow Bold Italic  bold    i       condensed
124     Black               black   r       normal
125     Black Italic        black   i       normal
126     Oblique             medium  o       normal
127     BoldOblique         bold    o       normal
128 @endverbatim
129
130     Style names not listed in the above table are treated as
131     "Regular".
132
133     Combination of a platform ID and an encoding ID corresponds to the
134     registry property.  For example, if a font has the combination (1
135     1), the registry property is 1-1.  Some frequent combinations have
136     a predefined registry property as below.
137
138 @verbatim
139     platform ID         encoding ID     registry property
140     -----------         -----------     -----------------
141     0                   3               unicode-bmp
142     0                   4               unicode-full
143     1                   0               apple-roman
144     3                   1               unicode-bmp
145     3                   1               unicode-full
146 @endverbatim
147
148     Thus, a font that has two combinations (1 0) and (3 1) corresponds
149     to four font objects whose registries are 1-0, apple-roman, 3-1,
150     and unicode-bmp.
151
152     <li> OpenType fonts 
153
154     The m17n library, if configured to use both the FreeType library
155     and the OTF library, supports any OpenType fonts.  The list of
156     actually available fonts is created in the same way as in the case
157     of FreeType fonts.  If a fontset instructs to use an OpenType font
158     via an FLT (Font Layout Table), and the FLT has an OTF-related
159     command (e.g. otf:deva), the OTF library converts a character
160     sequence to a glyph code sequence according to the OpenType layout
161     tables of the font, and the FreeType library gives a bitmap image
162     for each glyph.
163
164     </ul>
165
166   */
167
168 /***ja
169     @addtogroup m17nFont
170     @brief ¥Õ¥©¥ó¥È¤È¤Ï¡¢¸Ä¡¹¤Î¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È¤ËÂбþ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë
171
172     m17n-win API ¤Ë¤ª¤±¤ë @e ¥Õ¥©¥ó¥È ¤È¤Ï¡¢@c MFont ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È
173     ¤Ç¤¢¤ê¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à°Í¸¤Î @e ¥·¥¹¥Æ¥à¥Õ¥©¥ó¥È ¤È°ìÂаì¤ËÂÐ
174     ±þÉÕ¤±¤é¤ì¤ë¡£¥Õ¥©¥ó¥È¤Ï¸ÇÄê¸Ä¿ô¤Î @e ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ ¤ò»ý¤Ä¡£
175     ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Ï¥­¡¼¤ÈÃͤ«¤é¤Ê¤ë¡£¥­¡¼¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢
176
177     @c Mfoundry, @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
178     @c Madstyle, @c Mregistry, @c Msize, @c Mresolution
179
180     ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£¥­¡¼¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¡¢
181     ÃͤÏÀ°¿ô¤Ç¤¢¤ë¡£¥­¡¼¤¬¤½¤ì°Ê³°¤Î¾ì¹ç¡¢Ãͤϥ·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£¡Ö¥Õ¥©¥ó
182     ¥È F ¤Î¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¥­¡¼¤¬ @c Mxxx ¤Ç¤¢¤ë¤â¤Î¡×¤Î¤³¤È¤ò
183     ´Êñ¤Ë¡ÖF ¤Î xxx ¥×¥í¥Ñ¥Æ¥£¡×¤È¸Æ¤Ö¤³¤È¤¬¤¢¤ë¡£
184
185     Family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢times, helvetica Åù¤Î¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê¡¼¤ò
186     É½¤ï¤¹¡£
187
188     Weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, bold Åù¤ÎÂÀ¤µ¤Ë´Ø¤¹¤ë¾ðÊó¤òɽ¤ï¤¹¡£
189
190     Style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, italic Åù¤Î·¹¤­¤Ë´Ø¤¹¤ë¾ðÊó¤òɽ¤ï
191     ¤¹¡£
192
193     Stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢normal, semicondensed Åù¤Îʸ»úÉý¤Ë´Ø¤¹¤ë
194     ¾ðÊó¤òɽ¤ï¤¹¡£
195
196     Adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢serif, sans-serif Åù¤ÎÃê¾ÝŪ¤Ê¥Õ¥©¥ó¥È
197     ¥Õ¥¡¥ß¥ê¡¼¤òɽ¤ï¤¹¡£
198
199     Registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢iso10646, iso8895-1 ¤Î¥ì¥¸¥¹¥È¥ê¤òɽ¤ï
200     ¤¹¡£
201
202     Size ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢¥Õ¥©¥ó¥È¤Î¥Ç¥¶¥¤¥ó¥µ¥¤¥º¤òɽ¤ï¤¹¡£Ã±°Ì
203     ¤Ï 1/10 ¥Ý¥¤¥ó¥È¤Ç¤¢¤ë¡£
204
205     Resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤϡ¢ÁÛÄꤵ¤ì¤Æ¤¤¤ë¥Ç¥Ð¥¤¥¹¤Î²òÁüÅÙ¤ò É½¤ï
206     ¤¹¡£Ã±°Ì¤Ï dots per inch (dpi) ¤Ç¤¢¤ë¡£  */
207
208 /*=*/
209
210 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
211 /*** @addtogroup m17nInternal
212      @{ */
213
214 #include "config.h"
215
216 #include <stdio.h>
217 #include <stdlib.h>
218 #include <string.h>
219
220 #include "m17n-gui.h"
221 #include "m17n-misc.h"
222 #include "internal.h"
223 #include "mtext.h"
224 #include "symbol.h"
225 #include "plist.h"
226 #include "charset.h"
227 #include "internal-gui.h"
228 #include "font.h"
229 #include "face.h"
230
231 MFontDriver *mfont__driver_list[MFONT_TYPE_MAX];
232
233 /** Indices to font properties sorted by their priority.  */
234 static int font_score_priority[] =
235   { MFONT_SIZE,
236     MFONT_ADSTYLE,
237     MFONT_FAMILY,
238     MFONT_WEIGHT,
239     MFONT_STYLE,
240     MFONT_STRETCH,
241     MFONT_FOUNDRY
242   };
243
244 #define FONT_SCORE_PRIORITY_SIZE        \
245   (sizeof font_score_priority / sizeof font_score_priority[0])
246
247 /* Indexed by a font property MFONT_XXX, and the value is how many
248    bits to shift the difference of property values.  */
249 static int font_score_shift_bits[MFONT_PROPERTY_MAX];
250
251 /** Predefined symbols for each font property.  The order is important
252     because the function score_font () decides how well a font matches
253     with a spec by checking how close the index is.  */
254
255 static char *common_foundry[] =
256   { "misc",
257     "adobe" };
258 static char *common_family[] =
259   { "fixed",
260     "courier",
261     "helvetica",
262     "times" };
263 static char *common_weight[] =
264   { "ultralight",
265     "extralight",
266     "light",
267     "demilight",
268     "book",
269     "normal",
270     "medium",
271     "regular",
272     "demibold",
273     "bold",
274     "extrabold",
275     "ultrabold",
276     "black" };
277 static char *common_style[] =
278   { "o",
279     "i",
280     "r",
281     "ri",
282     "ro" };
283 static char *common_stretch[] =
284   { "condensed",
285     "narrow",
286     "semicondensed",
287     "normal",
288     "semiexpanded",
289     "expanded" };
290 static char *common_adstyle[] =
291   { "serif",
292     "",
293     "sans" };
294 static char *common_registry[] =
295   { "iso8859-1" };
296
297 /* Table containing all the data above.  */
298
299 struct MFontCommonNames
300 {
301   int num;
302   char **names;
303 };
304
305 static struct MFontCommonNames font_common_names[] =
306   {
307     { sizeof (common_foundry) / sizeof (char *), common_foundry},
308     { sizeof (common_family) / sizeof (char *), common_family},
309     { sizeof (common_weight) / sizeof (char *), common_weight},
310     { sizeof (common_style) / sizeof (char *), common_style},
311     { sizeof (common_stretch) / sizeof (char *), common_stretch},
312     { sizeof (common_adstyle) / sizeof (char *), common_adstyle},
313     { sizeof (common_registry) / sizeof (char *), common_registry}
314   };
315
316
317 /** Table of available font property names.  */
318
319 MFontPropertyTable mfont__property_table[MFONT_REGISTRY + 1];
320
321
322 /** Return the numeric value of SYMBOL as the Nth font property.  */
323
324 #define FONT_PROPERTY_NUMERIC(symbol, n)        \
325   ((symbol) == Mnil                             \
326    ? 0                                          \
327    : ((int) msymbol_get ((symbol), mfont__property_table[(n)].property)))
328
329
330 /** Set the numeric value of SYMBOL as the Nth font property to NUMERIC.  */
331
332 #define SET_FONT_PROPERTY_NUMERIC(symbol, n, numeric)           \
333   msymbol_put((symbol), mfont__property_table[(n)].property,    \
334               (void *) (numeric))
335
336 static char *
337 gen_font_name (char *buf, MFont *font)
338 {
339   char size[16];
340   int i;
341
342   buf[0] = '\0';
343   for (i = 0; i <= MFONT_REGISTRY; i++)
344     if (FONT_PROPERTY (font, i) != Mnil)
345       {
346         char *name = msymbol_name (FONT_PROPERTY (font, i));
347
348         if (name[0])
349           {
350             if (i > 0)
351               strcat (buf, ",");
352             strcat (buf, name);
353           }
354       }
355   sprintf (size, ",%d", font->property[MFONT_SIZE] / 10);
356   strcat (buf, size);
357   return buf;
358 }
359
360
361 \f
362 /* Font selector.  */
363
364 struct MFontEncoding {
365   MFont spec;
366   MSymbol encoding_name;
367   MCharset *encoding_charset;
368   MSymbol repertory_name;
369   MCharset *repertory_charset;
370 };
371
372 static MPlist *font_encoding_list;
373 static MFontEncoding default_encoding;
374
375 /** Load font encoding table from the data <font encoding>.
376     The data has this form:
377         (FONT-SPEC ENCODING) ...
378     where FONT-SPEC has this form:
379         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
380     All elements are symbols.  */
381
382 static int
383 load_font_encoding_table ()
384 {
385   MDatabase *mdb;
386   MPlist *encoding_list, *plist, *pl, *elt;
387
388   font_encoding_list = pl = mplist ();
389
390   mdb = mdatabase_find (Mfont, msymbol ("encoding"), Mnil, Mnil);
391   if (! mdb
392       || ! (encoding_list = (MPlist *) mdatabase_load (mdb)))
393     MERROR (MERROR_FONT, -1);
394
395   MPLIST_DO (plist, encoding_list)
396     {
397       MFontEncoding *encoding;
398       MSymbol registry;
399
400       MSTRUCT_CALLOC (encoding, MERROR_FONT);
401
402       if (! MPLIST_PLIST_P (plist)
403           || (elt = MPLIST_PLIST (plist), mplist_length (elt) < 2)
404           || ! MPLIST_PLIST_P (elt))
405         MWARNING (MERROR_FONT);
406       registry = mfont__set_spec_from_plist (&encoding->spec,
407                                              MPLIST_PLIST (elt));
408       elt = MPLIST_NEXT (elt);
409       if (! MPLIST_SYMBOL_P (elt))
410         MWARNING (MERROR_FONT);
411       encoding->encoding_name = MPLIST_SYMBOL (elt);
412       elt = MPLIST_NEXT (elt);
413       if (MPLIST_TAIL_P (elt))
414         encoding->repertory_name = encoding->encoding_name;
415       else if (! MPLIST_SYMBOL_P (elt))
416         MWARNING (MERROR_FONT);
417       else
418         encoding->repertory_name = MPLIST_SYMBOL (elt);
419
420       if (registry == Mnil)
421         registry = Mt;
422       pl = mplist_add (pl, registry, encoding);
423       continue;
424
425     warning:
426       free (encoding);
427     }
428
429   M17N_OBJECT_UNREF (encoding_list);
430   return 0;
431 }
432
433 typedef struct {
434   MFont spec;
435   int resize;
436 } MFontResize;
437
438 static MPlist *font_resize_list;
439
440 /** Load font size table from the data <font size>.
441     The data has this form:
442         (FONT-SPEC RESIZE-FACTOR) ...
443     where FONT-SPEC has this form:
444         ([FOUNDRY FAMILY [WEIGHT [STYLE [STRETCH [ADSTYLE]]]]] REGISTRY)
445     All elements of FONT-SPEC are symbols.  */
446
447 static int
448 load_font_resize_table ()
449 {
450   MDatabase *mdb;
451   MPlist *size_adjust_list, *plist, *pl, *elt;
452
453   font_resize_list = pl = mplist ();
454
455   mdb = mdatabase_find (Mfont, msymbol ("resize"), Mnil, Mnil);
456   if (! mdb)
457     return -1;
458   if (! (size_adjust_list = (MPlist *) mdatabase_load (mdb)))
459     MERROR (MERROR_FONT, -1);
460
461   MPLIST_DO (plist, size_adjust_list)
462     {
463       MFontResize *resize;
464       MSymbol registry;
465
466       MSTRUCT_CALLOC (resize, MERROR_FONT);
467
468       if (! MPLIST_PLIST_P (plist)
469           || (elt = MPLIST_PLIST (plist), mplist_length (elt) != 2)
470           || ! MPLIST_PLIST_P (elt))
471         MWARNING (MERROR_FONT);
472       registry = mfont__set_spec_from_plist (&resize->spec,
473                                              MPLIST_PLIST (elt));
474       elt = MPLIST_NEXT (elt);
475       if (! MPLIST_INTEGER_P (elt))
476         MWARNING (MERROR_FONT);
477       resize->resize = MPLIST_INTEGER (elt);
478
479       if (registry == Mnil)
480         registry = Mt;
481       pl = mplist_add (pl, registry, resize);
482       continue;
483
484     warning:
485       free (resize);
486     }
487
488   M17N_OBJECT_UNREF (size_adjust_list);
489   return 0;
490 }
491
492 /** Return a font encoding (and repertory) of FONT.  */
493
494 static MFontEncoding *
495 find_encoding (MFont *font)
496 {
497   MSymbol registry = FONT_PROPERTY (font, MFONT_REGISTRY);
498   MFontEncoding *encoding = NULL;
499   MPlist *plist;
500
501   if (! font_encoding_list)
502     load_font_encoding_table ();
503   if (! MPLIST_TAIL_P (font_encoding_list))
504     while (1)
505       {
506         plist = font_encoding_list;
507         while (registry ? (plist = mplist_find_by_key (plist, registry))
508                : plist)
509           {
510             encoding = (MFontEncoding *) MPLIST_VAL (plist);
511             if (mfont__match_p (font, &encoding->spec, MFONT_ADSTYLE))
512               {
513                 if (! encoding->encoding_charset)
514                   encoding->encoding_charset
515                     = MCHARSET (encoding->encoding_name);
516                 if (! encoding->encoding_charset)
517                   {
518                     mplist_pop (plist);
519                     continue;
520                   }
521                 if (encoding->repertory_name == encoding->encoding_name)
522                   encoding->repertory_charset = encoding->encoding_charset;
523                 else if (encoding->repertory_name != Mnil)
524                   {
525                     encoding->repertory_charset
526                       = MCHARSET (encoding->repertory_name);
527                     if (! encoding->repertory_charset)
528                       {
529                         mplist_pop (plist);
530                         continue;
531                       }
532                   }
533                 return encoding;
534               }
535             else
536               plist = MPLIST_NEXT (plist);
537           }
538         if (registry == Mnil || registry == Mt)
539           break;
540         registry = Mt;
541       }
542   return &default_encoding;
543 }
544
545
546 \f
547 /* Internal API */
548
549 int
550 mfont__init ()
551 {
552   int i, shift;
553
554   Mfoundry = msymbol ("foundry");
555   mfont__property_table[MFONT_FOUNDRY].property = Mfoundry;
556   Mfamily = msymbol ("family");
557   mfont__property_table[MFONT_FAMILY].property = Mfamily;
558   Mweight = msymbol ("weight");
559   mfont__property_table[MFONT_WEIGHT].property = Mweight;
560   Mstyle = msymbol ("style");
561   mfont__property_table[MFONT_STYLE].property = Mstyle;
562   Mstretch = msymbol ("stretch");
563   mfont__property_table[MFONT_STRETCH].property = Mstretch;
564   Madstyle = msymbol ("adstyle");
565   mfont__property_table[MFONT_ADSTYLE].property = Madstyle;
566   Mregistry = msymbol ("registry");
567   mfont__property_table[MFONT_REGISTRY].property = Mregistry;
568
569   Msize = msymbol ("size");
570   Mresolution = msymbol ("resolution");
571
572   /* The first entry of each mfont__property_table must be Mnil so
573      that actual properties get positive numeric numbers.  */
574   for (i = 0; i <= MFONT_REGISTRY; i++)
575     {
576       MLIST_INIT1 (&mfont__property_table[i], names, 8);
577       MLIST_APPEND1 (&mfont__property_table[i], names, Mnil, MERROR_FONT);
578     }
579
580   /* Register predefined font property names.  */
581   for (i = 0; i <= MFONT_REGISTRY; i++)
582     {
583       int j;
584
585       for (j = 0; j < font_common_names[i].num; j++)
586         {
587           MSymbol sym = msymbol (font_common_names[i].names[j]);
588
589           if (sym == Mnil)
590             return -1;
591           if (msymbol_put(sym, mfont__property_table[i].property,
592                           (void *) (j + 1)) < 0)
593             return -1;
594           MLIST_APPEND1 (&mfont__property_table[i], names, sym, MERROR_FONT);
595         }
596     }
597
598   memset (mfont__driver_list, 0, sizeof mfont__driver_list);
599
600   /* Here, SHIFT starts from 1, not 0.  This is because the lowest bit
601      of a score is a flag for a scalable font (see the documentation
602      of mfont_score).  */
603   i = FONT_SCORE_PRIORITY_SIZE - 1;
604   for (shift = 1; i >= 0; i--)
605     {
606       font_score_shift_bits[font_score_priority[i]] = shift;
607       if (font_score_priority[i] == MFONT_SIZE)
608         shift += 16;
609       else
610         shift += 2;
611     }
612
613   MFONT_INIT (&default_encoding.spec);
614   default_encoding.encoding_name = Mnil;
615   default_encoding.encoding_charset = NULL;
616   default_encoding.repertory_name = Mnil;
617   default_encoding.repertory_charset = NULL;
618   {
619     char *path, *buf;
620     int bufsize;
621
622     mfont_freetype_path = mplist ();
623     bufsize = strlen (M17NDIR) + 7;
624     buf = alloca (bufsize);
625     sprintf (buf, "%s/fonts", M17NDIR);
626     mplist_add (mfont_freetype_path, Mstring, strdup (buf));
627     path = getenv ("M17NDIR");
628     if (path)
629       {
630         i = strlen (path) + 7;
631         if (i > bufsize)
632           buf = alloca (i);
633         sprintf (buf, "%s/fonts", path);
634         mplist_push (mfont_freetype_path, Mstring, strdup (buf));
635       }
636   }
637
638 #ifdef HAVE_FREETYPE
639   if (mfont__ft_init () < 0)
640     return -1;
641 #endif /* HAVE_FREETYPE */
642   if (mfont__flt_init () < 0)
643     return -1;
644
645   return 0;
646 }
647
648 void
649 mfont__fini ()
650 {
651   MPlist *plist;
652   int i;
653
654   mfont__flt_fini ();
655 #ifdef HAVE_FREETYPE
656   mfont__ft_fini ();
657 #endif /* HAVE_FREETYPE */
658
659   MPLIST_DO (plist, mfont_freetype_path)
660     free (MPLIST_VAL (plist));
661   M17N_OBJECT_UNREF (mfont_freetype_path);
662
663   if (font_resize_list)
664     {
665       MPLIST_DO (plist, font_resize_list)
666         free (MPLIST_VAL (plist));
667       M17N_OBJECT_UNREF (font_resize_list);
668       font_resize_list = NULL;
669     }
670   if (font_encoding_list)
671     {
672       MPLIST_DO (plist, font_encoding_list)
673         free (MPLIST_VAL (plist));
674       M17N_OBJECT_UNREF (font_encoding_list);
675       font_encoding_list = NULL;
676     }
677   for (i = 0; i <= MFONT_REGISTRY; i++)
678     MLIST_FREE1 (&mfont__property_table[i], names);
679 }
680
681 void
682 mfont__free_realized (MRealizedFont *rfont)
683 {
684   if (rfont->info)
685     M17N_OBJECT_UNREF (rfont->info);
686   free (rfont);
687 }
688
689
690 /* Compare FONT with REQUEST and return how much they differs.  If
691    FONT does not match with SPEC, return -1.  */
692
693 int
694 mfont__score (MFont *font, MFont *spec, MFont *request, int limited_size)
695 {
696   int score = 0;
697   int i = FONT_SCORE_PRIORITY_SIZE;
698
699   while (--i >= 0)
700     {
701       enum MFontProperty prop = font_score_priority[i];
702
703       if (request->property[prop] != 0)
704         {
705           int val = 0;
706
707           if (spec->property[prop] && font->property[prop]
708               && font->property[prop] != spec->property[prop])
709             return -1;
710           if (font->property[prop])
711             val = abs (font->property[prop] - request->property[prop]);
712           if (prop == MFONT_SIZE)
713             {
714               if (font->property[MFONT_RESY] == 0)
715                 /* This is a scalable font.  We prefer a bitmap font
716                    if the size matches exactly.  */
717                 score |= 1;
718               else
719                 score |= (val << font_score_shift_bits[MFONT_SIZE]
720                           | ((limited_size && val > 0) ? 0x400000 : 0));
721             }
722           else
723             score |= (val > 3 ? 3 : val) << font_score_shift_bits[prop];
724         }
725     }
726   return score;
727 }
728
729
730 /** Return 1 iff FONT matches SPEC.  */
731
732 int
733 mfont__match_p (MFont *font, MFont *spec, int prop)
734 {
735   for (; prop >= 0; prop--)
736     if (spec->property[prop] && font->property[prop]
737         && font->property[prop] != spec->property[prop])
738       return 0;
739   return 1;
740 }
741
742
743 void
744 mfont__set_spec_from_face (MFont *spec, MFace *face)
745 {
746   int i;
747
748   for (i = 0; i <= MFONT_ADSTYLE; i++)
749     mfont__set_property (spec, i, face->property[i]);
750   /* The value 1 is "iso8859-1".  */
751   spec->property[MFONT_REGISTRY] = 1;
752   spec->property[MFONT_SIZE] = (int) (face->property[MFACE_SIZE]);
753   spec->property[MFONT_RESY] = 0;
754   spec->property[MFONT_TYPE] = 0;
755 }
756
757
758 extern MSymbol
759 mfont__set_spec_from_plist (MFont *spec, MPlist *plist)
760 {
761   int i;
762   MSymbol spec_list[MFONT_REGISTRY + 1];
763   MSymbol registry;
764
765   MFONT_INIT (spec);
766   memset (spec_list, 0, sizeof spec_list);
767   for (i = 0; ! MPLIST_TAIL_P (plist); i++, plist = MPLIST_NEXT (plist))
768     {
769       if (! MPLIST_SYMBOL_P (plist))
770         MERROR (MERROR_FONT, Mnil);     
771       spec_list[i] = MPLIST_SYMBOL (plist);
772     }
773   registry = spec_list[i - 1];
774   mfont__set_property (spec, MFONT_REGISTRY, registry);
775   for (i -= 2; i >= 0; i--)
776     mfont__set_property (spec, i, spec_list[i]);
777   return registry;
778 }
779
780 MRealizedFont *
781 mfont__select (MFrame *frame, MFont *spec, MFont *request, int limited_size,
782                MSymbol layouter)
783 {
784   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
785   MPlist *realized_font_list;
786   MRealizedFont *best_font[MFONT_TYPE_MAX], *best;
787   int best_index;
788   int i;
789   int mdebug_mask = MDEBUG_FONT;
790
791   if (registry == Mnil)
792     registry = Mt;
793
794   MPLIST_DO (realized_font_list, frame->realized_font_list)
795     {
796       best = MPLIST_VAL (realized_font_list);
797       if (MPLIST_KEY (realized_font_list) == registry
798           && ! memcmp (&best->spec, spec, sizeof (MFont))
799           && ! memcmp (&best->request, request, sizeof (MFont)))
800         {
801           if (best->layouter != layouter)
802             {
803               MRealizedFont *copy;
804
805               MSTRUCT_MALLOC (copy, MERROR_FONT);
806               *copy = *best;
807               copy->layouter = layouter;
808               if (copy->info)
809                 M17N_OBJECT_REF (copy->info);
810               mplist_add (frame->realized_font_list, registry, copy);
811               best = copy;
812             }
813           return best;
814         }
815     }
816
817   MDEBUG_PUSH_TIME ();
818   best = NULL;
819   best_index = -1;
820   for (i = 0; i < MFONT_TYPE_MAX; i++)
821     {
822       MFontDriver *driver = mfont__driver_list[i];
823
824       best_font[i] = (driver
825                       ? (driver->select) (frame, spec, request, limited_size)
826                       : NULL);
827       if (best_font[i]
828           && (best_index < 0
829               || best_font[best_index]->score < best_font[i]->score))
830         best_index = i;
831     }
832   for (i = 0; i < MFONT_TYPE_MAX; i++)
833     {
834       if (i == best_index)
835         best = best_font[i];
836       else if (best_font[i])
837         free (best_font[i]);
838     }
839
840   if (mdebug__flag & mdebug_mask)
841     {
842       char buf1[256], buf2[256];
843       MFont font = *spec;
844
845       for (i = 0; i < MFONT_PROPERTY_MAX; i++)
846         if (! font.property[i])
847           font.property[i] = request->property[i];
848       gen_font_name (buf2, &font);
849
850       if (best)
851         MDEBUG_PRINT_TIME ("FONT", 
852                            (stderr, " to select <%s> from <%s>.",
853                             gen_font_name (buf1, &best->font),
854                             buf2));
855       else
856         MDEBUG_PRINT_TIME ("FONT", (stderr, " to fail to find <%s>.", buf2));
857       MDEBUG_POP_TIME ();
858     }
859
860   if (! best)
861     return NULL;
862   best->layouter = layouter;
863   mplist_add (frame->realized_font_list, registry, best);
864   return best;
865 }
866
867
868 /** Open a font specified in RFONT.  Return 0 if successfully
869     opened, otherwise return -1.  */
870
871 int
872 mfont__open (MRealizedFont *rfont)
873 {
874   MPlist *realized_font_list;
875   MSymbol registry = FONT_PROPERTY (&rfont->font, MFONT_REGISTRY);
876
877   if (rfont->status)
878     mdebug_hook ();
879
880   MPLIST_DO (realized_font_list, rfont->frame->realized_font_list)
881     {
882       MRealizedFont *this_rfont = MPLIST_VAL (realized_font_list);
883
884       if (this_rfont->status != 0
885           && MPLIST_KEY (realized_font_list) == registry
886           && ! memcmp (&this_rfont->font, &rfont->font, sizeof (MFont)))
887         {
888           if (rfont->info)
889             M17N_OBJECT_UNREF (rfont->info);
890           rfont->info = this_rfont->info;
891           M17N_OBJECT_REF (this_rfont->info);
892           rfont->status = this_rfont->status;
893           return (this_rfont->status > 0 ? 0 : -1);
894         }
895     }
896
897   return (rfont->driver->open) (rfont);
898 }
899
900 void
901 mfont__close (MRealizedFont *rfont)
902 {
903   (rfont->driver->close) (rfont);
904 }
905
906 void
907 mfont__resize (MFont *spec, MFont *request)
908 {
909   MSymbol registry = FONT_PROPERTY (spec, MFONT_REGISTRY);
910   MFontResize *resize;
911   MPlist *plist;
912
913   if (! font_resize_list)
914     load_font_resize_table ();
915   if (! MPLIST_TAIL_P (font_resize_list))
916     while (1)
917       {
918         plist = font_resize_list;
919         while (registry ? (plist = mplist_find_by_key (plist, registry))
920                : plist)
921           {
922             resize = (MFontResize *) MPLIST_VAL (plist);
923             if (mfont__match_p (spec, &resize->spec, MFONT_ADSTYLE))
924               {
925                 request->property[MFONT_SIZE]
926                   = request->property[MFONT_SIZE] * resize->resize / 100;
927                 return;
928               }
929             plist = MPLIST_NEXT (plist);
930           }
931         if (registry == Mt)
932           break;
933         registry = Mt;
934       }
935 }
936
937 /* Return 1 if C is encodable, 0, if C is not encodable, -1 if it
938    can't be decided now.  */
939
940 int
941 mfont__encodable_p (MRealizedFont *rfont, MSymbol layouter_name, int c)
942 {
943   MFontEncoding *encoding;
944
945   if (layouter_name != Mnil)
946     return (mfont__flt_encode_char (layouter_name, c)
947             != MCHAR_INVALID_CODE);
948   if (! rfont->encoding)
949     rfont->encoding = find_encoding (&rfont->spec);
950   encoding = rfont->encoding;
951   if (! encoding->repertory_charset)
952     return -1;
953   return (ENCODE_CHAR (encoding->repertory_charset, c) != MCHAR_INVALID_CODE);
954 }
955
956 unsigned
957 mfont__encode_char (MRealizedFont *rfont, int c)
958 {
959   MFontEncoding *encoding;
960   unsigned code;
961
962   if (rfont->layouter != Mnil)
963     return mfont__flt_encode_char (rfont->layouter, c);
964   if (! rfont->encoding)
965     rfont->encoding = find_encoding (&rfont->font);
966   encoding = rfont->encoding;
967   if (! encoding->encoding_charset)
968     return MCHAR_INVALID_CODE;
969   code = ENCODE_CHAR (encoding->encoding_charset, c);
970   if (code == MCHAR_INVALID_CODE)
971     return MCHAR_INVALID_CODE;
972   if (! encoding->repertory_charset)
973     return (rfont->driver->encode_char) (rfont, c, code);
974   if (ENCODE_CHAR (encoding->repertory_charset, c) == MCHAR_INVALID_CODE)
975     return MCHAR_INVALID_CODE;
976   return code;
977 }
978
979 void
980 mfont__get_metric (MGlyphString *gstring, int from, int to)
981 {
982   MGlyph *from_g = MGLYPH (from), *to_g = MGLYPH (to), *g;
983   MRealizedFont *rfont = from_g->rface->rfont;
984
985   for (g = from_g; g != to_g; g++)
986     if (g->rface->rfont != rfont)
987       {
988         int idx = GLYPH_INDEX (g);
989
990         (rfont->driver->find_metric) (rfont, gstring, from, idx);
991         from_g = g;
992         rfont = g->rface->rfont;
993         from = idx;
994       }
995   (rfont->driver->find_metric) (rfont, gstring, from, GLYPH_INDEX (g));
996 }
997
998
999 void
1000 mfont__set_property (MFont *font, enum MFontProperty key, MSymbol val)
1001 {
1002   int numeric;
1003
1004   if (val == Mnil)
1005     numeric = 0;
1006   else
1007     {
1008       numeric = FONT_PROPERTY_NUMERIC (val, key);
1009       if (! numeric)
1010         {
1011           numeric = mfont__property_table[key].used;
1012           MLIST_APPEND1 (mfont__property_table + key, names, val, MERROR_FONT);
1013           SET_FONT_PROPERTY_NUMERIC (val, key, numeric);
1014         }
1015     }
1016   font->property[key] = numeric;
1017 }
1018
1019 void
1020 mfont__set_spec (MFont *font, MSymbol *attrs,
1021                  unsigned short size, unsigned short resy)
1022 {
1023   int i;
1024
1025   for (i = 0; i <= MFONT_REGISTRY; i++)
1026     mfont__set_property (font, i, attrs[i]);
1027   font->property[MFONT_SIZE] = size;
1028   font->property[MFONT_RESY] = resy;
1029 }
1030
1031 /*** @} */
1032 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1033
1034 \f
1035
1036 /* External API */
1037
1038 /*** @addtogroup m17nFont */
1039 /*** @{ */
1040 /*=*/
1041
1042 /***en @name Variables: Keys of font property.  */
1043 /***ja @name ÊÑ¿ô: ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ëÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë */
1044 /*** @{ */
1045 /*=*/
1046
1047 /***en
1048     @brief Key of font property specifying foundry.
1049
1050     The variable #Mfoundry is a symbol of name <tt>"foundry"</tt> and
1051     is used as a key of font property and face property.  The property
1052     value must be a symbol whose name is a foundry name of a font.  */
1053
1054 MSymbol Mfoundry;
1055
1056 /***en
1057     @brief Key of font property specifying foundry.
1058
1059     The variable #Mfamily is a symbol of name <tt>"family"</tt> and is
1060     used as a key of font property and face property.  The property
1061     value must be a symbol whose name is a family name of a font.  */ 
1062
1063 /***ja
1064     @brief ¥Õ¥©¥ó¥È¤Î family ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë
1065
1066     ¥·¥ó¥Ü¥ë @c Mfamily ¤Ï <tt>"family"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©¥ó
1067     ¥È¤Î family ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î°ú
1068     ¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£
1069
1070     ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î family ¤ò»ØÄê
1071     ¤¹¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£  */
1072
1073 MSymbol Mfamily;
1074
1075 /***en
1076     @brief Key of font property specifying weight.
1077
1078     The variable #Mweight is a symbol of name <tt>"weight"</tt> and is
1079     used as a key of font property and face property.  The property
1080     value must be a symbol whose name is a weight name of a font (e.g
1081     "medium", "bold").  */ 
1082
1083 /***ja
1084     @brief ¥Õ¥©¥ó¥È¤Î weight ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë
1085
1086     ¥·¥ó¥Ü¥ë @c Mweight ¤Ï <tt>"weight"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©¥ó
1087     ¥È¤Î weight ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î°ú
1088     ¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£
1089
1090     ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î weight ¤ò»ØÄê
1091     ¤¹¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£  */
1092
1093 MSymbol Mweight;
1094
1095 /***en
1096     @brief Key of font property specifying style.
1097
1098     The variable #Mstyle is a symbol of name <tt>"style"</tt> and is
1099     used as a key of font property and face property.  The property
1100     value must be a symbol whose name is a style name of a font (e.g
1101     "r", "i", "o").  */ 
1102
1103 /***ja
1104     @brief ¥Õ¥©¥ó¥È¤Î style ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë
1105
1106     ¥·¥ó¥Ü¥ë @c Mstyle ¤Ï <tt>"style"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©¥ó¥È
1107     ¤Î style ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î°ú¿ô¤È
1108     ¤·¤Æ»È¤ï¤ì¤ë¡£
1109
1110     ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î style ¤ò»ØÄê
1111     ¤¹¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£  */
1112
1113 MSymbol Mstyle;
1114
1115 /***en
1116     @brief Key of font property specifying stretch.
1117
1118     The variable #Mstretch is a symbol of name <tt>"stretch"</tt> and
1119     is used as a key of font property and face property.  The property
1120     value must be a symbol whose name is a stretch name of a font (e.g
1121     "normal", "condensed").  */ 
1122
1123 /***ja
1124     @brief ¥Õ¥©¥ó¥È¤Î stretch ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë
1125
1126     ¥·¥ó¥Ü¥ë @c Mstretch ¤Ï <tt>"stretch"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©
1127     ¥ó¥È¤Î stretch ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î
1128     °ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£
1129
1130     ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î stretch ¤ò»Ø
1131     Äꤹ¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£  */
1132
1133 MSymbol Mstretch;
1134
1135 /***en
1136     @brief Key of font property specifying additional style.
1137
1138     The variable #Madstyle is a symbol of name <tt>"adstyle"</tt> and
1139     is used as a key of font property and face property.  The property
1140     value must be a symbol whose name is an additional style name of a
1141     font (e.g "serif", "", "sans").  */ 
1142
1143 /***ja
1144     @brief ¥Õ¥©¥ó¥È¤Î adstyle ¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¤¿¤á¤Î¥·¥ó¥Ü¥ë
1145
1146     ¥·¥ó¥Ü¥ë @c Madstyle ¤Ï <tt>"adstyle"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©
1147     ¥ó¥È¤Î adstyle ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î
1148     °ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£
1149
1150     ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î adstyle ¤ò»Ø
1151     Äꤹ¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
1152
1153 MSymbol Madstyle;
1154
1155 /***en
1156     @brief Key of font property specifying registry.
1157
1158     The variable #Mregistry is a symbol of name <tt>"registry"</tt>
1159     and is used as a key of font property.  The property value must be
1160     a symbol whose name is a registry name a font registry
1161     (e.g. "iso8859-1", "jisx0208.1983-0").  */ 
1162
1163 /***ja
1164     @brief ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ registry ¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë
1165
1166     ¥·¥ó¥Ü¥ë @c Mregistry ¤Ï <tt>"registry"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©
1167     ¥ó¥È¤Î registry ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë¡¢´Ø¿ô mfont_get_prop () 
1168     ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
1169
1170 MSymbol Mregistry;
1171
1172 /***en
1173     @brief Key of font property specifying size.
1174
1175     The variable #Msize is a symbol of name <tt>"size"</tt> and is
1176     used as a key of font property and face property.  The property
1177     value must be an integer specifying a font design size in the unit
1178     of 1/10 point (on 100 dpi display).  */ 
1179
1180 /***ja
1181     @brief ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ size ¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë
1182
1183     ¥·¥ó¥Ü¥ë @c Msize ¤Ï <tt>"size"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢¥Õ¥©¥ó¥È¤Î size ¥×¥í
1184     ¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë´Ø¿ô mfont_get_prop () ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£
1185
1186     ¤Þ¤¿¤³¤Î¥·¥ó¥Ü¥ë¤Ï¡¢¥Õ¥§¡¼¥¹Á´ÂΤˤª¤±¤ë¥Ç¥Õ¥©¥ë¥È¤Î size ¤ò»ØÄꤹ
1187     ¤ëºÝ¤Ë¡¢¥Õ¥§¡¼¥¹¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
1188
1189 MSymbol Msize;
1190
1191 /***en
1192     @brief Key of font property specifying resolution.
1193
1194     The variable #Mresolution is a symbol of name <tt>"size"</tt> and
1195     is used as a key of font property and face property.  The property
1196     value must be an integer to specifying a font resolution in the
1197     unit of dots per inch (dpi).  */ 
1198
1199 /***ja
1200     @brief ¥Õ¥©¥ó¥È¥×¥í¥Ñ¥Æ¥£ resolution ¤òɽ¤ï¤¹¥·¥ó¥Ü¥ë
1201
1202     ¥·¥ó¥Ü¥ë @c Mresolution ¤Ï <tt>"resolution"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Á¡¢
1203     ¥Õ¥©¥ó¥È¤Î resolution ¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë¤È¤­¤Ë¡¢´Ø¿ô 
1204     mfont_get_prop () ¤Î°ú¿ô¤È¤·¤Æ»È¤ï¤ì¤ë¡£  */
1205
1206 MSymbol Mresolution;
1207
1208 /*=*/
1209 /*** @} */
1210 /*=*/
1211
1212 /***en
1213     @brief List of font files and directories that contain font files.
1214
1215     The variable @c mfont_freetype_path is a plist of FreeType font
1216     files and directories that contain FreeType font files.  Key of
1217     the element is @c Mstring, and the value is a string that
1218     represents a font file or a directory.
1219
1220     The macro M17N_INIT () sets up this variable to contain the
1221     sub-directory "fonts" of the m17n database and the environment
1222     variable "M17NDIR".  The first call of mframe () creates the
1223     internal list of the actually available fonts from this variable.
1224     Thus, an application program, if necessary, must modify the
1225     variable before calling mframe ().  If it is going to add a new
1226     element, value must be a string that can be safely freed.
1227
1228     If the m17n library is not configured to use the FreeType library,
1229     this variable is not used.  */
1230
1231 MPlist *mfont_freetype_path;
1232
1233 /*=*/
1234
1235 /***en
1236     @brief Create a new font.
1237
1238     The mfont () function creates a new font object that has no
1239     property.
1240
1241     @return
1242     This function returns a pointer to the created font object.  */
1243
1244
1245 MFont *
1246 mfont ()
1247 {
1248   MFont *font;
1249
1250   MSTRUCT_CALLOC (font, MERROR_FONT);
1251   return font;
1252 }
1253
1254 /*=*/
1255
1256 /***en
1257     @brief Create a new font from fontname.
1258
1259     The mfont_from_name () function creates a new font object.  The
1260     properties are extracted fontname $NAME.
1261
1262     How to extract properties is window system dependent.  The m17n-X
1263     library parses $NAME as XLFD (X Logical Font Description).
1264
1265     @return
1266     If the operation was successful, this function returns a pointer
1267     to the created font.  Otherwise it returns @c NULL.  */
1268
1269 /***ja
1270     @brief ¥Õ¥©¥ó¥È̾¤«¤é¥Õ¥©¥ó¥È¤òºî¤ë
1271
1272     ´Ø¿ô mfont_from_name () ¤Ï¥Õ¥©¥ó¥È̾ $NAME ¤ò²òÀϤ·¡¢¿·¤·¤¤¥Õ¥©¥ó
1273     ¥È¤òºî¤ë¡£
1274
1275     ¥Õ¥©¥ó¥È̾¤Îʸˡ¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤Ë°Í¸¤¹¤ë¡£m17n-X ¥é¥¤¥Ö¥é¥ê
1276     ¤Î¾ì¹ç¤Ï XLFD (X Logical Font Description) ¤Ë½¾¤¦¡£
1277
1278     @return
1279     ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mfont_from_name () ¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥Õ¥©¥ó¥È¤Ø¤Î
1280     ¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$NAME ¤Î²òÀϤ˼ºÇÔ¤·¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤¹¡£  */
1281
1282 MFont *
1283 mfont_from_name (char *name)
1284 {
1285   MFont template, *font;
1286
1287   if (mwin__parse_font_name (name, &template) < 0)
1288     return NULL;
1289   MSTRUCT_CALLOC (font, MERROR_FONT);
1290   *font = template;
1291   return font;
1292 }
1293
1294 /*=*/
1295
1296 /***en
1297     @brief Return a copy of a font.
1298
1299     The mfont_copy () function returns a new copy of $FONT.  */
1300
1301 MFont *
1302 mfont_copy (MFont *font)
1303 {
1304   MFont *copy;
1305
1306   MSTRUCT_MALLOC (copy, MERROR_FONT);
1307   *copy = *font;
1308   return copy;
1309 }
1310
1311 /*=*/
1312
1313 /***en
1314     @brief Create a fontname from a font.
1315
1316     The mfont_name () function creates a fontname string created from
1317     $FONT.
1318
1319     The syntax of fontname is window system dependent.  The m17n-X
1320     library returns a fontname conforming to XLFD (X Logical Font
1321     Description).
1322
1323     @return
1324     This function returns the created fontname string, which is not freed
1325     unless the user explicitly does so by free ().  */
1326
1327 char *
1328 mfont_name (MFont *font)
1329 {
1330   return mwin__build_font_name (font);
1331 }
1332
1333 /*=*/
1334
1335 /***en
1336     @brief Get a property value of a font.
1337
1338     The mfont_get_prop () function gets the value of $KEY property of
1339     $FONT.  $KEY must be one of the following symbols:
1340
1341         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1342         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1343
1344     @return
1345     If $KEY is @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch, @c
1346     Madstyle, or @c Mregistry, this function returns the
1347     corresponding value as a symbol.  If the font does not have $KEY
1348     property, it returns @c Mnil.
1349
1350     If $KEY is @c Msize or @c Mresolution, this function returns the
1351     corresponding value as an integer.  If the font does not have $KEY
1352     property, it returns 0.
1353
1354     If $KEY is something else, it returns @c NULL and assigns an error
1355     code to the external variable @c merror_code.  */
1356
1357 /***ja
1358     @brief ¥Õ¥©¥ó¥È¤Î¥×¥í¥Ñ¥Æ¥£ÃͤòÆÀ¤ë
1359
1360     ´Ø¿ô mfont_get_prop () ¤Ï¥Õ¥©¥ó¥È $FONT ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¤¦¤Á¡¢¥­¡¼¤¬ 
1361     $KEY ¤Ç¤¢¤ë¤â¤Î¤ÎÃͤòÊÖ¤¹¡£$KEY ¤Ï°Ê²¼¤Î¥·¥ó¥Ü¥ë¤Î¤¤¤º¤ì¤«¤Ç¤Ê¤±¤ì
1362     ¤Ð¤Ê¤é¤Ê¤¤¡£
1363
1364         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1365         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1366
1367     @return
1368     ¤â¤· $KEY ¤¬ @c Msize ¤¢¤ë¤¤¤Ï @c Mresolution ¤Î¾ì¹ç¡¢
1369     mfont_get_prop () ¤ÏÀ°¿ô¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£¥¨¥é¡¼
1370     ¤¬¸¡½Ð¤µ¤ì¤¿¾ì¹ç¤Ï @c NULL ¤òÊÖ¤·¡¢³°ÉôÊÑ¿ô @c merror_code ¤Ë¥¨¥é¡¼
1371     ¥³¡¼¥É¤òÀßÄꤹ¤ë¡£  */
1372
1373 void *
1374 mfont_get_prop (MFont *font, MSymbol key)
1375 {
1376   if (key == Mfoundry)
1377     return (void *) FONT_PROPERTY (font, MFONT_FOUNDRY);
1378   if (key == Mfamily)
1379     return (void *) FONT_PROPERTY (font, MFONT_FAMILY);
1380   if (key == Mweight)
1381     return (void *) FONT_PROPERTY (font, MFONT_WEIGHT);
1382   if (key == Mstyle)
1383     return (void *) FONT_PROPERTY (font, MFONT_STYLE);
1384   if (key == Mstretch)
1385     return (void *) FONT_PROPERTY (font, MFONT_STRETCH);
1386   if (key == Madstyle)
1387     return (void *) FONT_PROPERTY (font, MFONT_ADSTYLE);
1388   if (key == Mregistry)
1389     return (void *) FONT_PROPERTY (font, MFONT_REGISTRY);
1390   if (key == Msize)
1391     {
1392       int size = font->property[MFONT_SIZE];
1393       return (void *) size;
1394     }
1395   if (key == Mresolution)
1396     {
1397       int resy = font->property[MFONT_RESY];
1398       return (void *) resy;
1399     }
1400
1401   MERROR (MERROR_FONT, NULL);
1402 }
1403
1404
1405 /*=*/
1406 /***en
1407     @brief Put a property value to a font.
1408
1409     The mfont_put_prop () function puts a font property whose key is
1410     $KEY and value is $VAL to $FONT.  $KEY must be one of the following
1411     symbols:
1412
1413         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1414         @c Madstyle, @c Mregistry, @c Msize, @c Mresolution.
1415
1416     If $KEY is @c Msize of @c Mresolution, $VAL must be an integer.
1417     Otherwise, $VAL must be a symbol.  */
1418
1419 int
1420 mfont_put_prop (MFont *font, MSymbol key, void *val)
1421 {
1422   if (key == Mfoundry)
1423     mfont__set_property (font, MFONT_FOUNDRY, (MSymbol) val);
1424   else if (key == Mfamily)
1425     mfont__set_property (font, MFONT_FAMILY, (MSymbol) val);
1426   else if (key == Mweight)
1427     mfont__set_property (font, MFONT_WEIGHT, (MSymbol) val);
1428   else if (key == Mstyle)
1429     mfont__set_property (font, MFONT_STYLE, (MSymbol) val);
1430   else if (key == Mstretch)
1431     mfont__set_property (font, MFONT_STRETCH, (MSymbol) val);
1432   else if (key == Madstyle)
1433     mfont__set_property (font, MFONT_ADSTYLE, (MSymbol) val);
1434   else if (key == Mregistry)
1435     mfont__set_property (font, MFONT_REGISTRY, (MSymbol) val);
1436   else if (key == Msize)
1437     {
1438       unsigned size = (unsigned) val;
1439       font->property[MFONT_SIZE] = size;
1440     }
1441   else if (key == Mresolution)
1442     {
1443       unsigned resy = (unsigned) val;
1444       font->property[MFONT_RESY] =  resy;
1445     }
1446   else
1447     MERROR (MERROR_FONT, -1);
1448   return 0;
1449 }
1450
1451 /*=*/
1452
1453 /***en
1454     @brief Return the font selection priority.
1455
1456     The mfont_selection_priority () function returns a newly created
1457     array of six symbols.  The elements are the following
1458     keys of font properties ordered by priority.
1459
1460         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1461         @c Madstyle, @c Msize.
1462
1463    The m17n library selects the best matching font according to the
1464    order of this array.  A font that has a different value for a
1465    property of lower priority is preferred to a font that has a
1466    different value for a property of higher priority.  */
1467
1468 MSymbol *
1469 mfont_selection_priority ()
1470 {
1471   MSymbol *keys;
1472   int i;
1473
1474   MTABLE_MALLOC (keys, FONT_SCORE_PRIORITY_SIZE, MERROR_FONT);
1475   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1476     {
1477       enum MFontProperty prop = font_score_priority[i];
1478
1479       if (prop == MFONT_SIZE)
1480         keys[i] = Msize;
1481       else if (prop == MFONT_ADSTYLE)
1482         keys[i] = Madstyle;
1483       else if (prop == MFONT_FAMILY)
1484         keys[i] = Mfamily;
1485       else if (prop == MFONT_WEIGHT)
1486         keys[i] = Mweight;
1487       else if (prop == MFONT_STYLE)
1488         keys[i] = Mstyle;
1489       else if (prop == MFONT_STRETCH)
1490         keys[i] = Mstretch;
1491       else
1492         keys[i] = Mfoundry;
1493     }
1494   return keys;
1495 }
1496
1497 /*=*/
1498
1499 /***en
1500     @brief Set the font selection priority.
1501
1502     The mfont_set_selection_priority () function sets font selection
1503     priority according to $KEYS, which is an array of six symbols.
1504     Each element must be one of the below.  No two elements must be
1505     the same.
1506
1507         @c Mfamily, @c Mweight, @c Mstyle, @c Mstretch,
1508         @c Madstyle, @c Msize.
1509
1510     See the documentation of the function mfont_selection_priority ()
1511     for details.  */
1512
1513 int
1514 mfont_set_selection_priority (MSymbol *keys)
1515 {
1516   int priority[FONT_SCORE_PRIORITY_SIZE];
1517   int i, j;
1518
1519   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++, keys++)
1520     {
1521       enum MFontProperty prop;
1522
1523       if (*keys == Msize)
1524         prop = MFONT_SIZE;
1525       else if (*keys == Madstyle)
1526         prop = MFONT_ADSTYLE;
1527       else if (*keys == Mfamily)
1528         prop = MFONT_FAMILY;
1529       else if (*keys == Mweight)
1530         prop = MFONT_WEIGHT;
1531       else if (*keys == Mstyle)
1532         prop = MFONT_STYLE;
1533       else if (*keys == Mstretch)
1534         prop = MFONT_STRETCH;
1535       else if (*keys == Mfoundry)
1536         prop = MFONT_FOUNDRY;
1537       else
1538         /* Invalid element.  */
1539         return -1;
1540       for (j = 0; j < i; j++)
1541         if (priority[j] == prop)
1542           /* Duplicated element.  */
1543           return -1;
1544       priority[i] = prop;
1545     }
1546   for (i = 0; i < FONT_SCORE_PRIORITY_SIZE; i++)
1547     font_score_priority[i] = priority[i];
1548   return 0;
1549 }
1550
1551 /*=*/
1552
1553 /***en
1554     @brief Find a font.
1555
1556     The mfont_find () function returns a pointer to the available font
1557     that matches best the specification $SPEC on frame $FRAME.
1558
1559     $SCORE, if not NULL, must point to a place to store the score
1560     value that indicates how well the found font matches to $SPEC.  A
1561     smaller score means a better match.  */
1562
1563 /***ja
1564     @brief ¥Õ¥©¥ó¥È¤òõ¤¹
1565
1566     ´Ø¿ô mfont_find () ¤Ï¡¢¥Õ¥ì¡¼¥à $FRAME ¾å¤Ç¥Õ¥©¥ó¥ÈÄêµÁ $SPEC ¤Ë¤â¤Ã
1567     ¤È¤â¶á¤¤¥Õ¥©¥ó¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£  */
1568
1569 MFont *
1570 mfont_find (MFrame *frame, MFont *spec, int *score, int limited_size)
1571 {
1572   MFont spec_copy;
1573   MRealizedFont *rfont;
1574
1575   MFONT_INIT (&spec_copy);
1576   spec_copy.property[MFONT_REGISTRY] = spec->property[MFONT_REGISTRY];
1577
1578   rfont = mfont__select (frame, &spec_copy, spec, limited_size, Mnil);
1579   if (!rfont)
1580     return NULL;
1581   if (score)
1582     *score = rfont->score;
1583   return &rfont->font;
1584 }
1585
1586 /*=*/
1587 /***en
1588     @brief Set encoding of a font.
1589
1590     The mfont_set_encoding () function sets the encoding information
1591     of $FONT.
1592
1593     If $ENCODING_NAME is be a symbol representing a charset that has
1594     the same encoding as the font.
1595
1596     If $REPERTORY_NAME @c Mnil or a symbol representing a charset that
1597     has the same repertory as the font.  If it is @c Mnil, whether a
1598     specific character is supported by the font is asked to each font
1599     driver.
1600
1601     @return
1602     If the operation was successful, this function returns 0.
1603     Otherwise it returns -1 and assigns an error code to the external
1604     variable @c merror_code.  */
1605
1606 int
1607 mfont_set_encoding (MFont *font, MSymbol encoding_name, MSymbol repertory_name)
1608 {
1609   MCharset *encoding_charset = MCHARSET (encoding_name);
1610   MCharset *repertory_charset;
1611   MSymbol registry;
1612   MFontEncoding *encoding;
1613   MPlist *plist;
1614
1615   if (! encoding_charset)
1616     MERROR (MERROR_FONT, -1);
1617   if (repertory_name != Mnil)
1618     {
1619       repertory_charset = MCHARSET (repertory_name);
1620       if (! repertory_charset)
1621         MERROR (MERROR_FONT, -1);
1622     }
1623   else
1624     repertory_charset = NULL;
1625
1626   MSTRUCT_CALLOC (encoding, MERROR_FONT);
1627   encoding->spec = *font;
1628   encoding->encoding_name = encoding_name;
1629   encoding->encoding_charset = encoding_charset;
1630   encoding->repertory_name = repertory_name;
1631   encoding->repertory_charset = repertory_charset;
1632   registry = FONT_PROPERTY (font, MFONT_REGISTRY);
1633   if (registry == Mnil)
1634     registry = Mt;
1635   if (! font_encoding_list)
1636     load_font_encoding_table ();
1637   mplist_push (font_encoding_list, registry, encoding);
1638   MPLIST_DO (plist, MPLIST_NEXT (font_encoding_list))
1639     if (! memcmp (font, &((MFontEncoding *) MPLIST_VAL (plist))->spec,
1640                   sizeof (MFont)))
1641       {
1642         mplist_pop (plist);
1643         break;
1644       }
1645   return 0;
1646 }
1647
1648 /*** @} */
1649
1650 /*** @addtogroup m17nDebug */
1651 /*=*/
1652 /*** @{ */
1653
1654 /***en
1655     @brief Dump a font
1656
1657     The mdebug_dump_font () function prints $FONT in a human readable
1658     way to the stderr.
1659
1660     @return
1661     This function returns $FONT.  */
1662
1663 MFont *
1664 mdebug_dump_font (MFont *font)
1665 {
1666   char *name = mwin__build_font_name (font);
1667
1668   fprintf (stderr, "%s", name);
1669   free (name);
1670   return font;
1671 }
1672
1673 /*** @} */
1674
1675 /*
1676   Local Variables:
1677   coding: euc-japan
1678   End:
1679 */