#include "symbol.h"
#include "plist.h"
#include "charset.h"
+#include "language.h"
#include "internal-gui.h"
#include "font.h"
#include "face.h"
static MSymbol M_font_capability, M_font_list, M_font_list_len;
+static MSymbol Motf;
+
/** Indices to font properties sorted by their priority. */
static int font_score_priority[] =
{ MFONT_SIZE,
}
#endif /* not HAVE_OTF */
-static MPlist *otf_script_list;
-
-static int
-load_otf_script_list ()
-{
- MDatabase *mdb;
- MPlist *plist, *pl;
-
- otf_script_list = mplist ();
- mdb = mdatabase_find (msymbol ("standard"), Mscript, msymbol ("otf"), Mnil);
- if (! mdb
- || ! (plist = mdatabase_load (mdb)))
- MERROR (MERROR_FONT, -1);
- MPLIST_DO (pl, plist)
- {
- MPlist *p;
- MSymbol script, otf_script;
- OTF_Tag tag;
-
- if (! MPLIST_PLIST_P (pl))
- continue;
- p = MPLIST_PLIST (pl);
- if (! MPLIST_SYMBOL_P (p))
- continue;
- script = MPLIST_SYMBOL (p);
- p = MPLIST_NEXT (p);
- if (! MPLIST_SYMBOL_P (p))
- continue;
- otf_script = MPLIST_SYMBOL (p);
- tag = OTF_tag (MSYMBOL_NAME (otf_script));
- mplist_push (otf_script_list, script, (void *) tag);
- }
- M17N_OBJECT_UNREF (plist);
- return 0;
-}
-
-static MSymbol
-find_script_from_otf_tag (OTF_Tag tag)
-{
- MPlist *plist;
-
- if (! otf_script_list)
- load_otf_script_list ();
- plist = mplist_find_by_value (otf_script_list, (void *) tag);
- return (plist ? MPLIST_KEY (plist) : Mnil);
-}
-
/* XLFD parser/generator */
/** Indices to each field of split font name. */
return score;
}
+static MSymbol
+merge_capability (MSymbol capability, MSymbol key, MSymbol val, int overwrite)
+{
+ MFontCapability *cap = NULL;
+ char *lang = NULL, *script = NULL, *otf = NULL, *buf, *p;
+ int lang_len = 0, script_len = 0, otf_len = 0;
+
+ if (key == Mlanguage)
+ lang = MSYMBOL_NAME (val), lang_len = MSYMBOL_NAMELEN (val) + 6;
+ else if (key == Mscript)
+ script = MSYMBOL_NAME (val), script_len = MSYMBOL_NAMELEN (val) + 7;
+ else if (key == Motf)
+ otf = MSYMBOL_NAME (val), otf_len = MSYMBOL_NAMELEN (val) + 5;
+ else
+ return capability;
+
+ if (capability != Mnil)
+ {
+ cap = mfont__get_capability (capability);
+ if (! overwrite)
+ {
+ if (cap->language)
+ lang = NULL;
+ if (cap->script)
+ script = NULL;
+ if (cap->script_tag)
+ otf = NULL;
+ if (! lang && !script && !otf)
+ return capability;
+ }
+ }
+
+ if (! lang && cap && cap->language)
+ {
+ lang_len = MSYMBOL_NAMELEN (cap->language);
+ lang = MSYMBOL_NAME (cap->language);
+ }
+ if (! script && cap && cap->script != Mnil)
+ {
+ script_len = MSYMBOL_NAMELEN (cap->script);
+ script = MSYMBOL_NAME (cap->script);
+ }
+ if (! otf && cap && cap->script_tag)
+ {
+ int i;
+
+ otf_len = 4; /* for script_tag */
+ if (cap->langsys_tag)
+ otf_len += 5; /* for "/XXXX */
+ for (i = 0; i < MFONT_OTT_MAX; i++)
+ if (cap->features[i].str)
+ otf_len += strlen (cap->features[i].str) + 1; /* for "[=+]..." */
+ otf = p = alloca (otf_len + 1);
+ OTF_tag_name (cap->script_tag, otf);
+ p += 4;
+ if (cap->langsys_tag)
+ {
+ *p++ = '/';
+ OTF_tag_name (cap->langsys_tag, p);
+ p += 4;
+ }
+ if (cap->features[MFONT_OTT_GSUB].str)
+ p += sprintf (p, "=%s", cap->features[MFONT_OTT_GSUB].str);
+ if (cap->features[MFONT_OTT_GPOS].str)
+ p += sprintf (p, "=%s", cap->features[MFONT_OTT_GSUB].str);
+ }
+ buf = p = alloca (lang_len + script_len + otf_len + 1);
+ if (lang_len)
+ p += sprintf (p, ":lang=%s", lang);
+ if (script_len)
+ p += sprintf (p, ":script=%s", script);
+ if (otf_len)
+ p += sprintf (p, ":otf=%s", otf);
+ return msymbol (buf);
+}
+
\f
/* Internal API */
Municode_full = msymbol ("unicode-full");
Mapple_roman = msymbol ("apple-roman");
+ Motf = msymbol ("otf");
+
/* The first entry of each mfont__property_table must be Mnil so
that actual properties get positive numeric numbers. */
for (i = 0; i <= MFONT_REGISTRY; i++)
M17N_OBJECT_UNREF (font_encoding_list);
font_encoding_list = NULL;
}
- if (otf_script_list)
- {
- M17N_OBJECT_UNREF (otf_script_list);
- otf_script_list = NULL;
- }
for (i = 0; i <= MFONT_REGISTRY; i++)
MLIST_FREE1 (&mfont__property_table[i], names);
{
MFontCapability *cap = object;
- if (cap->lang)
- free (cap->lang);
- if (cap->script)
+ if (cap->script_tag)
{
int i;
for (i = 0; i < MFONT_OTT_MAX; i++)
{
if (*str++ != ':')
continue;
- if (str[0] == 'o' && str[1] == 't' && str[2] == 'f' && str[3] == '=')
+ if (str[0] == 'o' && strncmp (str + 1, "tf=", 3) == 0)
{
+ MSymbol sym;
int i;
str += 4;
for (i = 0, p = str; i < 4 && p < endp; i++, p++);
if (i < 4)
break;
+ sym = msymbol__with_len (str, 4);
+ cap->script = mscript__from_otf_tag (sym);
+ if (cap->script == Mnil)
+ break;
cap->script_tag = OTF_tag (str);
- cap->script = find_script_from_otf_tag (cap->script_tag);
if (*p == '/')
{
for (i = 0, str = ++p; i < 4 && p < endp; i++, p++);
if (i < 4)
{
cap->script = Mnil;
+ cap->script_tag = 0;
break;
}
cap->langsys_tag = OTF_tag (str);
}
str = p;
}
- else if (str[0] == 'l' && str[1] == 'a' && str[2] == 'n' && str[3] == 'g'
- && str[4] == '=')
+ else if (str[0] == 'l' && strncmp (str + 1, "ang=", 4) == 0)
{
- int count;
-
str += 5;
- for (p = str, count = 2; p < endp && *p != ':'; p++)
- if (*p == ',')
- count++;
- MTABLE_MALLOC (cap->lang, count, MERROR_FONT);
- for (p = str, count = 0; p < endp && *p != ':'; p++)
- if (*p == ',')
- {
- MSymbol lang = msymbol__with_len (str, p - str), sym;
-
- if (msymbol_get (lang, Miso639_2))
- cap->lang[count++] = lang;
- else if ((sym = msymbol_get (lang, Miso639_1)) != Mnil)
- cap->lang[count++] = sym;
- else if (msymbol_get (lang, Mlanguage))
- cap->lang[count++] = lang;
- str = p + 1;
- }
+ for (p = str; p < endp && *p != ':'; p++);
if (str < p)
- cap->lang[count++] = msymbol__with_len (str, p - str);
- cap->lang[count] = Mnil;
+ cap->language = msymbol__with_len (str, p - str);
str = p;
}
- else if (str[0] == 's' && str[1] == 'c' && str[2] == 'r' && str[3] == 'i'
- && str[4] == 'p' && str[5] == 't' && str[6] == '=')
+ else if (str[0] == 's' && strncmp (str + 1, "cript=", 6) == 0)
{
str += 7;
for (p = str; p < endp && *p != ':'; p++);
unsigned resy = (unsigned) val;
font->property[MFONT_RESY] = resy;
}
- else if (key == Mlanguage)
+ else if (key == Mlanguage || key == Mscript || key == Motf)
{
- char *langname = MSYMBOL_NAME ((MSymbol) val);
- int len = MSYMBOL_NAMELEN ((MSymbol) val);
-
- if (len <= 3)
- {
- char buf[10];
-
- sprintf (buf, ":lang=%s", langname);
- font->capability = msymbol (buf);
- }
+ font->capability = merge_capability (font->capability,
+ key, (MSymbol) val, 1);
}
else if (key == Mfontfile)
{
ones that support $LANGUAGE. $MAXNUM, if greater than 0, limits
the number of fonts.
+ $LANGUAGE argument exists just for backward compatibility, and the
+ use is deprecated. Use #Mlanguage font property instead. If
+ $FONT already has #Mlanguage property, $LANGUAGE is ignored.
+
@return
This function returns a plist whose keys are family names and
values are pointers to the object MFont. The plist must be freed
/***ja
@brief ¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÆÀ¤ë
- ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
- $FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
- $LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£
- $MAXNUM ¤Ï¡¢0 ¤è¤êÂ礤¤¾ì¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
+ ´Ø¿ô mfont_list () ¤Ï¥Õ¥ì¡¼¥à $FRAME ¤ÇÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤ò
+ ÊÖ¤¹¡£$FONT ¤¬ NULL ¤Ç¤Ê¤±¤ì¤Ð¡¢$FONT ¤È¹çÃפ¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È
+ ¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£$LANGUAGE ¤¬ @c Mnil ¤Ç¤Ê¤±¤ì¤Ð¡¢$LANGUAGE ¤ò¥µ¥Ý¡¼
+ ¥È¤¹¤ëÍøÍѲÄǽ¤Ê¥Õ¥©¥ó¥È¤Î¥ê¥¹¥È¤òÊÖ¤¹¡£$MAXNUM ¤Ï¡¢0 ¤è¤êÂ礤¤¾ì
+ ¹ç¤Ë¤Ï¡¢ÊÖ¤¹¥Õ¥©¥ó¥È¤Î¿ô¤Î¾å¸Â¤Ç¤¢¤ë¡£
+
+ ¤¿¤À¤·¡¢°ú¿ô $LANGUAGE ¤ÏµìÈǤȤÎÀ°¹çÀ¤Î¤¿¤á¤À¤±¤Ë¤¢¤ê¡¢¤½¤Î»ÈÍѤÏ
+ ´«¤á¤é¤ì¤Ê¤¤¡£¥Õ¥©¥ó¥È¤Î #Mlanguage ¥×¥í¥Ñ¥Æ¥£¤ò»È¤¦¤Ù¤¤Ç¤¢¤ë¡£¤â
+ ¤· $FONT ¤¬¤¹¤Ç¤Ë¤³¤Î¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤¤¤¿¤é¡¢°ú¿ô $LANGUAGE ¤Ï̵
+
@return
- ¤³¤Î´Ø¿ô¤Ï¥¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Ê
- plist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref ()
- ¤Ç²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£ */
+ ¤³¤Î´Ø¿ô¤Ï¥¡¼¤¬¥Õ¥©¥ó¥È¥Õ¥¡¥ß¥ê̾¤Ç¤¢¤êÃͤ¬ MFont ¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î
+ ¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¤è¤¦¤Êplist ¤òÊÖ¤¹¡£plist ¤Ï m17n_object_unref () ¤Ç
+ ²òÊü¤¹¤ëɬÍפ¬¤¢¤ë¡£¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤±¤ì¤ÐNULL ¤òÊÖ¤¹¡£ */
MPlist *
mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum)
}
if (language != Mnil)
- {
- /* ":lang=XXX" */
- char *buf = alloca (MSYMBOL_NAMELEN (language) + 7);
-
- sprintf (buf, ":lang=%s", MSYMBOL_NAME (language));
- spec.capability = msymbol (buf);
- }
+ spec.capability = merge_capability (spec.capability, Mlanguage, language,
+ 0);
font_list = mfont__list (frame, &spec, &spec, 0);
if (! font_list)
return plist;
}
+/***en
+ @brief Get a list of font famiy names.
+
+ The mfont_list_family_names () functions returns a list of font
+ family names available on frame $FRAME.
+
+ @return
+
+ This function returns a plist whose keys are #Msymbol and values
+ are symbols representing font family names. The elements are
+ sorted by alphabetical order. The plist must be freed by
+ m17n_object_unref (). If not font is found, it returns NULL. */
+
+MPlist *
+mfont_list_family_names (MFrame *frame)
+{
+ MPlist *plist = mplist (), *p;
+
+ MPLIST_DO (p, frame->font_driver_list)
+ {
+ MFontDriver *driver = MPLIST_VAL (p);
+
+ (driver->list_family_names) (frame, plist);
+ }
+ return plist;
+}
+
/*=*/