Imported Upstream version 2.6.7
[platform/upstream/harfbuzz.git] / src / hb-ot-tag.cc
index 8ad917a..7ec91c5 100644 (file)
@@ -319,12 +319,26 @@ parse_private_use_subtag (const char     *private_use_subtag,
   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;
@@ -434,30 +448,28 @@ hb_ot_tag_to_language (hb_tag_t tag)
     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);
   }
 }
 
@@ -498,13 +510,14 @@ hb_ot_tags_to_script_and_language (hb_tag_t       script_tag,
       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++] = '-';
@@ -515,10 +528,9 @@ hb_ot_tags_to_script_and_language (hb_tag_t       script_tag,
        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);
       }