char tag[4];
int i;
s += strlen (prefix);
- for (i = 0; i < 4 && ISALNUM (s[i]); i++)
- tag[i] = normalize (s[i]);
- if (!i) return false;
-
- for (; i < 4; i++)
- tag[i] = ' ';
+ if (s[0] == '-') {
+ s += 1;
+ char c;
+ for (i = 0; i < 8 && ISHEX (s[i]); i++)
+ {
+ c = FROMHEX (s[i]);
+ if (i % 2 == 0)
+ tag[i / 2] = c << 4;
+ else
+ tag[i / 2] += c;
+ }
+ if (i != 8) return false;
+ } else {
+ for (i = 0; i < 4 && ISALNUM (s[i]); i++)
+ tag[i] = normalize (s[i]);
+ if (!i) return false;
+
+ for (; i < 4; i++)
+ tag[i] = ' ';
+ }
tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]);
if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT)
tags[0] ^= ~0xDFDFDFDF;
if (ot_languages[i].tag == tag)
return hb_language_from_string (ot_languages[i].language, -1);
- /* If it's three letters long, assume it's ISO 639-3 and lower-case and use it
- * (if it's not a registered tag, calling hb_ot_tag_from_language on the
- * result might not return the same tag as the original tag).
- * Else return a custom language in the form of "x-hbotABCD". */
+ /* Return a custom language in the form of "x-hbot-AABBCCDD".
+ * If it's three letters long, also guess it's ISO 639-3 and lower-case and
+ * prepend it (if it's not a registered tag, the private use subtags will
+ * ensure that calling hb_ot_tag_from_language on the result will still return
+ * the same tag as the original tag).
+ */
{
- char buf[11] = "x-hbot";
+ char buf[20];
char *str = buf;
- buf[6] = tag >> 24;
- buf[7] = (tag >> 16) & 0xFF;
- buf[8] = (tag >> 8) & 0xFF;
- buf[9] = tag & 0xFF;
- if (buf[9] == 0x20)
+ if (ISALPHA (tag >> 24)
+ && ISALPHA ((tag >> 16) & 0xFF)
+ && ISALPHA ((tag >> 8) & 0xFF)
+ && (tag & 0xFF) == ' ')
{
- buf[9] = '\0';
- if (ISALPHA (buf[6]) && ISALPHA (buf[7]) && ISALPHA (buf[8]))
- {
- buf[6] = TOLOWER (buf[6]);
- buf[7] = TOLOWER (buf[7]);
- buf[8] = TOLOWER (buf[8]);
- str += 6;
- }
+ buf[0] = TOLOWER (tag >> 24);
+ buf[1] = TOLOWER ((tag >> 16) & 0xFF);
+ buf[2] = TOLOWER ((tag >> 8) & 0xFF);
+ buf[3] = '-';
+ str += 4;
}
- buf[10] = '\0';
- return hb_language_from_string (str, -1);
+ snprintf (str, 16, "x-hbot-%08x", tag);
+ return hb_language_from_string (&*buf, -1);
}
}
unsigned char *buf;
const char *lang_str = hb_language_to_string (*language);
size_t len = strlen (lang_str);
- buf = (unsigned char *) malloc (len + 11);
+ buf = (unsigned char *) malloc (len + 16);
if (unlikely (!buf))
{
*language = nullptr;
}
else
{
+ int shift;
memcpy (buf, lang_str, len);
if (lang_str[0] != 'x' || lang_str[1] != '-') {
buf[len++] = '-';
buf[len++] = 'b';
buf[len++] = 's';
buf[len++] = 'c';
- buf[len++] = script_tag >> 24;
- buf[len++] = (script_tag >> 16) & 0xFF;
- buf[len++] = (script_tag >> 8) & 0xFF;
- buf[len++] = script_tag & 0xFF;
+ buf[len++] = '-';
+ for (shift = 28; shift >= 0; shift -= 4)
+ buf[len++] = TOHEX (script_tag >> shift);
*language = hb_language_from_string ((char *) buf, len);
free (buf);
}