]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - utf8lib.c
Fix engine not starting on Windows if linked against SDL > 2.0.5
[xonotic/darkplaces.git] / utf8lib.c
index b726e220d9768ca01d82b973aba0d5d464fecdd2..255c44f55619769b0c0c8e58af36e13b4bea93d1 100644 (file)
--- a/utf8lib.c
+++ b/utf8lib.c
@@ -226,6 +226,29 @@ size_t u8_strlen(const char *_s)
        return len;
 }
 
+static int colorcode_skipwidth(const unsigned char *s)
+{
+       if(*s == STRING_COLOR_TAG)
+       {
+               if(s[1] <= '9' && s[1] >= '0') // ^[0-9] found
+               {
+                       return 2;
+               }
+               else if(s[1] == STRING_COLOR_RGB_TAG_CHAR &&
+                       ((s[2] >= '0' && s[2] <= '9') || (s[2] >= 'a' && s[2] <= 'f') || (s[2] >= 'A' && s[2] <= 'F')) &&
+                       ((s[3] >= '0' && s[3] <= '9') || (s[3] >= 'a' && s[3] <= 'f') || (s[3] >= 'A' && s[3] <= 'F')) &&
+                       ((s[4] >= '0' && s[4] <= '9') || (s[4] >= 'a' && s[4] <= 'f') || (s[4] >= 'A' && s[4] <= 'F')))
+               {
+                       return 5;
+               }
+               else if(s[1] == STRING_COLOR_TAG)
+               {
+                       return 1; // special case, do NOT call colorcode_skipwidth for next char
+               }
+       }
+       return 0;
+}
+
 /** Get the number of characters in a part of an UTF-8 string.
  * @param _s    An utf-8 encoded null-terminated string.
  * @param n     The maximum number of bytes.
@@ -274,6 +297,49 @@ size_t u8_strnlen(const char *_s, size_t n)
        return len;
 }
 
+static size_t u8_strnlen_colorcodes(const char *_s, size_t n)
+{
+       size_t st, ln;
+       size_t len = 0;
+       const unsigned char *s = (const unsigned char*)_s;
+
+       while (*s && n)
+       {
+               int w = colorcode_skipwidth(s);
+               n -= w;
+               s += w;
+               if(w > 1) // == 1 means single caret
+                       continue;
+
+               // ascii char, skip u8_analyze
+               if (*s < 0x80 || !utf8_enable.integer)
+               {
+                       ++len;
+                       ++s;
+                       --n;
+                       continue;
+               }
+
+               // invalid, skip u8_analyze
+               if (*s < 0xC2)
+               {
+                       ++s;
+                       --n;
+                       continue;
+               }
+
+               if (!u8_analyze((const char*)s, &st, &ln, NULL, n))
+                       break;
+               // valid character, see if it's still inside the range specified by n:
+               if (n < st + ln)
+                       return len;
+               ++len;
+               n -= st + ln;
+               s += st + ln;
+       }
+       return len;
+}
+
 /** Get the number of bytes used in a string to represent an amount of characters.
  * @param _s    An utf-8 encoded null-terminated string.
  * @param n     The number of characters we want to know the byte-size for.
@@ -318,6 +384,46 @@ size_t u8_bytelen(const char *_s, size_t n)
        return len;
 }
 
+static size_t u8_bytelen_colorcodes(const char *_s, size_t n)
+{
+       size_t st, ln;
+       size_t len = 0;
+       const unsigned char *s = (const unsigned char*)_s;
+
+       while (*s && n)
+       {
+               int w = colorcode_skipwidth(s);
+               len += w;
+               s += w;
+               if(w > 1) // == 1 means single caret
+                       continue;
+
+               // ascii char, skip u8_analyze
+               if (*s < 0x80 || !utf8_enable.integer)
+               {
+                       ++len;
+                       ++s;
+                       --n;
+                       continue;
+               }
+
+               // invalid, skip u8_analyze
+               if (*s < 0xC2)
+               {
+                       ++s;
+                       ++len;
+                       continue;
+               }
+
+               if (!u8_analyze((const char*)s, &st, &ln, NULL, U8_ANALYZE_INFINITY))
+                       break;
+               --n;
+               s += st + ln;
+               len += st + ln;
+       }
+       return len;
+}
+
 /** Get the byte-index for a character-index.
  * @param _s      An utf-8 encoded string.
  * @param i       The character-index for which you want the byte offset.
@@ -339,7 +445,7 @@ int u8_byteofs(const char *_s, size_t i, size_t *len)
                }
 
                if (len) *len = 1;
-               return i;
+               return (int)i;
        }
 
        st = ln = 0;
@@ -352,7 +458,7 @@ int u8_byteofs(const char *_s, size_t i, size_t *len)
        } while(i-- > 0);
        if (len)
                *len = ln;
-       return ofs;
+       return (int)ofs;
 }
 
 /** Get the char-index for a byte-index.
@@ -372,7 +478,7 @@ int u8_charidx(const char *_s, size_t i, size_t *len)
        if (!utf8_enable.integer)
        {
                if (len) *len = 0;
-               return i;
+               return (int)i;
        }
 
        while (ofs < i && s[ofs])
@@ -596,15 +702,14 @@ int u8_fromchar(Uchar w, char *to, size_t maxlen)
  * @param l         The number of bytes without the terminating null.
  * @return          A statically allocated buffer containing the character's utf8 representation, or NULL if it fails.
  */
-char *u8_encodech(Uchar ch, size_t *l)
+char *u8_encodech(Uchar ch, size_t *l, char *buf16)
 {
-       static char buf[16];
        size_t len;
-       len = u8_fromchar(ch, buf, sizeof(buf));
+       len = u8_fromchar(ch, buf16, 16);
        if (len > 0)
        {
                if (l) *l = len;
-               return buf;
+               return buf16;
        }
        return NULL;
 }
@@ -791,14 +896,25 @@ size_t u8_strpad(char *out, size_t outsize, const char *in, qboolean leftalign,
        {
                size_t l = u8_bytelen(in, maxwidth);
                size_t actual_width = u8_strnlen(in, l);
-               int pad = (actual_width >= minwidth) ? 0 : (minwidth - actual_width);
-               int prec = l;
+               int pad = (int)((actual_width >= minwidth) ? 0 : (minwidth - actual_width));
+               int prec = (int)l;
                int lpad = leftalign ? 0 : pad;
                int rpad = leftalign ? pad : 0;
                return dpsnprintf(out, outsize, "%*s%.*s%*s", lpad, "", prec, in, rpad, "");
        }
 }
 
+size_t u8_strpad_colorcodes(char *out, size_t outsize, const char *in, qboolean leftalign, size_t minwidth, size_t maxwidth)
+{
+       size_t l = u8_bytelen_colorcodes(in, maxwidth);
+       size_t actual_width = u8_strnlen_colorcodes(in, l);
+       int pad = (int)((actual_width >= minwidth) ? 0 : (minwidth - actual_width));
+       int prec = (int)l;
+       int lpad = leftalign ? 0 : pad;
+       int rpad = leftalign ? pad : 0;
+       return dpsnprintf(out, outsize, "%*s%.*s%*s", lpad, "", prec, in, rpad, "");
+}
+
 
 /*
 The two following functions (u8_toupper, u8_tolower) are derived from