shithub: choc

Download patch

ref: c818fb021632cbb68229ba265f01b060e6b6d0f4
parent: d4df22aa1e8e2ee8d389be9fb485985c4d80d47e
author: Simon Howard <[email protected]>
date: Fri Feb 3 15:21:17 EST 2012

Split off UTF-8 code into separate file and add extra functions.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 2489

--- a/textscreen/Makefile.am
+++ b/textscreen/Makefile.am
@@ -30,6 +30,7 @@
 	                         txt_smallfont.h          \
 	txt_strut.c              txt_strut.h              \
 	txt_table.c              txt_table.h              \
+	txt_utf8.c               txt_utf8.h               \
 	txt_widget.c             txt_widget.h             \
 	txt_window.c             txt_window.h             \
 	txt_window_action.c      txt_window_action.h      \
--- a/textscreen/txt_gui.c
+++ b/textscreen/txt_gui.c
@@ -25,6 +25,7 @@
 #include "txt_gui.h"
 #include "txt_io.h"
 #include "txt_main.h"
+#include "txt_utf8.h"
 
 typedef struct txt_cliparea_s txt_cliparea_t;
 
@@ -296,58 +297,6 @@
     TXT_GotoXY(x + strlen(s), y);
 }
 
-// Decode UTF-8 character, incrementing *ptr over the decoded bytes.
-
-static unsigned int DecodeUTF8(const char **ptr)
-{
-    const char *p = *ptr;
-    unsigned int c;
-
-    // UTF-8 decode.
-
-    if ((*p & 0x80) == 0)                     // 1 character (ASCII):
-    {
-        c = *p;
-        *ptr += 1;
-    }
-    else if ((p[0] & 0xe0) == 0xc0            // 2 character:
-          && (p[1] & 0xc0) == 0x80)
-    {
-        c = ((p[0] & 0x1f) << 6)
-          |  (p[1] & 0x3f);
-        *ptr += 2;
-    }
-    else if ((p[0] & 0xf0) == 0xe0            // 3 character:
-          && (p[1] & 0xc0) == 0x80
-          && (p[2] & 0xc0) == 0x80)
-    {
-        c = ((p[0] & 0x0f) << 12)
-          | ((p[1] & 0x3f) << 6)
-          |  (p[2] & 0x3f);
-        *ptr += 3;
-    }
-    else if ((p[0] & 0xf8) == 0xf0            // 4 character:
-          && (p[1] & 0xc0) == 0x80
-          && (p[2] & 0xc0) == 0x80
-          && (p[3] & 0xc0) == 0x80)
-    {
-        c = ((p[0] & 0x07) << 18)
-          | ((p[1] & 0x3f) << 12)
-          | ((p[2] & 0x3f) << 6)
-          |  (p[3] & 0x3f);
-        *ptr += 4;
-    }
-    else
-    {
-        // Decode failure.
-        // Don't bother with 5/6 byte sequences.
-
-        c = 0;
-    }
-
-    return c;
-}
-
 static void PutUnicodeChar(unsigned int c)
 {
     unsigned int i;
@@ -389,7 +338,7 @@
 
         for (p = s; *p != '\0'; )
         {
-            c = DecodeUTF8(&p);
+            c = TXT_DecodeUTF8(&p);
 
             if (c == 0)
             {
@@ -406,7 +355,7 @@
         }
     }
 
-    TXT_GotoXY(x + strlen(s), y);
+    TXT_GotoXY(x + TXT_UTF8_Strlen(s), y);
 }
 
 void TXT_DrawHorizScrollbar(int x, int y, int w, int cursor, int range)
--- a/textscreen/txt_gui.h
+++ b/textscreen/txt_gui.h
@@ -34,6 +34,7 @@
 void TXT_DrawWindowFrame(const char *title, int x, int y, int w, int h);
 void TXT_DrawSeparator(int x, int y, int w);
 void TXT_DrawString(const char *s);
+void TXT_DrawUTF8String(const char *s);
 
 void TXT_DrawHorizScrollbar(int x, int y, int w, int cursor, int range);
 void TXT_DrawVertScrollbar(int x, int y, int h, int cursor, int range);
--- /dev/null
+++ b/textscreen/txt_utf8.c
@@ -1,0 +1,160 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2012 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "txt_utf8.h"
+
+// Encode a Unicode character as UTF-8, storing it in the buffer 'p'
+// and returning the new, incremented position.
+
+char *TXT_EncodeUTF8(char *p, unsigned int c)
+{
+    if (c < 0x80)                             // 1 character (ASCII):
+    {
+        p[0] = c;
+        return p + 1;
+    }
+    else if (c < 0x800)                       // 2 character:
+    {
+        p[0] = 0xc0 | (c >> 6);
+        p[1] = 0x80 | (c & 0x3f);
+        return p + 2;
+    }
+    else if (c < 0x10000)                     // 3 chacater:
+    {
+        p[0] = 0xe0 | (c >> 12);
+        p[1] = 0x80 | ((c >> 6) & 0x3f);
+        p[2] = 0x80 | (c & 0x3f);
+        return p + 3;
+    }
+    else if (c < 0x200000)                    // 4 character:
+    {
+        p[0] = 0xf0 | (c >> 18);
+        p[1] = 0x80 | ((c >> 12) & 0x3f);
+        p[2] = 0x80 | ((c >> 6) & 0x3f);
+        p[3] = 0x80 | (c & 0x3f);
+        return p + 4;
+    }
+    else
+    {
+        // Too big!
+
+        return p;
+    }
+}
+
+// Decode UTF-8 character, incrementing *ptr over the decoded bytes.
+
+unsigned int TXT_DecodeUTF8(const char **ptr)
+{
+    const char *p = *ptr;
+    unsigned int c;
+
+    // UTF-8 decode.
+
+    if ((*p & 0x80) == 0)                     // 1 character (ASCII):
+    {
+        c = *p;
+        *ptr += 1;
+    }
+    else if ((p[0] & 0xe0) == 0xc0            // 2 character:
+          && (p[1] & 0xc0) == 0x80)
+    {
+        c = ((p[0] & 0x1f) << 6)
+          |  (p[1] & 0x3f);
+        *ptr += 2;
+    }
+    else if ((p[0] & 0xf0) == 0xe0            // 3 character:
+          && (p[1] & 0xc0) == 0x80
+          && (p[2] & 0xc0) == 0x80)
+    {
+        c = ((p[0] & 0x0f) << 12)
+          | ((p[1] & 0x3f) << 6)
+          |  (p[2] & 0x3f);
+        *ptr += 3;
+    }
+    else if ((p[0] & 0xf8) == 0xf0            // 4 character:
+          && (p[1] & 0xc0) == 0x80
+          && (p[2] & 0xc0) == 0x80
+          && (p[3] & 0xc0) == 0x80)
+    {
+        c = ((p[0] & 0x07) << 18)
+          | ((p[1] & 0x3f) << 12)
+          | ((p[2] & 0x3f) << 6)
+          |  (p[3] & 0x3f);
+        *ptr += 4;
+    }
+    else
+    {
+        // Decode failure.
+        // Don't bother with 5/6 byte sequences.
+
+        c = 0;
+    }
+
+    return c;
+}
+
+// Count the number of characters in a UTF-8 string.
+
+unsigned int TXT_UTF8_Strlen(const char *s)
+{
+    const char *p;
+    unsigned int result = 0;
+    unsigned int c;
+
+    for (p = s; *p != '\0';)
+    {
+        c = TXT_DecodeUTF8(&p);
+
+        if (c == 0)
+        {
+            break;
+        }
+
+        ++result;
+    }
+
+    return result;
+}
+
+// Skip past the first n characters in a UTF-8 string.
+
+char *TXT_UTF8_SkipChars(const char *s, unsigned int n)
+{
+    unsigned int i;
+    const char *p;
+
+    p = s;
+
+    for (i = 0; i < n; ++i)
+    {
+        if (TXT_DecodeUTF8(&p) == 0)
+        {
+            break;
+        }
+    }
+
+    return (char *) p;
+}
+
--- /dev/null
+++ b/textscreen/txt_utf8.h
@@ -1,0 +1,31 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2012 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+
+#ifndef TXT_UTF8_H
+#define TXT_UTF8_H
+
+char *TXT_EncodeUTF8(char *p, unsigned int c);
+unsigned int TXT_DecodeUTF8(const char **ptr);
+unsigned int TXT_UTF8_Strlen(const char *s);
+char *TXT_UTF8_SkipChars(const char *s, unsigned int n);
+
+#endif /* #ifndef TXT_UTF8_H */
+