Index: GNUmakefile.am
===================================================================
--- Webkit-38858/GNUmakefile.am	(revision 38858)
+++ Webkit-38858.working/GNUmakefile.am	(working copy)
@@ -50,8 +50,15 @@ IDL_BINDINGS :=
 # Global flags to CPP
 global_cppflags :=

+if USE_ICU_UNICODE
 global_cppflags += \
 	-DWTF_USE_ICU_UNICODE=1
+endif
+
+if USE_GLIB_UNICODE
+global_cppflags += \
+	-DWTF_USE_GLIB_UNICODE=1
+endif

 # Default compiler flags
 global_cflags := \
Index: configure.ac
===================================================================
--- Webkit-38858/configure.ac	(revision 38858)
+++ Webkit-38858.working/configure.ac	(working copy)
@@ -222,18 +222,18 @@ AC_SUBST([PNG_LIBS])
 # determine the Unicode backend
 AC_MSG_CHECKING([the Unicode backend to use])
 AC_ARG_WITH(unicode_backend,
-            AC_HELP_STRING([--with-unicode-backend=@<:@icu@:>@],
+            AC_HELP_STRING([--with-unicode-backend=@<:@icu/glib@:>@],
                            [Select Unicode backend [default=icu]]),
-            [],[unicode_backend="icu"])
+            [],[with_unicode_backend="icu"])

-case "$unicode_backend" in
-     icu) ;;
-     *) AC_MSG_ERROR([Invalid Unicode backend: must be icu.]) ;;
+case "$with_unicode_backend" in
+     icu|glib) ;;
+     *) AC_MSG_ERROR([Invalid Unicode backend: must be icu or glib.]) ;;
 esac

-AC_MSG_RESULT([$unicode_backend])
+AC_MSG_RESULT([$with_unicode_backend])

-if test "$unicode_backend" = "icu"; then
+if test "$with_unicode_backend" = "icu"; then
 	if test "$os_darwin" = "yes"; then
 		UNICODE_CFLAGS="-I\$(srcdir)/JavaScriptCore/icu -I\$(srcdir)/WebCore/icu"
 		UNICODE_LIBS="-licucore"
@@ -254,6 +254,18 @@ if test "$unicode_backend" = "icu"; then
 	fi
 fi

+if test "$with_unicode_backend" = "glib"; then
+	PKG_CHECK_MODULES([UNICODE], [glib-2.0 pango >= 1.21.0])
+	AC_MSG_CHECKING([for libidn])
+	AC_CHECK_HEADER(idna.h,
+		AC_CHECK_LIB(idn, stringprep_check_version,
+			[libidn=yes UNICODE_LIBS="${UNICODE_LIBS} -lidn"], libidn=no),
+		libidn=no)
+	if test "$libidn" = "no" ; then
+		AC_MSG_ERROR([Libidn not found, needed for GLib unicode backend.])
+	fi
+fi
+
 AC_SUBST([UNICODE_CFLAGS])
 AC_SUBST([UNICODE_LIBS])

@@ -708,6 +720,10 @@ AM_CONDITIONAL([TARGET_WIN32], [test "$w
 AM_CONDITIONAL([TARGET_QUARTZ], [test "$with_target" = "quartz"])
 AM_CONDITIONAL([TARGET_DIRECTFB], [test "$with_target" = "directfb"])

+# Unicode backend conditionals
+AM_CONDITIONAL([USE_ICU_UNICODE], [test "$with_unicode_backend" = "icu"])
+AM_CONDITIONAL([USE_GLIB_UNICODE], [test "$with_unicode_backend" = "glib"])
+
 # HTTP backend conditionals
 AM_CONDITIONAL([USE_CURL], [test "$with_http_backend" = "curl"])
 AM_CONDITIONAL([USE_SOUP], [test "$with_http_backend" = "soup"])
@@ -757,7 +773,7 @@ Build configuration:
  Enable debugging (slow)                                  : $enable_debug
  Enable GCC build optimization                            : $enable_optimizations
  Code coverage support                                    : $enable_coverage
- Unicode backend                                          : $unicode_backend
+ Unicode backend                                          : $with_unicode_backend
  HTTP backend                                             : $with_http_backend
  Font backend                                             : $with_font_backend
  Optimized memory allocator                               : $enable_fast_malloc
Index: JavaScriptCore/GNUmakefile.am
===================================================================
--- Webkit-38858/JavaScriptCore/GNUmakefile.am	(revision 38858)
+++ Webkit-38858.working/JavaScriptCore/GNUmakefile.am	(working copy)
@@ -229,9 +229,27 @@ javascriptcore_sources += \
 	JavaScriptCore/wtf/unicode/CollatorDefault.cpp \
 	JavaScriptCore/wtf/unicode/UTF8.cpp \
 	JavaScriptCore/wtf/unicode/UTF8.h \
-	JavaScriptCore/wtf/unicode/Unicode.h \
+	JavaScriptCore/wtf/unicode/Unicode.h
+
+# ----
+# icu unicode backend
+# ----
+if USE_ICU_UNICODE
+javascriptcore_sources += \
 	JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp \
 	JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
+endif # USE_ICU_UNICODE
+
+# ----
+# glib unicode backend
+# ----
+if USE_GLIB_UNICODE
+javascriptcore_sources += \
+	JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h \
+	JavaScriptCore/wtf/unicode/glib/UnicodeGLibTypes.h \
+	JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h \
+	JavaScriptCore/wtf/unicode/glib/CasefoldTableFromGLib.h
+endif

 # Debug build
 if ENABLE_DEBUG
Index: JavaScriptCore/wtf/unicode/Unicode.h
===================================================================
--- Webkit-38858/JavaScriptCore/wtf/unicode/Unicode.h	(revision 38858)
+++ Webkit-38858.working/JavaScriptCore/wtf/unicode/Unicode.h	(working copy)
@@ -28,6 +28,8 @@
 #include "qt4/UnicodeQt4.h"
 #elif USE(ICU_UNICODE)
 #include <wtf/unicode/icu/UnicodeIcu.h>
+#elif USE(GLIB_UNICODE)
+#include <wtf/unicode/glib/UnicodeGLib.h>
 #else
 #error "Unknown Unicode implementation"
 #endif
Index: JavaScriptCore/wtf/unicode/glib/CasefoldTableFromGLib.h
===================================================================
--- Webkit-38858/JavaScriptCore/wtf/unicode/glib/CasefoldTableFromGLib.h	(revision 0)
+++ Webkit-38858.working/JavaScriptCore/wtf/unicode/glib/CasefoldTableFromGLib.h	(revision 0)
@@ -0,0 +1,200 @@
+/*
+ *  Copyright (C) 2006 George Staikos <staikos@kde.org>
+ *  Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ *  Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
+ *  Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ *  Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef CasefoldTableFromGLib_h
+#define CasefoldTableFromGLib_h
+
+#include <glib.h>
+
+// copied from GLib
+
+/* Table of casefolding cases that can't be derived by lowercasing
+ */
+static const struct {
+    guint16 ch;
+    gchar data[7];
+} casefold_table[] = {
+    { 0x00b5, "\xce\xbc" },
+    { 0x00df, "\x73\x73" },
+    { 0x0130, "\x69\xcc\x87" },
+    { 0x0149, "\xca\xbc\x6e" },
+    { 0x017f, "\x73" },
+    { 0x01f0, "\x6a\xcc\x8c" },
+    { 0x0345, "\xce\xb9" },
+    { 0x0390, "\xce\xb9\xcc\x88\xcc\x81" },
+    { 0x03b0, "\xcf\x85\xcc\x88\xcc\x81" },
+    { 0x03c2, "\xcf\x83" },
+    { 0x03d0, "\xce\xb2" },
+    { 0x03d1, "\xce\xb8" },
+    { 0x03d5, "\xcf\x86" },
+    { 0x03d6, "\xcf\x80" },
+    { 0x03f0, "\xce\xba" },
+    { 0x03f1, "\xcf\x81" },
+    { 0x03f5, "\xce\xb5" },
+    { 0x0587, "\xd5\xa5\xd6\x82" },
+    { 0x1e96, "\x68\xcc\xb1" },
+    { 0x1e97, "\x74\xcc\x88" },
+    { 0x1e98, "\x77\xcc\x8a" },
+    { 0x1e99, "\x79\xcc\x8a" },
+    { 0x1e9a, "\x61\xca\xbe" },
+    { 0x1e9b, "\xe1\xb9\xa1" },
+    { 0x1f50, "\xcf\x85\xcc\x93" },
+    { 0x1f52, "\xcf\x85\xcc\x93\xcc\x80" },
+    { 0x1f54, "\xcf\x85\xcc\x93\xcc\x81" },
+    { 0x1f56, "\xcf\x85\xcc\x93\xcd\x82" },
+    { 0x1f80, "\xe1\xbc\x80\xce\xb9" },
+    { 0x1f81, "\xe1\xbc\x81\xce\xb9" },
+    { 0x1f82, "\xe1\xbc\x82\xce\xb9" },
+    { 0x1f83, "\xe1\xbc\x83\xce\xb9" },
+    { 0x1f84, "\xe1\xbc\x84\xce\xb9" },
+    { 0x1f85, "\xe1\xbc\x85\xce\xb9" },
+    { 0x1f86, "\xe1\xbc\x86\xce\xb9" },
+    { 0x1f87, "\xe1\xbc\x87\xce\xb9" },
+    { 0x1f88, "\xe1\xbc\x80\xce\xb9" },
+    { 0x1f89, "\xe1\xbc\x81\xce\xb9" },
+    { 0x1f8a, "\xe1\xbc\x82\xce\xb9" },
+    { 0x1f8b, "\xe1\xbc\x83\xce\xb9" },
+    { 0x1f8c, "\xe1\xbc\x84\xce\xb9" },
+    { 0x1f8d, "\xe1\xbc\x85\xce\xb9" },
+    { 0x1f8e, "\xe1\xbc\x86\xce\xb9" },
+    { 0x1f8f, "\xe1\xbc\x87\xce\xb9" },
+    { 0x1f90, "\xe1\xbc\xa0\xce\xb9" },
+    { 0x1f91, "\xe1\xbc\xa1\xce\xb9" },
+    { 0x1f92, "\xe1\xbc\xa2\xce\xb9" },
+    { 0x1f93, "\xe1\xbc\xa3\xce\xb9" },
+    { 0x1f94, "\xe1\xbc\xa4\xce\xb9" },
+    { 0x1f95, "\xe1\xbc\xa5\xce\xb9" },
+    { 0x1f96, "\xe1\xbc\xa6\xce\xb9" },
+    { 0x1f97, "\xe1\xbc\xa7\xce\xb9" },
+    { 0x1f98, "\xe1\xbc\xa0\xce\xb9" },
+    { 0x1f99, "\xe1\xbc\xa1\xce\xb9" },
+    { 0x1f9a, "\xe1\xbc\xa2\xce\xb9" },
+    { 0x1f9b, "\xe1\xbc\xa3\xce\xb9" },
+    { 0x1f9c, "\xe1\xbc\xa4\xce\xb9" },
+    { 0x1f9d, "\xe1\xbc\xa5\xce\xb9" },
+    { 0x1f9e, "\xe1\xbc\xa6\xce\xb9" },
+    { 0x1f9f, "\xe1\xbc\xa7\xce\xb9" },
+    { 0x1fa0, "\xe1\xbd\xa0\xce\xb9" },
+    { 0x1fa1, "\xe1\xbd\xa1\xce\xb9" },
+    { 0x1fa2, "\xe1\xbd\xa2\xce\xb9" },
+    { 0x1fa3, "\xe1\xbd\xa3\xce\xb9" },
+    { 0x1fa4, "\xe1\xbd\xa4\xce\xb9" },
+    { 0x1fa5, "\xe1\xbd\xa5\xce\xb9" },
+    { 0x1fa6, "\xe1\xbd\xa6\xce\xb9" },
+    { 0x1fa7, "\xe1\xbd\xa7\xce\xb9" },
+    { 0x1fa8, "\xe1\xbd\xa0\xce\xb9" },
+    { 0x1fa9, "\xe1\xbd\xa1\xce\xb9" },
+    { 0x1faa, "\xe1\xbd\xa2\xce\xb9" },
+    { 0x1fab, "\xe1\xbd\xa3\xce\xb9" },
+    { 0x1fac, "\xe1\xbd\xa4\xce\xb9" },
+    { 0x1fad, "\xe1\xbd\xa5\xce\xb9" },
+    { 0x1fae, "\xe1\xbd\xa6\xce\xb9" },
+    { 0x1faf, "\xe1\xbd\xa7\xce\xb9" },
+    { 0x1fb2, "\xe1\xbd\xb0\xce\xb9" },
+    { 0x1fb3, "\xce\xb1\xce\xb9" },
+    { 0x1fb4, "\xce\xac\xce\xb9" },
+    { 0x1fb6, "\xce\xb1\xcd\x82" },
+    { 0x1fb7, "\xce\xb1\xcd\x82\xce\xb9" },
+    { 0x1fbc, "\xce\xb1\xce\xb9" },
+    { 0x1fbe, "\xce\xb9" },
+    { 0x1fc2, "\xe1\xbd\xb4\xce\xb9" },
+    { 0x1fc3, "\xce\xb7\xce\xb9" },
+    { 0x1fc4, "\xce\xae\xce\xb9" },
+    { 0x1fc6, "\xce\xb7\xcd\x82" },
+    { 0x1fc7, "\xce\xb7\xcd\x82\xce\xb9" },
+    { 0x1fcc, "\xce\xb7\xce\xb9" },
+    { 0x1fd2, "\xce\xb9\xcc\x88\xcc\x80" },
+    { 0x1fd3, "\xce\xb9\xcc\x88\xcc\x81" },
+    { 0x1fd6, "\xce\xb9\xcd\x82" },
+    { 0x1fd7, "\xce\xb9\xcc\x88\xcd\x82" },
+    { 0x1fe2, "\xcf\x85\xcc\x88\xcc\x80" },
+    { 0x1fe3, "\xcf\x85\xcc\x88\xcc\x81" },
+    { 0x1fe4, "\xcf\x81\xcc\x93" },
+    { 0x1fe6, "\xcf\x85\xcd\x82" },
+    { 0x1fe7, "\xcf\x85\xcc\x88\xcd\x82" },
+    { 0x1ff2, "\xe1\xbd\xbc\xce\xb9" },
+    { 0x1ff3, "\xcf\x89\xce\xb9" },
+    { 0x1ff4, "\xcf\x8e\xce\xb9" },
+    { 0x1ff6, "\xcf\x89\xcd\x82" },
+    { 0x1ff7, "\xcf\x89\xcd\x82\xce\xb9" },
+    { 0x1ffc, "\xcf\x89\xce\xb9" },
+    { 0x2160, "\xe2\x85\xb0" },
+    { 0x2161, "\xe2\x85\xb1" },
+    { 0x2162, "\xe2\x85\xb2" },
+    { 0x2163, "\xe2\x85\xb3" },
+    { 0x2164, "\xe2\x85\xb4" },
+    { 0x2165, "\xe2\x85\xb5" },
+    { 0x2166, "\xe2\x85\xb6" },
+    { 0x2167, "\xe2\x85\xb7" },
+    { 0x2168, "\xe2\x85\xb8" },
+    { 0x2169, "\xe2\x85\xb9" },
+    { 0x216a, "\xe2\x85\xba" },
+    { 0x216b, "\xe2\x85\xbb" },
+    { 0x216c, "\xe2\x85\xbc" },
+    { 0x216d, "\xe2\x85\xbd" },
+    { 0x216e, "\xe2\x85\xbe" },
+    { 0x216f, "\xe2\x85\xbf" },
+    { 0x24b6, "\xe2\x93\x90" },
+    { 0x24b7, "\xe2\x93\x91" },
+    { 0x24b8, "\xe2\x93\x92" },
+    { 0x24b9, "\xe2\x93\x93" },
+    { 0x24ba, "\xe2\x93\x94" },
+    { 0x24bb, "\xe2\x93\x95" },
+    { 0x24bc, "\xe2\x93\x96" },
+    { 0x24bd, "\xe2\x93\x97" },
+    { 0x24be, "\xe2\x93\x98" },
+    { 0x24bf, "\xe2\x93\x99" },
+    { 0x24c0, "\xe2\x93\x9a" },
+    { 0x24c1, "\xe2\x93\x9b" },
+    { 0x24c2, "\xe2\x93\x9c" },
+    { 0x24c3, "\xe2\x93\x9d" },
+    { 0x24c4, "\xe2\x93\x9e" },
+    { 0x24c5, "\xe2\x93\x9f" },
+    { 0x24c6, "\xe2\x93\xa0" },
+    { 0x24c7, "\xe2\x93\xa1" },
+    { 0x24c8, "\xe2\x93\xa2" },
+    { 0x24c9, "\xe2\x93\xa3" },
+    { 0x24ca, "\xe2\x93\xa4" },
+    { 0x24cb, "\xe2\x93\xa5" },
+    { 0x24cc, "\xe2\x93\xa6" },
+    { 0x24cd, "\xe2\x93\xa7" },
+    { 0x24ce, "\xe2\x93\xa8" },
+    { 0x24cf, "\xe2\x93\xa9" },
+    { 0xfb00, "\x66\x66" },
+    { 0xfb01, "\x66\x69" },
+    { 0xfb02, "\x66\x6c" },
+    { 0xfb03, "\x66\x66\x69" },
+    { 0xfb04, "\x66\x66\x6c" },
+    { 0xfb05, "\x73\x74" },
+    { 0xfb06, "\x73\x74" },
+    { 0xfb13, "\xd5\xb4\xd5\xb6" },
+    { 0xfb14, "\xd5\xb4\xd5\xa5" },
+    { 0xfb15, "\xd5\xb4\xd5\xab" },
+    { 0xfb16, "\xd5\xbe\xd5\xb6" },
+    { 0xfb17, "\xd5\xb4\xd5\xad" }
+};
+
+
+#endif
+
Index: JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
===================================================================
--- Webkit-38858/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h	(revision 0)
+++ Webkit-38858.working/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h	(revision 0)
@@ -0,0 +1,399 @@
+/*
+ *  Copyright (C) 2006 George Staikos <staikos@kde.org>
+ *  Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ *  Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
+ *  Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ *  Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef UnicodeGLib_h
+#define UnicodeGLib_h
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <glib.h>
+#include <pango/pango.h>
+
+#include <wtf/GOwnPtr.h>
+
+#include "CasefoldTableFromGLib.h"
+#include "UnicodeGLibTypes.h"
+#include "UnicodeMacrosFromICU.h"
+
+namespace WTF {
+    namespace Unicode {
+
+        enum Direction {
+            LeftToRight,
+            RightToLeft,
+            EuropeanNumber,
+            EuropeanNumberSeparator,
+            EuropeanNumberTerminator,
+            ArabicNumber,
+            CommonNumberSeparator,
+            BlockSeparator,
+            SegmentSeparator,
+            WhiteSpaceNeutral,
+            OtherNeutral,
+            LeftToRightEmbedding,
+            LeftToRightOverride,
+            RightToLeftArabic,
+            RightToLeftEmbedding,
+            RightToLeftOverride,
+            PopDirectionalFormat,
+            NonSpacingMark,
+            BoundaryNeutral
+        };
+
+        enum DecompositionType {
+            DecompositionNone,
+            DecompositionCanonical,
+            DecompositionCompat,
+            DecompositionCircle,
+            DecompositionFinal,
+            DecompositionFont,
+            DecompositionFraction,
+            DecompositionInitial,
+            DecompositionIsolated,
+            DecompositionMedial,
+            DecompositionNarrow,
+            DecompositionNoBreak,
+            DecompositionSmall,
+            DecompositionSquare,
+            DecompositionSub,
+            DecompositionSuper,
+            DecompositionVertical,
+            DecompositionWide,
+        };
+
+        enum CharCategory {
+            NoCategory =  0,
+            Other_NotAssigned = U_MASK(G_UNICODE_UNASSIGNED),
+            Letter_Uppercase = U_MASK(G_UNICODE_UPPERCASE_LETTER),
+            Letter_Lowercase = U_MASK(G_UNICODE_LOWERCASE_LETTER),
+            Letter_Titlecase = U_MASK(G_UNICODE_TITLECASE_LETTER),
+            Letter_Modifier = U_MASK(G_UNICODE_MODIFIER_LETTER),
+            Letter_Other = U_MASK(G_UNICODE_OTHER_LETTER),
+
+            Mark_NonSpacing = U_MASK(G_UNICODE_NON_SPACING_MARK),
+            Mark_Enclosing = U_MASK(G_UNICODE_ENCLOSING_MARK),
+            Mark_SpacingCombining = U_MASK(G_UNICODE_COMBINING_MARK),
+
+            Number_DecimalDigit = U_MASK(G_UNICODE_DECIMAL_NUMBER),
+            Number_Letter = U_MASK(G_UNICODE_LETTER_NUMBER),
+            Number_Other = U_MASK(G_UNICODE_OTHER_NUMBER),
+
+            Separator_Space = U_MASK(G_UNICODE_SPACE_SEPARATOR),
+            Separator_Line = U_MASK(G_UNICODE_LINE_SEPARATOR),
+            Separator_Paragraph = U_MASK(G_UNICODE_PARAGRAPH_SEPARATOR),
+
+            Other_Control = U_MASK(G_UNICODE_CONTROL),
+            Other_Format = U_MASK(G_UNICODE_FORMAT),
+            Other_PrivateUse = U_MASK(G_UNICODE_PRIVATE_USE),
+            Other_Surrogate = U_MASK(G_UNICODE_SURROGATE),
+
+            Punctuation_Dash = U_MASK(G_UNICODE_DASH_PUNCTUATION),
+            Punctuation_Open = U_MASK(G_UNICODE_OPEN_PUNCTUATION),
+            Punctuation_Close = U_MASK(G_UNICODE_CLOSE_PUNCTUATION),
+            Punctuation_Connector = U_MASK(G_UNICODE_CONNECT_PUNCTUATION),
+            Punctuation_Other = U_MASK(G_UNICODE_OTHER_PUNCTUATION),
+
+            Symbol_Math = U_MASK(G_UNICODE_MATH_SYMBOL),
+            Symbol_Currency = U_MASK(G_UNICODE_CURRENCY_SYMBOL),
+            Symbol_Modifier = U_MASK(G_UNICODE_MODIFIER_SYMBOL),
+            Symbol_Other = U_MASK(G_UNICODE_OTHER_SYMBOL),
+
+            Punctuation_InitialQuote = U_MASK(G_UNICODE_INITIAL_PUNCTUATION),
+            Punctuation_FinalQuote = U_MASK(G_UNICODE_FINAL_PUNCTUATION)
+        };
+
+        inline UChar32 foldCase(UChar32 ch)
+        {
+            // add g_unichar_casefold to GLib upstream?
+
+            int start = 0;
+            int end = G_N_ELEMENTS(casefold_table);
+
+            if (ch >= casefold_table[start].ch &&
+                ch <= casefold_table[end - 1].ch) {
+                while (true) {
+                    int half = (start + end) / 2;
+                    if (ch == casefold_table[half].ch)
+                        return g_utf8_get_char(casefold_table[half].data);
+                    if (half == start)
+                        break;
+                    else if (ch > casefold_table[half].ch)
+                        start = half;
+                    else
+                        end = half;
+                }
+            }
+
+            return g_unichar_tolower (ch);
+        }
+
+        inline int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
+        {
+            *error = false;
+            GOwnPtr<GError> gerror;
+
+            GOwnPtr<char> utf8src;
+            utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr()));
+            if (gerror) {
+                *error = true;
+                return -1;
+            }
+
+            GOwnPtr<char> utf8result;
+            utf8result.set(g_utf8_casefold(utf8src.get(), -1));
+
+            long utf16resultLength = -1;
+            GOwnPtr<UChar> utf16result;
+            utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr()));
+            if (gerror) {
+                *error = true;
+                return -1;
+            }
+
+            if (utf16resultLength > resultLength) {
+                *error = true;
+                return utf16resultLength;
+            }
+            memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar));
+
+            return utf16resultLength;
+        }
+
+        inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
+        {
+            *error = false;
+            GOwnPtr<GError> gerror;
+
+            GOwnPtr<char> utf8src;
+            utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr()));
+            if (gerror) {
+                *error = true;
+                return -1;
+            }
+
+            GOwnPtr<char> utf8result;
+            utf8result.set(g_utf8_strdown(utf8src.get(), -1));
+
+            long utf16resultLength = -1;
+            GOwnPtr<UChar> utf16result;
+            utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr()));
+            if (gerror) {
+                *error = true;
+                return -1;
+            }
+
+            if (utf16resultLength > resultLength) {
+                *error = true;
+                return utf16resultLength;
+            }
+            memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar));
+
+            return utf16resultLength;
+        }
+
+        inline UChar32 toLower(UChar32 c)
+        {
+            return g_unichar_tolower(c);
+        }
+
+        inline UChar32 toUpper(UChar32 c)
+        {
+            return g_unichar_toupper(c);
+        }
+
+        inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
+        {
+            *error = false;
+            GOwnPtr<GError> gerror;
+
+            GOwnPtr<char> utf8src;
+            utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr()));
+            if (gerror) {
+                *error = true;
+                return -1;
+            }
+
+            GOwnPtr<char> utf8result;
+            utf8result.set(g_utf8_strup(utf8src.get(), -1));
+
+            long utf16resultLength = -1;
+            GOwnPtr<UChar> utf16result;
+            utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr()));
+            if (gerror) {
+                *error = true;
+                return -1;
+            }
+
+            if (utf16resultLength > resultLength) {
+                *error = true;
+                return utf16resultLength;
+            }
+            memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar));
+
+            return utf16resultLength;
+        }
+
+        inline UChar32 toTitleCase(UChar32 c)
+        {
+            return g_unichar_totitle(c);
+        }
+
+        inline bool isArabicChar(UChar32 c)
+        {
+            return c >= 0x0600 && c <= 0x06FF;
+        }
+
+        inline bool isFormatChar(UChar32 c)
+        {
+            return g_unichar_type(c) == G_UNICODE_FORMAT;
+        }
+
+        inline bool isSeparatorSpace(UChar32 c)
+        {
+            return g_unichar_type(c) == G_UNICODE_SPACE_SEPARATOR;
+        }
+
+        inline bool isPrintableChar(UChar32 c)
+        {
+            return g_unichar_isprint(c);
+        }
+
+        inline bool isDigit(UChar32 c)
+        {
+            return g_unichar_isdigit(c);
+        }
+
+        inline bool isPunct(UChar32 c)
+        {
+            return g_unichar_ispunct(c);
+        }
+
+        inline UChar32 mirroredChar(UChar32 c)
+        {
+            gunichar mirror = 0;
+            g_unichar_get_mirror_char(c, &mirror);
+            return mirror;
+        }
+
+        inline CharCategory category(UChar32 c)
+        {
+            if (c > 0xffff)
+                return NoCategory;
+
+            return (CharCategory) U_MASK(g_unichar_type(c));
+        }
+
+        inline Direction direction(UChar32 c)
+        {
+            PangoBidiType type = pango_bidi_type_for_unichar(c);
+            switch (type) {
+            case PANGO_BIDI_TYPE_L:
+                return LeftToRight;
+            case PANGO_BIDI_TYPE_R:
+                return RightToLeft;
+            case PANGO_BIDI_TYPE_AL:
+                return RightToLeftArabic;
+            case PANGO_BIDI_TYPE_LRE:
+                return LeftToRightEmbedding;
+            case PANGO_BIDI_TYPE_RLE:
+                return RightToLeftEmbedding;
+            case PANGO_BIDI_TYPE_LRO:
+                return LeftToRightOverride;
+            case PANGO_BIDI_TYPE_RLO:
+                return RightToLeftOverride;
+            case PANGO_BIDI_TYPE_PDF:
+                return PopDirectionalFormat;
+            case PANGO_BIDI_TYPE_EN:
+                return EuropeanNumber;
+            case PANGO_BIDI_TYPE_AN:
+                return ArabicNumber;
+            case PANGO_BIDI_TYPE_ES:
+                return EuropeanNumberSeparator;
+            case PANGO_BIDI_TYPE_ET:
+                return EuropeanNumberTerminator;
+            case PANGO_BIDI_TYPE_CS:
+                return CommonNumberSeparator;
+            case PANGO_BIDI_TYPE_NSM:
+                return NonSpacingMark;
+            case PANGO_BIDI_TYPE_BN:
+                return BoundaryNeutral;
+            case PANGO_BIDI_TYPE_B:
+                return BlockSeparator;
+            case PANGO_BIDI_TYPE_S:
+                return SegmentSeparator;
+            case PANGO_BIDI_TYPE_WS:
+                return WhiteSpaceNeutral;
+            default:
+                return OtherNeutral;
+            }
+        }
+
+        inline bool isLower(UChar32 c)
+        {
+            return g_unichar_islower(c);
+        }
+
+        inline int digitValue(UChar32 c)
+        {
+            return g_unichar_digit_value(c);
+        }
+
+        inline uint8_t combiningClass(UChar32 c)
+        {
+            // return g_unichar_combining_class(c);
+            return 0;
+        }
+
+        inline DecompositionType decompositionType(UChar32 c)
+        {
+            // FIXME
+            return DecompositionNone;
+        }
+
+        inline int umemcasecmp(const UChar* a, const UChar* b, int len)
+        {
+            GOwnPtr<char> utf8a;
+            GOwnPtr<char> utf8b;
+
+            utf8a.set(g_utf16_to_utf8(a, len, 0, 0, 0));
+            utf8b.set(g_utf16_to_utf8(b, len, 0, 0, 0));
+
+            GOwnPtr<char> foldedA;
+            GOwnPtr<char> foldedB;
+
+            foldedA.set(g_utf8_casefold(utf8a.get(), -1));
+            foldedB.set(g_utf8_casefold(utf8b.get(), -1));
+
+            int result = g_utf8_collate(foldedA.get(), foldedB.get());
+
+            return result;
+        }
+
+    }
+}
+
+#endif
+
Index: JavaScriptCore/wtf/unicode/glib/UnicodeGLibTypes.h
===================================================================
--- Webkit-38858/JavaScriptCore/wtf/unicode/glib/UnicodeGLibTypes.h	(revision 0)
+++ Webkit-38858.working/JavaScriptCore/wtf/unicode/glib/UnicodeGLibTypes.h	(revision 0)
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (C) 2006 George Staikos <staikos@kde.org>
+ *  Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ *  Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
+ *  Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ *  Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef UnicodeGLibTypes_h
+#define UnicodeGLibTypes_h
+
+typedef uint16_t UChar;
+typedef int32_t UChar32;
+
+#endif
Index: JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h
===================================================================
--- Webkit-38858/JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h	(revision 0)
+++ Webkit-38858.working/JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h	(revision 0)
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 2006 George Staikos <staikos@kde.org>
+ *  Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ *  Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
+ *  Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ *  Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef UnicodeMacrosFromICU_h
+#define UnicodeMacrosFromICU_h
+
+// some defines from ICU
+
+#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
+#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
+#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
+#define U16_GET_SUPPLEMENTARY(lead, trail) \
+    (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET)
+
+#define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0)
+#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00)
+
+#define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800)
+#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
+#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)
+#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
+
+#define U16_NEXT(s, i, length, c) { \
+    (c)=(s)[(i)++]; \
+    if(U16_IS_LEAD(c)) { \
+        uint16_t __c2; \
+        if((i)<(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
+            ++(i); \
+            (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+        } \
+    } \
+}
+
+#define U_MASK(x) ((uint32_t)1<<(x))
+
+#endif
+
Index: WebCore/GNUmakefile.am
===================================================================
--- Webkit-38858/WebCore/GNUmakefile.am	(revision 38858)
+++ Webkit-38858.working/WebCore/GNUmakefile.am	(working copy)
@@ -1371,14 +1371,9 @@ webcore_sources += \
 	WebCore/platform/text/StringImpl.cpp \
 	WebCore/platform/text/StringImpl.h \
 	WebCore/platform/text/TextBoundaries.h \
-	WebCore/platform/text/TextBoundariesICU.cpp \
 	WebCore/platform/text/TextBreakIterator.h \
-	WebCore/platform/text/TextBreakIteratorICU.cpp \
-	WebCore/platform/text/TextBreakIteratorInternalICU.h \
 	WebCore/platform/text/TextCodec.cpp \
 	WebCore/platform/text/TextCodec.h \
-	WebCore/platform/text/TextCodecICU.cpp \
-	WebCore/platform/text/TextCodecICU.h \
 	WebCore/platform/text/TextCodecLatin1.cpp \
 	WebCore/platform/text/TextCodecLatin1.h \
 	WebCore/platform/text/TextCodecUTF16.cpp \
@@ -1731,8 +1726,31 @@ webcoregtk_sources += \
 	WebCore/platform/image-decoders/png/PNGImageDecoder.cpp \
 	WebCore/platform/image-decoders/png/PNGImageDecoder.h \
 	WebCore/platform/image-decoders/xbm/XBMImageDecoder.cpp \
-	WebCore/platform/image-decoders/xbm/XBMImageDecoder.h \
+	WebCore/platform/image-decoders/xbm/XBMImageDecoder.h
+
+# ----
+# icu unicode backend
+# ----
+if USE_ICU_UNICODE
+webcoregtk_sources += \
+	WebCore/platform/text/TextCodecICU.cpp \
+	WebCore/platform/text/TextCodecICU.h \
+	WebCore/platform/text/TextBoundariesICU.cpp \
+	WebCore/platform/text/TextBreakIteratorICU.cpp \
+	WebCore/platform/text/TextBreakIteratorInternalICU.h \
 	WebCore/platform/text/gtk/TextBreakIteratorInternalICUGtk.cpp
+endif # USE_ICU_UNICODE
+
+# ----
+# glib unicode backend
+# ----
+if USE_GLIB_UNICODE
+webcoregtk_sources += \
+	WebCore/platform/text/gtk/TextCodecGtk.cpp \
+	WebCore/platform/text/gtk/TextCodecGtk.h \
+	WebCore/platform/text/gtk/TextBoundariesGtk.cpp \
+	WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp
+endif

 # ----
 # curl http backend
Index: WebCore/platform/KURL.cpp
===================================================================
--- Webkit-38858/WebCore/platform/KURL.cpp	(revision 38858)
+++ Webkit-38858.working/WebCore/platform/KURL.cpp	(working copy)
@@ -35,6 +35,10 @@
 #include <unicode/uidna.h>
 #elif USE(QT4_UNICODE)
 #include <QUrl>
+#elif USE(GLIB_UNICODE)
+#include <glib.h>
+#include <idna.h>
+#include <wtf/GOwnPtr.h>
 #endif

 #include <stdio.h>
@@ -1339,6 +1343,19 @@ static void appendEncodedHostname(UCharB
 #elif USE(QT4_UNICODE)
     QByteArray result = QUrl::toAce(String(str, strLen));
     buffer.append(result.constData(), result.length());
+#elif USE(GLIB_UNICODE)
+    // first translate to ucs4, libidn is expecting code points
+    GOwnPtr<gunichar> ucs4Hostname;
+    GOwnPtr<GError> ucs4Err;
+    ucs4Hostname.set(g_utf16_to_ucs4(str, strLen, 0, 0, &ucs4Err.outPtr()));
+    if(ucs4Err)
+        return;
+    char* encodedHostname = 0;
+    int err;
+    err = idna_to_ascii_4z(ucs4Hostname.get(), &encodedHostname, IDNA_ALLOW_UNASSIGNED);
+    if(err == IDNA_SUCCESS)
+        buffer.append(encodedHostname, strlen(encodedHostname));
+    free(encodedHostname);
 #endif
 }

Index: WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
===================================================================
--- Webkit-38858/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp	(revision 38858)
+++ Webkit-38858.working/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp	(working copy)
@@ -39,8 +39,6 @@
 #include "FontDescription.h"
 #include "GlyphBuffer.h"
 #include <cairo.h>
-#include <unicode/uchar.h>
-#include <unicode/unorm.h>
 #include <wtf/MathExtras.h>

 namespace WebCore {
Index: WebCore/platform/text/TextBreakIterator.h
===================================================================
--- Webkit-38858/WebCore/platform/text/TextBreakIterator.h	(revision 38858)
+++ Webkit-38858.working/WebCore/platform/text/TextBreakIterator.h	(working copy)
@@ -35,7 +35,9 @@ namespace WebCore {
     TextBreakIterator* sentenceBreakIterator(const UChar*, int length);

     int textBreakFirst(TextBreakIterator*);
+    int textBreakLast(TextBreakIterator*);
     int textBreakNext(TextBreakIterator*);
+    int textBreakPrevious(TextBreakIterator*);
     int textBreakCurrent(TextBreakIterator*);
     int textBreakPreceding(TextBreakIterator*, int);
     int textBreakFollowing(TextBreakIterator*, int);
Index: WebCore/platform/text/TextBreakIteratorICU.cpp
===================================================================
--- Webkit-38858/WebCore/platform/text/TextBreakIteratorICU.cpp	(revision 38858)
+++ Webkit-38858.working/WebCore/platform/text/TextBreakIteratorICU.cpp	(working copy)
@@ -89,11 +89,21 @@ int textBreakFirst(TextBreakIterator* bi
     return ubrk_first(bi);
 }

+int textBreakLast(TextBreakIterator* bi)
+{
+    return ubrk_last(bi);
+}
+
 int textBreakNext(TextBreakIterator* bi)
 {
     return ubrk_next(bi);
 }

+int textBreakPrevious(TextBreakIterator* bi)
+{
+    return ubrk_previous(bi);
+}
+
 int textBreakPreceding(TextBreakIterator* bi, int pos)
 {
     return ubrk_preceding(bi, pos);
Index: WebCore/platform/text/TextEncoding.cpp
===================================================================
--- Webkit-38858/WebCore/platform/text/TextEncoding.cpp	(revision 38858)
+++ Webkit-38858.working/WebCore/platform/text/TextEncoding.cpp	(working copy)
@@ -36,6 +36,9 @@
 #include <unicode/unorm.h>
 #elif USE(QT4_UNICODE)
 #include <QString>
+#elif USE(GLIB_UNICODE)
+#include <glib.h>
+#include <wtf/GOwnPtr.h>
 #endif
 #include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
@@ -112,6 +115,20 @@ CString TextEncoding::encode(const UChar
     QString str(reinterpret_cast<const QChar*>(characters), length);
     str = str.normalized(QString::NormalizationForm_C);
     return newTextCodec(*this)->encode(reinterpret_cast<const UChar *>(str.utf16()), str.length(), handling);
+#elif USE(GLIB_UNICODE)
+    GOwnPtr<char> utf8source;
+    utf8source.set(g_utf16_to_utf8(characters, length, 0, 0, 0));
+
+    GOwnPtr<char> utf8normalized;
+    utf8normalized.set(g_utf8_normalize(utf8source.get(), -1, G_NORMALIZE_NFC));
+
+    long utf16length;
+    GOwnPtr<UChar> utf16normalized;
+    utf16normalized.set(g_utf8_to_utf16(utf8normalized.get(), -1, 0, &utf16length, 0));
+
+    CString result = newTextCodec(*this)->encode(utf16normalized.get(), utf16length, handling);
+
+    return result;
 #endif
 }

Index: WebCore/platform/text/TextEncodingRegistry.cpp
===================================================================
--- Webkit-38858/WebCore/platform/text/TextEncodingRegistry.cpp	(revision 38858)
+++ Webkit-38858.working/WebCore/platform/text/TextEncodingRegistry.cpp	(working copy)
@@ -46,6 +46,9 @@
 #if PLATFORM(QT)
 #include "qt/TextCodecQt.h"
 #endif
+#if PLATFORM(GTK)
+#include "gtk/TextCodecGtk.h"
+#endif

 using namespace WTF;

@@ -192,6 +195,11 @@ static void buildBaseTextCodecMaps()
     TextCodecICU::registerBaseEncodingNames(addToTextEncodingNameMap);
     TextCodecICU::registerBaseCodecs(addToTextCodecMap);
 #endif
+
+#if USE(GLIB_UNICODE)
+    TextCodecGtk::registerBaseEncodingNames(addToTextEncodingNameMap);
+    TextCodecGtk::registerBaseCodecs(addToTextCodecMap);
+#endif
 }

 static void extendTextCodecMaps()
@@ -210,6 +218,11 @@ static void extendTextCodecMaps()
     TextCodecMac::registerEncodingNames(addToTextEncodingNameMap);
     TextCodecMac::registerCodecs(addToTextCodecMap);
 #endif
+
+#if USE(GLIB_UNICODE)
+    TextCodecGtk::registerExtendedEncodingNames(addToTextEncodingNameMap);
+    TextCodecGtk::registerExtendedCodecs(addToTextCodecMap);
+#endif
 }

 std::auto_ptr<TextCodec> newTextCodec(const TextEncoding& encoding)
Index: WebCore/platform/text/gtk/TextBoundariesGtk.cpp
===================================================================
--- Webkit-38858/WebCore/platform/text/gtk/TextBoundariesGtk.cpp	(revision 0)
+++ Webkit-38858.working/WebCore/platform/text/gtk/TextBoundariesGtk.cpp	(revision 0)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
+ * Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextBoundaries.h"
+
+#include <glib.h>
+
+#include "StringImpl.h"
+#include "TextBreakIterator.h"
+
+namespace WebCore {
+
+int findNextWordFromIndex(const UChar* chars, int len, int position, bool forward)
+{
+    TextBreakIterator* it = wordBreakIterator(chars, len);
+
+    if (forward) {
+        position = textBreakFollowing(it, position);
+        while (position != TextBreakDone) {
+            // We stop searching when the character preceeding the break
+            // is alphanumeric.
+            if (position < len && g_unichar_isalnum(chars[position - 1]))
+                return position;
+
+            position = textBreakFollowing(it, position);
+        }
+
+        return len;
+    } else {
+        position = textBreakPreceding(it, position);
+        while (position != TextBreakDone) {
+            // We stop searching when the character following the break
+            // is alphanumeric.
+            if (position > 0 && g_unichar_isalnum(chars[position]))
+                return position;
+
+            position = textBreakPreceding(it, position);
+        }
+
+        return 0;
+    }
+}
+
+void findWordBoundary(const UChar* chars, int len, int position, int* start, int* end)
+{
+    TextBreakIterator* it = wordBreakIterator(chars, len);
+    *end = textBreakFollowing(it, position);
+    if (*end < 0)
+        *end = textBreakLast(it);
+    *start = textBreakPrevious(it);
+}
+
+} // namespace WebCore
Index: WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp
===================================================================
--- Webkit-38858/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp	(revision 0)
+++ Webkit-38858.working/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp	(revision 0)
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2006 Lars Knoll <lars@trolltech.com>
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "TextBreakIterator.h"
+
+#include <pango/pango.h>
+
+#include <wtf/GOwnPtr.h>
+
+namespace WebCore {
+
+enum UBreakIteratorType {
+    UBRK_CHARACTER,
+    UBRK_WORD,
+    UBRK_LINE,
+    UBRK_SENTENCE
+};
+
+class TextBreakIterator {
+public:
+    UBreakIteratorType m_type;
+    int m_length;
+    PangoLogAttr* m_log_attrs;
+
+    int m_index;
+};
+
+static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator*& iterator,
+    UBreakIteratorType type, const UChar* string, int length)
+{
+    if (!string)
+        return 0;
+
+    if (!createdIterator) {
+        iterator = new TextBreakIterator();
+        createdIterator = true;
+    }
+    if (!iterator)
+        return 0;
+
+    long utf8len;
+    GOwnPtr<char> utf8;
+    utf8.set(g_utf16_to_utf8(string, length, 0, &utf8len, 0));
+
+    // FIXME: assumes no surrogate pairs
+
+    iterator->m_type = type;
+    iterator->m_length = length;
+    if(createdIterator)
+        g_free(iterator->m_log_attrs);
+    iterator->m_log_attrs = g_new0(PangoLogAttr, length + 1);
+    iterator->m_index = -1;
+    pango_get_log_attrs(utf8.get(), utf8len, -1, 0, iterator->m_log_attrs, length + 1);
+
+    return iterator;
+}
+
+TextBreakIterator* characterBreakIterator(const UChar* string, int length)
+{
+    static bool createdCharacterBreakIterator = false;
+    static TextBreakIterator* staticCharacterBreakIterator;
+    return setUpIterator(createdCharacterBreakIterator,
+        staticCharacterBreakIterator, UBRK_CHARACTER, string, length);
+}
+
+TextBreakIterator* wordBreakIterator(const UChar* string, int length)
+{
+    static bool createdWordBreakIterator = false;
+    static TextBreakIterator* staticWordBreakIterator;
+    return setUpIterator(createdWordBreakIterator,
+        staticWordBreakIterator, UBRK_WORD, string, length);
+}
+
+TextBreakIterator* lineBreakIterator(const UChar* string, int length)
+{
+    static bool createdLineBreakIterator = false;
+    static TextBreakIterator* staticLineBreakIterator;
+    return setUpIterator(createdLineBreakIterator,
+        staticLineBreakIterator, UBRK_LINE, string, length);
+}
+
+TextBreakIterator* sentenceBreakIterator(const UChar* string, int length)
+{
+    static bool createdSentenceBreakIterator = false;
+    static TextBreakIterator* staticSentenceBreakIterator;
+    return setUpIterator(createdSentenceBreakIterator,
+        staticSentenceBreakIterator, UBRK_SENTENCE, string, length);
+}
+
+int textBreakFirst(TextBreakIterator* bi)
+{
+    // see textBreakLast
+
+    int firstCursorPosition = -1;
+    int pos = 0;
+    while(pos <= bi->m_length && (firstCursorPosition < 0)) {
+        if (bi->m_log_attrs[pos].is_cursor_position)
+            firstCursorPosition = pos;
+    }
+    bi->m_index = firstCursorPosition;
+    return firstCursorPosition;
+}
+
+int textBreakLast(TextBreakIterator* bi)
+{
+    // textBreakLast is not meant to find breaks according to bi->m_type but really last character
+    // (cmp ICU documentation for ubrk_first and ubrk_last)
+    // so we should advance or traverse back based on bi->m_log_attrs cursor positions
+
+    // from ICU docs for ubrk_last:
+    // "Determine the index immediately beyond the last character in the text being scanned."
+
+    // If last character position in the original string is a whitespace,
+    // traverse to the left until the first non-white character position is found
+    // and return the position of the first white-space char after this one.
+    // otherwise return m_length, as "the first character beyond the last" is outside our string.
+
+    bool whiteSpaceAtTheEnd = true;
+    int nextWhiteSpacePos = bi->m_length;
+
+    int pos = bi->m_length;
+    while (pos >= 0 && whiteSpaceAtTheEnd) {
+        if (bi->m_log_attrs[pos].is_cursor_position) {
+            if (whiteSpaceAtTheEnd = bi->m_log_attrs[pos].is_white)
+                nextWhiteSpacePos = pos;
+        }
+        pos--;
+    }
+    bi->m_index = nextWhiteSpacePos;
+    return nextWhiteSpacePos;
+}
+
+int textBreakNext(TextBreakIterator* bi)
+{
+    for (int i = bi->m_index + 1; i <= bi->m_length; i++) {
+        if (bi->m_type == UBRK_LINE && bi->m_log_attrs[i].is_line_break) {
+            bi->m_index = i;
+            return i;
+        }
+        if (bi->m_type == UBRK_WORD && (bi->m_log_attrs[i].is_word_start || bi->m_log_attrs[i].is_word_end)) {
+            // FIXME: Single multibyte characters (i.e. white space around them), such as the euro symbol €,
+            // are not marked as word_start & word_end as opposed to the way ICU does it
+            // This leads - for example - to different word selection behaviour when right clicking.
+            bi->m_index = i;
+            return i;
+        }
+        if (bi->m_type == UBRK_CHARACTER && bi->m_log_attrs[i].is_cursor_position) {
+            bi->m_index = i;
+            return i;
+        }
+        if (bi->m_type == UBRK_SENTENCE && (bi->m_log_attrs[i].is_sentence_start || bi->m_log_attrs[i].is_sentence_end)) {
+            bi->m_index = i;
+            return i;
+        }
+    }
+    return TextBreakDone;
+}
+
+int textBreakPrevious(TextBreakIterator* bi)
+{
+    for (int i = bi->m_index - 1; i >= 0; i--) {
+        if (bi->m_type == UBRK_LINE && bi->m_log_attrs[i].is_line_break) {
+            bi->m_index = i;
+            return i;
+        }
+        if (bi->m_type == UBRK_WORD && (bi->m_log_attrs[i].is_word_start || bi->m_log_attrs[i].is_word_end)) {
+            bi->m_index = i;
+            return i;
+        }
+        if (bi->m_type == UBRK_CHARACTER && bi->m_log_attrs[i].is_cursor_position) {
+            bi->m_index = i;
+            return i;
+        }
+        if (bi->m_type == UBRK_SENTENCE && (bi->m_log_attrs[i].is_sentence_start || bi->m_log_attrs[i].is_sentence_end)) {
+            bi->m_index = i;
+            return i;
+        }
+    }
+    return textBreakFirst(bi);
+}
+
+int textBreakPreceding(TextBreakIterator* bi, int pos)
+{
+    bi->m_index = pos;
+    return textBreakPrevious(bi);
+}
+
+int textBreakFollowing(TextBreakIterator* bi, int pos)
+{
+    if (pos < 0)
+        pos = -1;
+    bi->m_index = pos;
+    return textBreakNext(bi);
+}
+
+int textBreakCurrent(TextBreakIterator* bi)
+{
+    return bi->m_index;
+}
+
+bool isTextBreak(TextBreakIterator* bi, int pos)
+{
+    if (bi->m_index >= 0) {
+        if (bi->m_type == UBRK_LINE && bi->m_log_attrs[bi->m_index].is_line_break) {
+            return true;
+        }
+        if (bi->m_type == UBRK_WORD && bi->m_log_attrs[bi->m_index].is_word_end) {
+            return true;
+        }
+        if (bi->m_type == UBRK_CHARACTER && bi->m_log_attrs[bi->m_index].is_char_break) {
+            return true;
+        }
+        if (bi->m_type == UBRK_SENTENCE && bi->m_log_attrs[bi->m_index].is_sentence_end) {
+            return true;
+        }
+    }
+    return FALSE;
+}
+
+}
Index: WebCore/platform/text/gtk/TextCodecGtk.cpp
===================================================================
--- Webkit-38858/WebCore/platform/text/gtk/TextCodecGtk.cpp	(revision 0)
+++ Webkit-38858.working/WebCore/platform/text/gtk/TextCodecGtk.cpp	(revision 0)
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ * Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextCodecGtk.h"
+
+#include "CString.h"
+#include "PlatformString.h"
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/GOwnPtr.h>
+#include "Logging.h"
+
+using std::auto_ptr;
+using std::min;
+
+namespace WebCore {
+
+
+
+// appendOmittingBOM is gone (http://trac.webkit.org/changeset/33380), so we need to avoid generating extra BOM's
+// here. This can be achieved by specifying the UTF-16 codecs' endianness explicitly when initializing iconv
+
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+    const gchar* WebCore::TextCodecGtk::m_internalEncodingName = "UTF-16BE";
+#else
+    const gchar* WebCore::TextCodecGtk::m_internalEncodingName = "UTF-16LE";
+#endif
+
+
+// list of text encodings and their aliases
+// the first entry/"alias" is the canonical name, each alias list must be terminated by a 0
+
+// Unicode
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_UTF_8            = { "UTF-8", 0};
+
+// Western
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_8859_1       = { "ISO-8859-1", "CP819", "IBM819", "ISO-IR-100", "ISO8859-1", "ISO_8859-1", "ISO_8859-1:1987",  "L1", "LATIN1", "CSISOLATIN1", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_MACROMAN         = { "MACROMAN", "MAC", "MACINTOSH", "CSMACINTOSH", 0};
+
+// Japanese
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_SHIFT_JIS        = { "Shift_JIS", "MS_KANJI", "SHIFT-JIS", "SJIS", "CSSHIFTJIS", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_EUC_JP           = { "EUC_JP", "EUC-JP", "EUCJP", "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", "CSEUCPKDFMTJAPANESE", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_2022_JP      = { "ISO-2022-JP", 0};
+
+// Traditional Chinese
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_BIG5             = { "BIG5", "BIG-5", "BIG-FIVE", "BIG5", "BIGFIVE", "CN-BIG5", "CSBIG5", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_BIG5_HKSCS       = { "BIG5-HKSCS", "BIG5-HKSCS:2004", "BIG5HKSCS", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP950            = { "CP950", 0};
+
+// Korean
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_2022_KR      = { "ISO-2022-KR", "CSISO2022KR", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP949            = { "CP949", "UHC", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_EUC_KR           = { "EUC-KR", "CSEUCKR", 0 };
+
+// Arabic
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_8859_6       = { "ISO-8859-6", "ARABIC", "ASMO-708", "ECMA-114", "ISO-IR-127", "ISO8859-6", "ISO_8859-6", "ISO_8859-6:1987", "CSISOLATINARABIC", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP1256           = { "windows-1256", "CP1256", "MS-ARAB", 0}; // rearranged, windows-1256 now declared the canonical name and put to lowercase to fix /fast/encoding/ahram-org-eg.html test case
+
+// Hebrew
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_8859_8       = { "ISO-8859-8", "HEBREW", "ISO-8859-8", "ISO-IR-138", "ISO8859-8", "ISO_8859-8", "ISO_8859-8:1988", "CSISOLATINHEBREW", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP1255           = { "windows-1255", "CP1255", "MS-HEBR", 0}; // rearranged, moved windows-1255 as canonical and lowercased, fixing /fast/encoding/meta-charset.html
+
+// Greek
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_8859_7       = { "ISO-8859-7", "ECMA-118", "ELOT_928", "GREEK", "GREEK8", "ISO-IR-126", "ISO8859-7", "ISO_8859-7", "ISO_8859-7:1987", "ISO_8859-7:2003", "CSI", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP869            = { "CP869", "869", "CP-GR", "IBM869", "CSIBM869", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_WINDOWS_1253     = { "WINDOWS-1253", 0 };
+
+// Cyrillic
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_8859_5       = { "ISO-8859-5", "CYRILLIC", "ISO-IR-144", "ISO8859-5", "ISO_8859-5", "ISO_8859-5:1988", "CSISOLATINCYRILLIC", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_KOI8_R           = { "KOI8-R", "CSKOI8R", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP866            = { "CP866", "866", "IBM866", "CSIBM866", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_KOI8_U           = { "KOI8-U", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_WINDOWS_1251     = { "windows-1251", "CP1251", 0}; // CP1251 added to pass /fast/encoding/charset-cp1251.html
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_MACCYRILLIC      = { "mac-cyrillic", "MACCYRILLIC", "x-mac-cyrillic", 0};
+
+// Thai
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP874            = { "CP874", "WINDOWS-874", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_TIS_620          = { "TIS-620", 0};
+
+// Simplified Chinese
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_GBK              = { "GBK", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_HZ               = { "HZ", "HZ-GB-2312", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_GB18030          = { "GB18030", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_EUC_CN           = { "EUC_CN", "EUCCN", "GB2312", "CN-GB", "CSGB2312", "EUC_CN", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_2312_80          = { "GB_2312-80", "CHINESE", "csISO58GB231280", "GB2312.1980-0", "ISO-IR-58" };
+
+// Central European
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_8859_2       = { "ISO-8859-2", "ISO-IR-101", "ISO8859-2", "ISO_8859-2", "ISO_8859-2:1987", "L2", "LATIN2", "CSISOLATIN2", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP1250           = { "CP1250", "MS-EE", "WINDOWS-1250", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_MACCENTRALEUROPE = { "MACCENTRALEUROPE", 0};
+
+// Vietnamese
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP1258           = { "CP1258", "WINDOWS-1258", 0};
+
+// Turkish
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP1254           = { "CP1254", "MS-TURK", "WINDOWS-1254", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_8859_9       = { "ISO-8859-9", "ISO-IR-148", "ISO8859-9", "ISO_8859-9", "ISO_8859-9:1989", "L5", "LATIN5", "CSISOLATIN5", 0};
+
+// Baltic
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_CP1257           = { "CP1257", "WINBALTRIM", "WINDOWS-1257", 0};
+TextCodecGtk::codecAliasList TextCodecGtk::m_codecAliases_ISO_8859_4       = { "ISO-8859-4", "ISO-IR-110", "ISO8859-4", "ISO_8859-4", "ISO_8859-4:1988", "L4", "LATIN4", "CSISOLATIN4", 0};
+
+gconstpointer const TextCodecGtk::m_iconvBaseCodecList[] = {
+    // Unicode
+    &m_codecAliases_UTF_8,
+
+    // Western
+    &m_codecAliases_ISO_8859_1
+};
+
+gconstpointer const TextCodecGtk::m_iconvExtendedCodecList[] =
+{
+    // Western
+    &m_codecAliases_MACROMAN,
+
+    // Japanese
+    &m_codecAliases_SHIFT_JIS,
+    &m_codecAliases_EUC_JP,
+    &m_codecAliases_ISO_2022_JP,
+
+    // Simplified Chinese
+    &m_codecAliases_BIG5,
+    &m_codecAliases_BIG5_HKSCS,
+    &m_codecAliases_CP950,
+
+    // Korean
+    &m_codecAliases_ISO_2022_KR,
+    &m_codecAliases_CP949,
+    &m_codecAliases_EUC_KR,
+
+    // Arabic
+    &m_codecAliases_ISO_8859_6,
+    &m_codecAliases_CP1256,
+
+    // Hebrew
+    &m_codecAliases_ISO_8859_8,
+    &m_codecAliases_CP1255,
+
+    // Greek
+    &m_codecAliases_ISO_8859_7,
+    &m_codecAliases_CP869,
+    &m_codecAliases_WINDOWS_1253,
+
+    // Cyrillic
+    &m_codecAliases_ISO_8859_5,
+    &m_codecAliases_KOI8_R,
+    &m_codecAliases_CP866,
+    &m_codecAliases_KOI8_U,
+    &m_codecAliases_WINDOWS_1251,
+    &m_codecAliases_MACCYRILLIC,
+
+    // Thai
+    &m_codecAliases_CP874,
+    &m_codecAliases_TIS_620,
+
+    // Traditional Chinese
+    &m_codecAliases_GBK,
+    &m_codecAliases_HZ,
+    &m_codecAliases_GB18030,
+    &m_codecAliases_EUC_CN,
+    &m_codecAliases_2312_80,
+
+    // Central European
+    &m_codecAliases_ISO_8859_2,
+    &m_codecAliases_CP1250,
+    &m_codecAliases_MACCENTRALEUROPE,
+
+    // Vietnamese
+    &m_codecAliases_CP1258,
+
+    // Turkish
+    &m_codecAliases_CP1254,
+    &m_codecAliases_ISO_8859_9,
+
+    // Baltic
+    &m_codecAliases_CP1257,
+    &m_codecAliases_ISO_8859_4
+};
+
+
+const size_t ConversionBufferSize = 16384;
+
+
+static auto_ptr<TextCodec> newTextCodecGtk(const TextEncoding& encoding, const void*)
+{
+#ifndef NDEBUG
+    // too noisy if each UTF-8 codec creation is logged
+    // if (strcmp(encoding.name(), "UTF-8"))
+    //     LOG(TextConversion, "creating new text codec for encoding name %s", encoding.name());
+#endif
+
+    return auto_ptr<TextCodec>(new TextCodecGtk(encoding));
+}
+
+gboolean TextCodecGtk::isEncodingAvailable(const gchar* encName)
+{
+    GIConv tester;
+    // test decoding
+    tester = g_iconv_open(m_internalEncodingName, encName);
+    if (tester == reinterpret_cast<GIConv>(-1)) {
+        LOG_ERROR("%s not decodable => not available!", encName);
+        return false;
+    } else {
+        g_iconv_close(tester);
+        // test encoding
+        tester = g_iconv_open(encName, m_internalEncodingName);
+        if (tester == reinterpret_cast<GIConv>(-1)) {
+            LOG_ERROR("%s not encodable => not available!", encName);
+            return false;
+        } else {
+            g_iconv_close(tester);
+            return true;
+        }
+    }
+}
+
+void TextCodecGtk::registerEncodingNames(EncodingNameRegistrar registrar, bool extended)
+{
+    const void* const* encodingList;
+    unsigned int listLength = 0;
+    if (extended) {
+        encodingList = m_iconvExtendedCodecList;
+        listLength = sizeof(m_iconvExtendedCodecList)/sizeof(gpointer);
+    } else {
+        encodingList = m_iconvBaseCodecList;
+        listLength = sizeof(m_iconvBaseCodecList)/sizeof(gpointer);
+    }
+
+    for (unsigned int i = 0; i < listLength; ++i) {
+        codecAliasList *codecAliases = static_cast<codecAliasList*>(encodingList[i]);
+        int codecCount = -1;
+        const gchar *canonicalName, *currentAlias;
+        bool canonicalAvailable = true;
+
+        // for each of the alias lists:
+        // bail out if canonical is not available,
+        // then continue testing each alias,
+        // if available, add it to the list, mapping it to its canonical name
+
+        while ((currentAlias = (*codecAliases)[++codecCount]) && canonicalAvailable) {
+            bool currentAvailable = isEncodingAvailable(currentAlias);
+
+            if (codecCount == 0 && currentAvailable) {
+                canonicalName = currentAlias;
+                canonicalAvailable = true;
+                LOG_VERBOSE(TextConversion, "registering encoding canonical %s", canonicalName);
+                registrar(canonicalName, canonicalName);
+            } else if (codecCount == 0 && !currentAvailable)
+                canonicalAvailable = false;
+            else if (codecCount > 0) {
+                if (isEncodingAvailable(currentAlias)) {
+                    LOG_VERBOSE(TextConversion, "registering encoding name alias %s to canonical %s", currentAlias, canonicalName);
+                    registrar(currentAlias, canonicalName);
+                }
+            }
+        }
+
+    }
+}
+
+void TextCodecGtk::registerCodecs(TextCodecRegistrar registrar, bool extended)
+{
+    const void* const* encodingList;
+    unsigned int listLength = 0;
+    if (extended) {
+        encodingList = m_iconvExtendedCodecList;
+        listLength = sizeof(m_iconvExtendedCodecList)/sizeof(gpointer);
+    } else {
+        encodingList = m_iconvBaseCodecList;
+        listLength = sizeof(m_iconvBaseCodecList)/sizeof(gpointer);
+    }
+
+    for (unsigned int i = 0; i < listLength; ++i) {
+        codecAliasList *codecAliases = static_cast<codecAliasList*>(encodingList[i]);
+        // by convention, the first "alias" should be the canonical name, see the definition of the alias lists
+        const gchar *codecName = (*codecAliases)[0];
+        if (isEncodingAvailable(codecName))
+            registrar(codecName, newTextCodecGtk, 0);
+    }
+}
+
+void TextCodecGtk::registerBaseEncodingNames(EncodingNameRegistrar registrar)
+{
+    registerEncodingNames(registrar, false);
+}
+
+void TextCodecGtk::registerBaseCodecs(TextCodecRegistrar registrar)
+{
+    registerCodecs(registrar, false);
+}
+
+void TextCodecGtk::registerExtendedEncodingNames(EncodingNameRegistrar registrar)
+{
+    registerEncodingNames(registrar, true);
+}
+
+void TextCodecGtk::registerExtendedCodecs(TextCodecRegistrar registrar)
+{
+    registerCodecs(registrar, true);
+}
+
+TextCodecGtk::TextCodecGtk(const TextEncoding& encoding)
+    : m_encoding(encoding)
+    , m_numBufferedBytes(0)
+    , m_iconvDecoder(reinterpret_cast<GIConv>(-1))
+    , m_iconvEncoder(reinterpret_cast<GIConv>(-1))
+{
+}
+
+TextCodecGtk::~TextCodecGtk()
+{
+    releaseIConv();
+}
+
+void TextCodecGtk::releaseIConv() const
+{
+    if (m_iconvDecoder != reinterpret_cast<GIConv>(-1)) {
+        g_iconv_close(m_iconvDecoder);
+        m_iconvDecoder = reinterpret_cast<GIConv>(-1);
+    }
+    if (m_iconvEncoder != reinterpret_cast<GIConv>(-1)) {
+        g_iconv_close(m_iconvEncoder);
+        m_iconvEncoder = reinterpret_cast<GIConv>(-1);
+    }
+}
+
+void TextCodecGtk::createIConvDecoder() const
+{
+    ASSERT(m_iconvDecoder == reinterpret_cast<GIConv>(-1));
+
+    m_iconvDecoder = g_iconv_open(m_internalEncodingName, m_encoding.name());
+}
+
+void TextCodecGtk::createIConvEncoder() const
+{
+    ASSERT(m_iconvDecoder == reinterpret_cast<GIConv>(-1));
+
+    m_iconvEncoder = g_iconv_open(m_encoding.name(), m_internalEncodingName);
+}
+
+String TextCodecGtk::decode(const char* bytes, size_t length, bool flush, bool stopOnError, bool& sawError)
+{
+    // Get a converter for the passed-in encoding.
+    if (m_iconvDecoder == reinterpret_cast<GIConv>(-1)) {
+        createIConvDecoder();
+        ASSERT(m_iconvDecoder != reinterpret_cast<GIConv>(-1));
+        if (m_iconvDecoder == reinterpret_cast<GIConv>(-1)) {
+            LOG_ERROR("error creating IConv encoder even though encoding was in table");
+            return String();
+        }
+    }
+
+    size_t countWritten, countRead, conversionLength;
+    const char* conversionBytes;
+    char* prefixedBytes = 0;
+
+    if (m_numBufferedBytes) {
+        conversionLength = length + m_numBufferedBytes;
+        prefixedBytes = static_cast<char*>(fastMalloc(conversionLength));
+        memcpy(prefixedBytes, m_bufferedBytes, m_numBufferedBytes);
+        memcpy(prefixedBytes + m_numBufferedBytes, bytes, length);
+
+        conversionBytes = prefixedBytes;
+
+        // all buffered bytes are consumed now
+        m_numBufferedBytes = 0;
+    } else {
+        // no previously buffered partial data,
+        // just convert the data that was passed in
+        conversionBytes = bytes;
+        conversionLength = length;
+    }
+
+    GOwnPtr<GError> err;
+    GOwnPtr<UChar> buffer;
+
+    buffer.outPtr() = reinterpret_cast<UChar*>(g_convert_with_iconv(conversionBytes, conversionLength, m_iconvDecoder, &countRead, &countWritten, &err.outPtr()));
+
+
+    if (err) {
+        LOG_ERROR("GIConv conversion error");
+        m_numBufferedBytes = 0; // reset state for subsequent calls to decode
+        fastFree(prefixedBytes);
+        sawError = true;
+        return String();
+    }
+
+    // Partial input at the end of the string may not result in an error being raised.
+    // From the gnome library documentation on g_convert_with_iconv:
+    // "Even if the conversion was successful, this may be less than len if there were partial characters at the end of the input."
+    // That's why we need to compare conversionLength against countRead
+
+    m_numBufferedBytes = conversionLength - countRead;
+    if (m_numBufferedBytes > 0) {
+        if (flush) {
+            LOG_ERROR("Partial bytes at end of input while flush requested.");
+            m_numBufferedBytes = 0; // reset state for subsequent calls to decode
+            fastFree(prefixedBytes);
+            sawError = true;
+            return String();
+        }
+        memcpy(m_bufferedBytes, conversionBytes + countRead, m_numBufferedBytes);
+    }
+
+    fastFree(prefixedBytes);
+
+    Vector<UChar> result;
+
+    result.append(buffer.get(), countWritten / sizeof(UChar));
+
+    return String::adopt(result);
+}
+
+CString TextCodecGtk::encode(const UChar* characters, size_t length, UnencodableHandling handling)
+{
+    if (!length)
+        return "";
+
+    if (m_iconvEncoder == reinterpret_cast<GIConv>(-1))
+        createIConvEncoder();
+    if (m_iconvEncoder == reinterpret_cast<GIConv>(-1))
+        return CString();
+
+    size_t count;
+
+    GOwnPtr<GError> err;
+    GOwnPtr<char> buffer;
+
+    buffer.outPtr() = g_convert_with_iconv(reinterpret_cast<const char*>(characters), length * sizeof(UChar), m_iconvEncoder, 0, &count, &err.outPtr());
+    if (err) {
+        LOG_ERROR("GIConv conversion error");
+        return CString();
+    }
+
+    CString result = CString(buffer.get(), count);
+
+    return result;
+}
+
+
+} // namespace WebCore
Index: WebCore/platform/text/gtk/TextCodecGtk.h
===================================================================
--- Webkit-38858/WebCore/platform/text/gtk/TextCodecGtk.h	(revision 0)
+++ Webkit-38858.working/WebCore/platform/text/gtk/TextCodecGtk.h	(revision 0)
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ * Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TextCodecGTK_h
+#define TextCodecGTK_h
+
+#include <glib.h>
+
+#include "TextCodec.h"
+#include "TextEncoding.h"
+
+namespace WebCore {
+
+    class TextCodecGtk : public TextCodec {
+    public:
+        static void registerBaseEncodingNames(EncodingNameRegistrar);
+        static void registerBaseCodecs(TextCodecRegistrar);
+
+        static void registerExtendedEncodingNames(EncodingNameRegistrar);
+        static void registerExtendedCodecs(TextCodecRegistrar);
+
+        TextCodecGtk(const TextEncoding&);
+        virtual ~TextCodecGtk();
+
+        virtual String decode(const char*, size_t length, bool flush, bool stopOnError, bool& sawError);
+        virtual CString encode(const UChar*, size_t length, UnencodableHandling);
+
+    private:
+        void createIConvDecoder() const;
+        void createIConvEncoder() const;
+        void releaseIConv() const;
+
+        static void registerEncodingNames(EncodingNameRegistrar registrar, bool extended);
+        static void registerCodecs(TextCodecRegistrar registrar, bool extended);
+        static gboolean isEncodingAvailable(const gchar*);
+
+        TextEncoding m_encoding;
+        size_t m_numBufferedBytes;
+        unsigned char m_bufferedBytes[16]; // bigger than any single multi-byte character
+        mutable GIConv m_iconvDecoder;
+        mutable GIConv m_iconvEncoder;
+
+        static const gchar* m_internalEncodingName;
+
+        typedef const gchar* const codecAliasList[];
+
+        // Unicode
+        static codecAliasList m_codecAliases_UTF_8;
+
+        // Western
+        static codecAliasList m_codecAliases_ISO_8859_1;
+        static codecAliasList m_codecAliases_MACROMAN;
+
+        // Japanese
+        static codecAliasList m_codecAliases_SHIFT_JIS;
+        static codecAliasList m_codecAliases_EUC_JP;
+        static codecAliasList m_codecAliases_ISO_2022_JP;
+
+        // Traditional Chinese
+        static codecAliasList m_codecAliases_BIG5;
+        static codecAliasList m_codecAliases_BIG5_HKSCS;
+        static codecAliasList m_codecAliases_CP950;
+
+        // Korean
+        static codecAliasList m_codecAliases_ISO_2022_KR;
+        static codecAliasList m_codecAliases_CP949;
+        static codecAliasList m_codecAliases_EUC_KR;
+
+        // Arabic
+        static codecAliasList m_codecAliases_ISO_8859_6;
+        static codecAliasList m_codecAliases_CP1256;
+
+        // Hebrew
+        static codecAliasList m_codecAliases_ISO_8859_8;
+        static codecAliasList m_codecAliases_CP1255;
+
+        // Greek
+        static codecAliasList m_codecAliases_ISO_8859_7;
+        static codecAliasList m_codecAliases_CP869;
+        static codecAliasList m_codecAliases_WINDOWS_1253;
+
+        // Cyrillic
+        static codecAliasList m_codecAliases_ISO_8859_5;
+        static codecAliasList m_codecAliases_KOI8_R;
+        static codecAliasList m_codecAliases_CP866;
+        static codecAliasList m_codecAliases_KOI8_U;
+        static codecAliasList m_codecAliases_WINDOWS_1251;
+        static codecAliasList m_codecAliases_MACCYRILLIC;
+
+        // Thai
+        static codecAliasList m_codecAliases_CP874;
+        static codecAliasList m_codecAliases_TIS_620;
+
+        // Simplified Chinese
+        static codecAliasList m_codecAliases_GBK;
+        static codecAliasList m_codecAliases_HZ;
+        static codecAliasList m_codecAliases_GB18030;
+        static codecAliasList m_codecAliases_EUC_CN;
+        static codecAliasList m_codecAliases_2312_80;
+
+        // Central European
+        static codecAliasList m_codecAliases_ISO_8859_2;
+        static codecAliasList m_codecAliases_CP1250;
+        static codecAliasList m_codecAliases_MACCENTRALEUROPE;
+
+        // Vietnamese
+        static codecAliasList m_codecAliases_CP1258;
+
+        // Turkish
+        static codecAliasList m_codecAliases_CP1254;
+        static codecAliasList m_codecAliases_ISO_8859_9;
+
+        // Baltic
+        static codecAliasList m_codecAliases_CP1257;
+        static codecAliasList m_codecAliases_ISO_8859_4;
+
+        static gconstpointer const m_iconvBaseCodecList[];
+        static gconstpointer const m_iconvExtendedCodecList[];
+
+    };
+
+} // namespace WebCore
+
+#endif // TextCodecGTK_h
