]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/lib/string.qh
Menu, player name editing: make changing an existing color much easier by detecting...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / string.qh
index 946438ca5f836ae29c8a2f8e276e46f8cd1330f6..69ecc7b4a7dfc3da9322acfb48f8518b24810fb8 100644 (file)
@@ -436,3 +436,63 @@ const string HEXDIGITS = "0123456789ABCDEF0123456789abcdef";
 
 const string DIGITS = "0123456789";
 #define IS_DIGIT(d) (strstrofs(DIGITS, (d), 0) >= 0)
+
+// returns true if the caret at position pos is escaped
+ERASEABLE
+bool isCaretEscaped(string theText, float pos)
+{
+       // count all the previous carets
+       int carets = 0;
+       while(pos - carets >= 1 && substring(theText, pos - carets - 1, 1) == "^")
+               ++carets;
+       // if number of previous carets is odd then this carets is escaped
+       return (carets & 1);
+}
+
+ERASEABLE
+bool isValidColorCodeValue(string theText, int cc_len, int tag_start)
+{
+       if (cc_len == 2)
+               return IS_DIGIT(substring(theText, tag_start + 1, 1));
+       if (cc_len == 5)
+               return (IS_HEXDIGIT(substring(theText, tag_start + 2, 1))
+                       && IS_HEXDIGIT(substring(theText, tag_start + 3, 1))
+                       && IS_HEXDIGIT(substring(theText, tag_start + 4, 1)));
+       return false;
+}
+
+// it returns 0 if pos is NOT in the middle or at the end of a color code
+// otherwise it returns a 2-digit number with cc_len as the first digit
+// and the offset from '^' position to pos as the second digit
+// e.g.:
+// "a^2xy" | returns 0 if pos == 0 or 1 or 4
+//    ^^   | returns 21 or 22 if pos == 2 or 3
+ERASEABLE
+int checkColorCode(string theText, int pos)
+{
+       int text_len = strlen(theText);
+       string tag_type = "^";
+       int cc_len = 2;
+       int tag_len = 1;
+
+       LABEL(check_color_tag)
+
+       for (int ofs = cc_len; ofs >= 1; ofs--)
+       {
+               if (!(pos >= ofs && text_len >= pos + (cc_len - ofs)))
+                       continue;
+               if(substring(theText, pos - ofs, tag_len) == tag_type)
+               {
+                       if (!isCaretEscaped(theText, pos - ofs) && isValidColorCodeValue(theText, cc_len, pos - ofs))
+                               return cc_len * 10 + ofs;
+               }
+       }
+       if (cc_len == 2)
+       {
+               tag_type = "^x";
+               cc_len = 5;
+               tag_len = 2;
+               goto check_color_tag;
+       }
+       return 0;
+}