Index: pango1.0-1.28.1/modules/thai/thai-lang.c
===================================================================
--- pango1.0-1.28.1.orig/modules/thai/thai-lang.c	2010-07-07 21:40:52.784805690 +0700
+++ pango1.0-1.28.1/modules/thai/thai-lang.c	2010-07-07 21:50:07.300304577 +0700
@@ -30,19 +30,27 @@
 typedef PangoEngineLang      ThaiEngineLang;
 typedef PangoEngineLangClass ThaiEngineLangClass;
 
-#define SCRIPT_ENGINE_NAME "ThaiScriptEngineLang"
-
 static PangoEngineScriptInfo thai_scripts[] = {
   { PANGO_SCRIPT_THAI, "*" }
 };
 
+static PangoEngineScriptInfo lao_scripts[] = {
+  { PANGO_SCRIPT_LAO, "*" }
+};
+
 static PangoEngineInfo script_engines[] = {
   {
-    SCRIPT_ENGINE_NAME,
+    "ThaiScriptEngineLang",
     PANGO_ENGINE_TYPE_LANG,
     PANGO_RENDER_TYPE_NONE,
     thai_scripts, G_N_ELEMENTS(thai_scripts)
-  }
+  },
+  {
+    "LaoScriptEngineLang",
+    PANGO_ENGINE_TYPE_LANG,
+    PANGO_RENDER_TYPE_NONE,
+    lao_scripts, G_N_ELEMENTS(lao_scripts)
+  },
 };
 
 /*
@@ -76,12 +84,37 @@
   int brk_stack[512];
   thchar_t *tis_text;
   int *brk_pnts;
-  int cnt;
+  int cnt, i;
+  const char *p;
 
   if (len < 0)
     len = strlen (text);
   cnt = g_utf8_strlen (text, len) + 1;
 
+  /* Override UAX#29 GB_Prepend & GB_Extend class for caret movements.
+   * See Bug 576156.
+   */
+  for (i = 0, p = text; i < cnt; i++, p = g_utf8_next_char (p))
+    {
+      gunichar wc = g_utf8_get_char (p);
+      if ((0x0E40 <= wc && wc <= 0x0E44) || (0x0EC0 <= wc && wc <= 0x0EC4))
+        {
+          /* GB_Prepend: override to allow cursor after it */
+          if (i + 1 < cnt)
+            attrs[i + 1].is_cursor_position = TRUE;
+        }
+      else if (wc == 0x0E30 || wc == 0x0E32 || wc == 0x0E33 || wc == 0x0E45 ||
+               wc == 0x0EB0 || wc == 0x0EB2 || wc == 0x0EB3)
+        {
+          /* GB_Extend: override to allow cursor before it */
+          attrs[i].is_cursor_position = TRUE;
+        }
+    }
+
+  /* Only Thai word break engine available for now */
+  if (analysis->script != PANGO_SCRIPT_THAI)
+    return;
+
   tis_text = tis_stack;
   if (cnt > (int) G_N_ELEMENTS (tis_stack))
     tis_text = g_new (thchar_t, cnt);
@@ -94,11 +127,11 @@
 
   /* find line break positions */
   len = th_brk (tis_text, brk_pnts, len);
-  for (cnt = 0; cnt < len; cnt++)
+  for (i = 0; i < len; i++)
     {
-      attrs[brk_pnts[cnt]].is_line_break = TRUE;
-      attrs[brk_pnts[cnt]].is_word_start = TRUE;
-      attrs[brk_pnts[cnt]].is_word_end = TRUE;
+      attrs[brk_pnts[i]].is_line_break = TRUE;
+      attrs[brk_pnts[i]].is_word_start = TRUE;
+      attrs[brk_pnts[i]].is_word_end = TRUE;
     }
 
   if (brk_pnts != brk_stack)
@@ -140,9 +173,14 @@
 PangoEngine *
 PANGO_MODULE_ENTRY(create) (const char *id)
 {
-  if (!strcmp (id, SCRIPT_ENGINE_NAME))
-    return g_object_new (thai_engine_lang_type, NULL);
-  else
-    return NULL;
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS(script_engines); i++)
+    {
+      if (!strcmp (id, script_engines[i].id))
+        return g_object_new (thai_engine_lang_type, NULL);
+    }
+
+  return NULL;
 }
 
