X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=utf8lib.c;h=76cc813766d944ed399efdb03f633524ace59187;hp=b726e220d9768ca01d82b973aba0d5d464fecdd2;hb=5a4be9fc214e0831a862d51f702510d2a002fa4b;hpb=3ceec78e79383ada2e6abe25e5a6e5f067259427 diff --git a/utf8lib.c b/utf8lib.c index b726e220..76cc8137 100644 --- 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. @@ -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; } @@ -799,6 +904,17 @@ size_t u8_strpad(char *out, size_t outsize, const char *in, qboolean leftalign, } } +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 = (actual_width >= minwidth) ? 0 : (minwidth - actual_width); + int prec = 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