Blame src-nuklear/nuklear_utf8.c

Ivan Mahonin b53a5c
#include "nuklear.h"
Ivan Mahonin b53a5c
#include "nuklear_internal.h"
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
/* ===============================================================
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 *                              UTF-8
Ivan Mahonin b53a5c
 *
Ivan Mahonin b53a5c
 * ===============================================================*/
Ivan Mahonin b53a5c
NK_GLOBAL const nk_byte nk_utfbyte[NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
Ivan Mahonin b53a5c
NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
Ivan Mahonin b53a5c
NK_GLOBAL const nk_uint nk_utfmin[NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000};
Ivan Mahonin b53a5c
NK_GLOBAL const nk_uint nk_utfmax[NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
NK_INTERN int
Ivan Mahonin b53a5c
nk_utf_validate(nk_rune *u, int i)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    NK_ASSERT(u);
Ivan Mahonin b53a5c
    if (!u) return 0;
Ivan Mahonin b53a5c
    if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
Ivan Mahonin b53a5c
         NK_BETWEEN(*u, 0xD800, 0xDFFF))
Ivan Mahonin b53a5c
            *u = NK_UTF_INVALID;
Ivan Mahonin b53a5c
    for (i = 1; *u > nk_utfmax[i]; ++i);
Ivan Mahonin b53a5c
    return i;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_INTERN nk_rune
Ivan Mahonin b53a5c
nk_utf_decode_byte(char c, int *i)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    NK_ASSERT(i);
Ivan Mahonin b53a5c
    if (!i) return 0;
Ivan Mahonin b53a5c
    for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) {
Ivan Mahonin b53a5c
        if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
Ivan Mahonin b53a5c
            return (nk_byte)(c & ~nk_utfmask[*i]);
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    return 0;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API int
Ivan Mahonin b53a5c
nk_utf_decode(const char *c, nk_rune *u, int clen)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    int i, j, len, type=0;
Ivan Mahonin b53a5c
    nk_rune udecoded;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(c);
Ivan Mahonin b53a5c
    NK_ASSERT(u);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    if (!c || !u) return 0;
Ivan Mahonin b53a5c
    if (!clen) return 0;
Ivan Mahonin b53a5c
    *u = NK_UTF_INVALID;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    udecoded = nk_utf_decode_byte(c[0], &len);
Ivan Mahonin b53a5c
    if (!NK_BETWEEN(len, 1, NK_UTF_SIZE))
Ivan Mahonin b53a5c
        return 1;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
Ivan Mahonin b53a5c
        udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
Ivan Mahonin b53a5c
        if (type != 0)
Ivan Mahonin b53a5c
            return j;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    if (j < len)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
    *u = udecoded;
Ivan Mahonin b53a5c
    nk_utf_validate(u, len);
Ivan Mahonin b53a5c
    return len;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_INTERN char
Ivan Mahonin b53a5c
nk_utf_encode_byte(nk_rune u, int i)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i]));
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API int
Ivan Mahonin b53a5c
nk_utf_encode(nk_rune u, char *c, int clen)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    int len, i;
Ivan Mahonin b53a5c
    len = nk_utf_validate(&u, 0);
Ivan Mahonin b53a5c
    if (clen < len || !len || len > NK_UTF_SIZE)
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    for (i = len - 1; i != 0; --i) {
Ivan Mahonin b53a5c
        c[i] = nk_utf_encode_byte(u, 0);
Ivan Mahonin b53a5c
        u >>= 6;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    c[0] = nk_utf_encode_byte(u, len);
Ivan Mahonin b53a5c
    return len;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API int
Ivan Mahonin b53a5c
nk_utf_len(const char *str, int len)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    const char *text;
Ivan Mahonin b53a5c
    int glyphs = 0;
Ivan Mahonin b53a5c
    int text_len;
Ivan Mahonin b53a5c
    int glyph_len;
Ivan Mahonin b53a5c
    int src_len = 0;
Ivan Mahonin b53a5c
    nk_rune unicode;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(str);
Ivan Mahonin b53a5c
    if (!str || !len) return 0;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    text = str;
Ivan Mahonin b53a5c
    text_len = len;
Ivan Mahonin b53a5c
    glyph_len = nk_utf_decode(text, &unicode, text_len);
Ivan Mahonin b53a5c
    while (glyph_len && src_len < len) {
Ivan Mahonin b53a5c
        glyphs++;
Ivan Mahonin b53a5c
        src_len = src_len + glyph_len;
Ivan Mahonin b53a5c
        glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len);
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    return glyphs;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c
NK_API const char*
Ivan Mahonin b53a5c
nk_utf_at(const char *buffer, int length, int index,
Ivan Mahonin b53a5c
    nk_rune *unicode, int *len)
Ivan Mahonin b53a5c
{
Ivan Mahonin b53a5c
    int i = 0;
Ivan Mahonin b53a5c
    int src_len = 0;
Ivan Mahonin b53a5c
    int glyph_len = 0;
Ivan Mahonin b53a5c
    const char *text;
Ivan Mahonin b53a5c
    int text_len;
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    NK_ASSERT(buffer);
Ivan Mahonin b53a5c
    NK_ASSERT(unicode);
Ivan Mahonin b53a5c
    NK_ASSERT(len);
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    if (!buffer || !unicode || !len) return 0;
Ivan Mahonin b53a5c
    if (index < 0) {
Ivan Mahonin b53a5c
        *unicode = NK_UTF_INVALID;
Ivan Mahonin b53a5c
        *len = 0;
Ivan Mahonin b53a5c
        return 0;
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
    text = buffer;
Ivan Mahonin b53a5c
    text_len = length;
Ivan Mahonin b53a5c
    glyph_len = nk_utf_decode(text, unicode, text_len);
Ivan Mahonin b53a5c
    while (glyph_len) {
Ivan Mahonin b53a5c
        if (i == index) {
Ivan Mahonin b53a5c
            *len = glyph_len;
Ivan Mahonin b53a5c
            break;
Ivan Mahonin b53a5c
        }
Ivan Mahonin b53a5c
Ivan Mahonin b53a5c
        i++;
Ivan Mahonin b53a5c
        src_len = src_len + glyph_len;
Ivan Mahonin b53a5c
        glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
Ivan Mahonin b53a5c
    }
Ivan Mahonin b53a5c
    if (i != index) return 0;
Ivan Mahonin b53a5c
    return buffer + src_len;
Ivan Mahonin b53a5c
}
Ivan Mahonin b53a5c