From 59910e65d2ce102e002ac1eb08b47a04ea9d8c55 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Thu, 9 Oct 2025 10:46:09 +0000 Subject: [PATCH] add utf32 function git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@239 b9cfdab3-6d41-4d17-bbe4-086880011989 --- GNUmakefile | 2 +- include/Mw/Milsko.h | 1 + include/Mw/Unicode.h | 28 +++++++++++++++++++++ src/unicode.c | 60 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 include/Mw/Unicode.h create mode 100644 src/unicode.c diff --git a/GNUmakefile b/GNUmakefile index 3668732..e2969cc 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -26,7 +26,7 @@ L_CFLAGS = $(DEPINC) $(CFLAGS) -fPIC -D_MILSKO L_LDFLAGS = $(LDFLAGS) L_LIBS = $(LIBS) -L_OBJS = src/core.o src/default.o src/draw.o src/lowlevel.o src/font.o src/boldfont.o src/error.o +L_OBJS = src/core.o src/default.o src/draw.o src/lowlevel.o src/font.o src/boldfont.o src/error.o src/unicode.o L_OBJS += src/external/ds.o src/external/image.o L_OBJS += src/widget/window.o src/widget/button.o src/widget/frame.o src/widget/menu.o src/widget/submenu.o src/widget/image.o src/widget/scrollbar.o src/widget/checkbox.o src/widget/label.o src/widget/entry.o L_OBJS += src/cursor/default.o src/cursor/cross.o src/cursor/text.o diff --git a/include/Mw/Milsko.h b/include/Mw/Milsko.h index 8ea962d..de6450b 100644 --- a/include/Mw/Milsko.h +++ b/include/Mw/Milsko.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/include/Mw/Unicode.h b/include/Mw/Unicode.h new file mode 100644 index 0000000..62794f3 --- /dev/null +++ b/include/Mw/Unicode.h @@ -0,0 +1,28 @@ +/* $Id$ */ +/*! + * %file Mw/Unicode.h + * %brief Handles UTF8 stuff + */ +#ifndef __MW_UNICODE_H__ +#define __MW_UNICODE_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * %brief Converts UTF-8 to UTF-32 + * %brief input Input + * %brief output Output + * %return Bytes this multibyte takes + */ +MWDECL int MwUTF8ToUTF32(const char* input, int32_t* output); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/unicode.c b/src/unicode.c new file mode 100644 index 0000000..940a941 --- /dev/null +++ b/src/unicode.c @@ -0,0 +1,60 @@ +/* $Id$ */ +#include + +/* this code was taken from my old code... :) */ + +#define CAST_I32(x) ((int)(x)) + +static int utf8_count(unsigned char c) { + if(c < 0x80) { + return 1; + } + if(0xc2 <= c && c < 0xe0) { + return 2; + } + if(0xe0 <= c && c < 0xf0) { + return 3; + } + if(0xf0 <= c && c < 0xf8) { + return 4; + } + return 0; +} + +static int utf8_later(unsigned char c) { + return 0x80 <= c && c < 0xc0; +} + +int MwUTF8ToUTF32(const char* input, int32_t* output) { + const unsigned char* inbuf = (const unsigned char*)input; + int b = utf8_count(inbuf[0]); + if(b == 0) return 0; + + if(b == 1) *output = inbuf[0]; + if(b == 2) { + if(!utf8_later(inbuf[1])) return 0; + if((inbuf[0] & 0x1e) == 0) return 0; + + *output = CAST_I32(inbuf[0] & 0x1f) << 6; + *output |= CAST_I32(inbuf[1] & 0x3f); + } + if(b == 3) { + if(!utf8_later(inbuf[1]) || !utf8_later(inbuf[2])) return 0; + if((inbuf[0] & 0x0f) == 0 && (inbuf[1] & 0x20) == 0) return 0; + + *output = CAST_I32(inbuf[0] & 0x0f) << 12; + *output |= CAST_I32(inbuf[1] & 0x3f) << 6; + *output |= CAST_I32(inbuf[2] & 0x3f); + } + if(b == 4) { + if(!utf8_later(inbuf[1]) || !utf8_later(inbuf[2]) || !utf8_later(inbuf[3])) return 0; + if((inbuf[0] & 0x07) == 0 && (inbuf[1] & 0x30) == 0) return 0; + + *output = CAST_I32(inbuf[0] & 0x07) << 18; + *output |= CAST_I32(inbuf[1] & 0x3f) << 12; + *output |= CAST_I32(inbuf[2] & 0x3f) << 6; + *output |= CAST_I32(inbuf[3] & 0x3f); + } + + return b; +}