+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);
+}
+