Implement unicode normalization
authorP. F. Chimento <philip.chimento@gmail.com>
Wed, 20 Apr 2011 11:57:10 +0000 (13:57 +0200)
committerP. F. Chimento <philip.chimento@gmail.com>
Wed, 20 Apr 2011 11:57:10 +0000 (13:57 +0200)
Unicode decomposition and normalization are now implemented.

libchimara/case.c
libchimara/gestalt.c

index 1b6eed72ba68fddcc6d7c2aa279b048827e34bad..5b1a5d755edadc1eddc6beeda73a880ac7860bc7 100644 (file)
@@ -1,5 +1,7 @@
-#include <gtk/gtk.h>
+#include <string.h>
+#include <glib.h>
 #include "glk.h"
 #include "glk.h"
+#include "charset.h"
 
 /**
  * glk_char_to_lower:
 
 /**
  * glk_char_to_lower:
@@ -193,8 +195,24 @@ glk_buffer_canon_decompose_uni(glui32 *buf, glui32 len, glui32 numchars)
        g_return_val_if_fail(buf != NULL && (len > 0 || numchars > 0), 0);
        g_return_val_if_fail(numchars <= len, 0);
 
        g_return_val_if_fail(buf != NULL && (len > 0 || numchars > 0), 0);
        g_return_val_if_fail(numchars <= len, 0);
 
-       /* TODO: Implement this */
-       return numchars;
+       long outchars;
+
+       /* Normalize the string */
+       char *utf8 = convert_ucs4_to_utf8(buf, numchars);
+       if(!utf8)
+               return numchars;
+       char *decomposed = g_utf8_normalize(utf8, -1, G_NORMALIZE_NFD);
+       g_free(utf8);
+       gunichar *outbuf = convert_utf8_to_ucs4(decomposed, &outchars);
+       g_free(decomposed);
+       if(!outbuf)
+               return numchars;
+
+       /* Copy the output buffer to the original buffer */
+       memcpy(buf, outbuf, MIN(outchars, len) * 4);
+       g_free(outbuf);
+
+       return outchars;
 }
 
 /**
 }
 
 /**
@@ -255,6 +273,22 @@ glk_buffer_canon_normalize_uni(glui32 *buf, glui32 len, glui32 numchars)
        g_return_val_if_fail(buf != NULL && (len > 0 || numchars > 0), 0);
        g_return_val_if_fail(numchars <= len, 0);
 
        g_return_val_if_fail(buf != NULL && (len > 0 || numchars > 0), 0);
        g_return_val_if_fail(numchars <= len, 0);
 
-       /* TODO: Implement this */
-       return numchars;
+       long outchars;
+
+       /* Normalize the string */
+       char *utf8 = convert_ucs4_to_utf8(buf, numchars);
+       if(!utf8)
+               return numchars;
+       char *decomposed = g_utf8_normalize(utf8, -1, G_NORMALIZE_NFC);
+       g_free(utf8);
+       gunichar *outbuf = convert_utf8_to_ucs4(decomposed, &outchars);
+       g_free(decomposed);
+       if(!outbuf)
+               return numchars;
+
+       /* Copy the output buffer to the original buffer */
+       memcpy(buf, outbuf, MIN(outchars, len) * 4);
+       g_free(outbuf);
+
+       return outchars;
 }
 }
index eef77489990aae324282325892a387e94a239f38..13193fcc6c485742903595e89038c9ea23a98980 100644 (file)
@@ -115,6 +115,7 @@ glk_gestalt_ext(glui32 sel, glui32 val, glui32 *arr, glui32 arrlen)
                case gestalt_Graphics:
                case gestalt_GraphicsTransparency:
                case gestalt_DateTime:
                case gestalt_Graphics:
                case gestalt_GraphicsTransparency:
                case gestalt_DateTime:
+               case gestalt_UnicodeNorm:
                        return 1;
 
                /* Capabilities supported if compiled with GStreamer */
                        return 1;
 
                /* Capabilities supported if compiled with GStreamer */
@@ -132,7 +133,6 @@ glk_gestalt_ext(glui32 sel, glui32 val, glui32 *arr, glui32 arrlen)
                case gestalt_LineInputEcho:
                case gestalt_LineTerminatorKey:
                case gestalt_LineTerminators:
                case gestalt_LineInputEcho:
                case gestalt_LineTerminatorKey:
                case gestalt_LineTerminators:
-               case gestalt_UnicodeNorm:
                /* Selector not supported */    
                default:
                        return 0;
                /* Selector not supported */    
                default:
                        return 0;