From cdc9fcbcce70579710d443eee4d67188938d32e3 Mon Sep 17 00:00:00 2001 From: handa Date: Fri, 23 Jun 2006 02:31:55 +0000 Subject: [PATCH] Include "language.h". (Motf): New variable. (otf_script_list, load_otf_script_list): Delete it. (find_script_from_otf_tag): Delete it. (merge_capability): New function. (mfont__init): Init Motf. (mfont__fini): Don't unref otf_script_list. (free_font_capability): Check cap->script_tag to determine if OTF-related capability is set. (mfont__get_capability): Call mscript__from_otf_tag. Adjusted for the change of type MFontCapability. (mfont_put_prop): Call merge_capability for Mlanguage, Mscript, and Motf properties. (mfont_list): Call merge_capability for LANGUAGE arg. (mfont_list_family_names): New function. --- src/font.c | 249 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 142 insertions(+), 107 deletions(-) diff --git a/src/font.c b/src/font.c index 49a0559..94dcea3 100644 --- a/src/font.c +++ b/src/font.c @@ -336,6 +336,7 @@ #include "symbol.h" #include "plist.h" #include "charset.h" +#include "language.h" #include "internal-gui.h" #include "font.h" #include "face.h" @@ -345,6 +346,8 @@ MPlist *mfont__driver_list; 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, @@ -665,53 +668,6 @@ OTF_tag (char *name) } #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. */ @@ -979,6 +935,82 @@ font_score (MFont *font, MFont *request) 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); +} + /* Internal API */ @@ -1029,6 +1061,8 @@ mfont__init () 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++) @@ -1145,11 +1179,6 @@ mfont__fini () 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); @@ -1635,9 +1664,7 @@ free_font_capability (void *object) { 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++) @@ -1670,22 +1697,27 @@ mfont__get_capability (MSymbol sym) { 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); @@ -1752,36 +1784,15 @@ mfont__get_capability (MSymbol sym) } 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++); @@ -2393,18 +2404,10 @@ mfont_put_prop (MFont *font, MSymbol key, void *val) 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) { @@ -2785,6 +2788,10 @@ mfont_resize_ratio (MFont *font) 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 @@ -2794,15 +2801,21 @@ mfont_resize_ratio (MFont *font) /***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) @@ -2825,13 +2838,8 @@ 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) @@ -2854,6 +2862,33 @@ mfont_list (MFrame *frame, MFont *font, MSymbol language, int maxnum) 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; +} + /*=*/ -- 1.7.10.4