summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoungbok Shin <youngb.shin@samsung.com>2018-08-20 07:21:53 -0400
committerMike Blumenkrantz <zmike@samsung.com>2018-08-20 10:29:32 -0400
commit517018e00897f61136418861563a49144a5fe39a (patch)
tree694c299402631380a10a7ad6ddbebfbb774e7e91
parent8da56ac873d5bb083b7cfe08aeefdaa2ad9a4b99 (diff)
downloadefl-517018e00897f61136418861563a49144a5fe39a.tar.gz
evas textblock: add/apply cursor cluster APIs based on grapheme cluster
Summary: Add a feature for moving cursor over a grapheme cluster. It is applied to edje_entry.c and elm_entry.c for improving cursor handling just like other modern text editors. ex) gedit The patch on Evas needs to update libunibreak library. So, the patch will update libunibreak, too. @feature Test Plan: 1. Put "ഹലോ" in your entry. 2. Your cursor can reach at the end of text from the beginning only in 2 right key event with this feature. Reviewers: raster, cedric, jpeg, herdsman, zmike, devilhorns Reviewed By: herdsman, zmike Subscribers: #reviewers, #committers, zmike, bowonryu, woohyun Tags: #efl Differential Revision: https://phab.enlightenment.org/D5490
-rw-r--r--src/Makefile_Evas.am8
-rw-r--r--src/lib/edje/edje_entry.c51
-rw-r--r--src/lib/efl/interfaces/efl_text_cursor.eo25
-rw-r--r--src/lib/evas/canvas/efl_canvas_text.eo3
-rw-r--r--src/lib/evas/canvas/evas_object_textblock.c276
-rw-r--r--src/lib/evas/canvas/evas_textblock_legacy.h26
-rw-r--r--src/static_libs/libunibreak/ChangeLog92
-rw-r--r--src/static_libs/libunibreak/LICENCE5
-rw-r--r--src/static_libs/libunibreak/NEWS7
-rw-r--r--src/static_libs/libunibreak/README.md14
-rw-r--r--src/static_libs/libunibreak/graphemebreak.c283
-rw-r--r--src/static_libs/libunibreak/graphemebreak.h69
-rw-r--r--src/static_libs/libunibreak/graphemebreakdata.c1337
-rw-r--r--src/static_libs/libunibreak/graphemebreakdef.h82
-rw-r--r--src/static_libs/libunibreak/linebreak.c28
-rw-r--r--src/static_libs/libunibreak/linebreak.h1
-rw-r--r--src/static_libs/libunibreak/linebreakdef.c1
-rw-r--r--src/static_libs/libunibreak/linebreakdef.h1
-rw-r--r--src/static_libs/libunibreak/unibreakbase.c3
-rw-r--r--src/static_libs/libunibreak/unibreakbase.h5
-rw-r--r--src/static_libs/libunibreak/unibreakdef.c3
-rw-r--r--src/static_libs/libunibreak/unibreakdef.h3
-rw-r--r--src/static_libs/libunibreak/wordbreak.c33
-rw-r--r--src/static_libs/libunibreak/wordbreak.h9
-rw-r--r--src/static_libs/libunibreak/wordbreakdef.h9
-rw-r--r--src/tests/evas/evas_test_textblock.c24
26 files changed, 2295 insertions, 103 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 0699dde533..b09521cb72 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -193,7 +193,10 @@ static_libs/libunibreak/linebreak.h \
static_libs/libunibreak/linebreakdef.h \
static_libs/libunibreak/wordbreakdef.h \
static_libs/libunibreak/wordbreak.h \
-static_libs/libunibreak/wordbreakdata.c
+static_libs/libunibreak/wordbreakdata.c \
+static_libs/libunibreak/graphemebreak.h \
+static_libs/libunibreak/graphemebreakdef.h \
+static_libs/libunibreak/graphemebreakdata.c
# Linebreak
lib_evas_libevas_la_SOURCES = \
@@ -202,7 +205,8 @@ static_libs/libunibreak/unibreakdef.c \
static_libs/libunibreak/linebreak.c \
static_libs/libunibreak/linebreakdata.c \
static_libs/libunibreak/linebreakdef.c \
-static_libs/libunibreak/wordbreak.c
+static_libs/libunibreak/wordbreak.c \
+static_libs/libunibreak/graphemebreak.c
# Main
lib_evas_libevas_la_SOURCES += \
diff --git a/src/lib/edje/edje_entry.c b/src/lib/edje/edje_entry.c
index 6c1f8960ff..1ad3c30b65 100644
--- a/src/lib/edje/edje_entry.c
+++ b/src/lib/edje/edje_entry.c
@@ -536,7 +536,7 @@ _curs_jump_line(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int ln)
if (!evas_object_textblock_line_number_geometry_get(o, ln, &lx, &ly, &lw, &lh))
return EINA_FALSE;
- if (evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+ if (evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
return EINA_TRUE;
evas_textblock_cursor_line_set(c, ln);
if (cx < (lx + (lw / 2)))
@@ -1607,24 +1607,33 @@ _delete_emit(Edje *ed, Evas_Textblock_Cursor *c, Entry *en, size_t pos,
ERR("Running very low on memory");
return;
}
- char *tmp = evas_textblock_cursor_content_get(c);
+ char *tmp = NULL;
info->insert = EINA_FALSE;
if (backspace)
{
info->change.del.start = pos - 1;
info->change.del.end = pos;
+ tmp = evas_textblock_cursor_content_get(c);
+ evas_textblock_cursor_char_delete(c);
}
else
{
- info->change.del.start = pos + 1;
+ Evas_Textblock_Cursor *cc = evas_object_textblock_cursor_new(en->rp->object);
+ evas_textblock_cursor_copy(c, cc);
+ evas_textblock_cursor_cluster_next(cc);
+
+ info->change.del.start = evas_textblock_cursor_pos_get(cc);
info->change.del.end = pos;
+
+ tmp = evas_textblock_cursor_range_text_get(c, cc, EVAS_TEXTBLOCK_TEXT_MARKUP);
+ evas_textblock_cursor_range_delete(c, cc);
+ evas_textblock_cursor_free(cc);
}
info->change.del.content = eina_stringshare_add(tmp);
if (tmp) free(tmp);
- evas_textblock_cursor_char_delete(c);
_edje_emit(ed, "entry,changed", en->rp->part->name);
_edje_emit_full(ed, "entry,changed,user", en->rp->part->name,
info, _free_entry_change_info);
@@ -1855,7 +1864,7 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
}
}
}
- if (evas_textblock_cursor_char_prev(en->cursor))
+ if (evas_textblock_cursor_cluster_prev(en->cursor))
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
#if defined(__APPLE__) && defined(__MACH__)
if (altgr) evas_textblock_cursor_word_start(en->cursor);
@@ -1903,7 +1912,7 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
#else
if (control) evas_textblock_cursor_word_end(en->cursor);
#endif
- if (evas_textblock_cursor_char_next(en->cursor))
+ if (evas_textblock_cursor_cluster_next(en->cursor))
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
if (en->select_allow)
{
@@ -1921,7 +1930,7 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
// del to start of previous word
_sel_start(en->cursor, rp->object, en);
- evas_textblock_cursor_char_prev(en->cursor);
+ evas_textblock_cursor_cluster_prev(en->cursor);
evas_textblock_cursor_word_start(en->cursor);
_sel_preextend(ed, en->cursor, rp->object, en);
@@ -1961,7 +1970,7 @@ _edje_key_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
_sel_start(en->cursor, rp->object, en);
evas_textblock_cursor_word_end(en->cursor);
- evas_textblock_cursor_char_next(en->cursor);
+ evas_textblock_cursor_cluster_next(en->cursor);
_sel_extend(ed, en->cursor, rp->object, en);
@@ -2400,7 +2409,7 @@ _edje_key_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, v
}
static Evas_Textblock_Cursor *
-_edje_cursor_char_coord_set(Edje_Real_Part *rp, Evas_Coord canvasx, Evas_Coord canvasy, Evas_Coord *cx, Evas_Coord *cy)
+_edje_cursor_cluster_coord_set(Edje_Real_Part *rp, Evas_Coord canvasx, Evas_Coord canvasy, Evas_Coord *cx, Evas_Coord *cy)
{
Entry *en;
Evas_Coord x, y, lh = 0, cly = 0;
@@ -2432,7 +2441,7 @@ _edje_cursor_char_coord_set(Edje_Real_Part *rp, Evas_Coord canvasx, Evas_Coord c
evas_textblock_cursor_free(line_cur);
/* No need to check return value if not able to set the char coord Textblock
* will take care */
- evas_textblock_cursor_char_coord_set(en->cursor, *cx, *cy);
+ evas_textblock_cursor_cluster_coord_set(en->cursor, *cx, *cy);
return tc;
}
@@ -2530,7 +2539,7 @@ _edje_part_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
else
{
evas_textblock_cursor_word_end(en->cursor);
- evas_textblock_cursor_char_next(en->cursor);
+ evas_textblock_cursor_cluster_next(en->cursor);
}
_sel_extend(en->ed, en->cursor, rp->object, en);
}
@@ -2544,13 +2553,13 @@ _edje_part_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
evas_textblock_cursor_word_start(en->cursor);
_sel_start(en->cursor, rp->object, en);
evas_textblock_cursor_word_end(en->cursor);
- evas_textblock_cursor_char_next(en->cursor);
+ evas_textblock_cursor_cluster_next(en->cursor);
_sel_extend(en->ed, en->cursor, rp->object, en);
}
goto end;
}
}
- tc = _edje_cursor_char_coord_set(rp, ev->canvas.x, ev->canvas.y, &cx, &cy);
+ tc = _edje_cursor_cluster_coord_set(rp, ev->canvas.x, ev->canvas.y, &cx, &cy);
if (dosel)
{
@@ -2670,7 +2679,7 @@ _edje_part_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
#endif
/* cx cy are unused but needed in mouse down, please bear with it */
- tc = _edje_cursor_char_coord_set(rp, ev->canvas.x, ev->canvas.y, &cx, &cy);
+ tc = _edje_cursor_cluster_coord_set(rp, ev->canvas.x, ev->canvas.y, &cx, &cy);
if (en->select_allow)
{
@@ -2748,7 +2757,7 @@ _edje_part_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
cx = ev->cur.canvas.x - x;
cy = ev->cur.canvas.y - y;
- if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
+ if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, cy))
{
Evas_Coord lx, ly, lw, lh;
@@ -2760,7 +2769,7 @@ _edje_part_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
{
evas_textblock_cursor_paragraph_first(en->cursor);
evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
- if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
+ if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, ly + (lh / 2)))
_curs_end(en->cursor, rp->object, en);
}
}
@@ -4029,7 +4038,7 @@ _edje_text_cursor_next(Edje_Real_Part *rp, Efl_Text_Cursor_Cursor *c)
_edje_entry_imf_context_reset(rp);
- if (!evas_textblock_cursor_char_next(c))
+ if (!evas_textblock_cursor_cluster_next(c))
{
return EINA_FALSE;
}
@@ -4062,7 +4071,7 @@ _edje_text_cursor_prev(Edje_Real_Part *rp, Efl_Text_Cursor_Cursor *c)
_edje_entry_imf_context_reset(rp);
- if (!evas_textblock_cursor_char_prev(c))
+ if (!evas_textblock_cursor_cluster_prev(c))
{
if (evas_textblock_cursor_paragraph_prev(c)) goto ok;
else return EINA_FALSE;
@@ -4106,7 +4115,7 @@ _edje_text_cursor_up(Edje_Real_Part *rp, Efl_Text_Cursor_Cursor *c)
&lx, &ly, &lw, &lh))
return EINA_FALSE;
evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
- if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+ if (!evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
evas_textblock_cursor_line_char_last(c);
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
@@ -4145,7 +4154,7 @@ _edje_text_cursor_down(Edje_Real_Part *rp, Efl_Text_Cursor_Cursor *c)
&lx, &ly, &lw, &lh))
return EINA_FALSE;
evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
- if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
+ if (!evas_textblock_cursor_cluster_coord_set(c, cx, ly + (lh / 2)))
evas_textblock_cursor_line_char_last(c);
_sel_update(en->ed, c, rp->object, rp->typedata.text->entry_data);
@@ -4347,7 +4356,7 @@ _edje_text_cursor_coord_set(Edje_Real_Part *rp, Efl_Text_Cursor_Cursor *c,
_edje_emit(en->ed, "selection,changed", rp->part->name);
}
}
- return evas_textblock_cursor_char_coord_set(c, x, y);
+ return evas_textblock_cursor_cluster_coord_set(c, x, y);
}
Eina_Bool
diff --git a/src/lib/efl/interfaces/efl_text_cursor.eo b/src/lib/efl/interfaces/efl_text_cursor.eo
index 973c7d85bd..b0e4c28b51 100644
--- a/src/lib/efl/interfaces/efl_text_cursor.eo
+++ b/src/lib/efl/interfaces/efl_text_cursor.eo
@@ -145,6 +145,20 @@ interface Efl.Text_Cursor {
/* @inout */ cur: ptr(Efl.Text_Cursor_Cursor); [[Cursor object]]
}
}
+ cursor_cluster_next {
+ [[Advances to the next grapheme cluster]]
+ legacy: null;
+ params {
+ /* @inout */ cur: ptr(Efl.Text_Cursor_Cursor); [[Cursor object]]
+ }
+ }
+ cursor_cluster_prev {
+ [[Advances to the previous grapheme cluster]]
+ legacy: null;
+ params {
+ /* @inout */ cur: ptr(Efl.Text_Cursor_Cursor); [[Cursor object]]
+ }
+ }
cursor_paragraph_char_first {
[[Advances to the first character in this paragraph]]
legacy: null;
@@ -232,6 +246,17 @@ interface Efl.Text_Cursor {
@in y: int; [[Y coord to set by.]]
}
}
+ cursor_cluster_coord_set {
+ [[Set cursor coordinates according to grapheme clusters.
+ It does not allow to put a cursor to the middle of a grapheme cluster.
+ ]]
+ legacy: null;
+ params {
+ /* @inout */ cur: ptr(Efl.Text_Cursor_Cursor); [[Cursor object]]
+ @in x: int; [[X coord to set by.]]
+ @in y: int; [[Y coord to set by.]]
+ }
+ }
cursor_text_insert {
[[Adds text to the current cursor position and set the cursor to
*after* the start of the text just added.
diff --git a/src/lib/evas/canvas/efl_canvas_text.eo b/src/lib/evas/canvas/efl_canvas_text.eo
index b24139e34a..6c82adf82a 100644
--- a/src/lib/evas/canvas/efl_canvas_text.eo
+++ b/src/lib/evas/canvas/efl_canvas_text.eo
@@ -327,6 +327,8 @@ class Efl.Canvas.Text (Efl.Canvas.Object, Efl.Text,
Efl.Text_Cursor.cursor_copy;
Efl.Text_Cursor.cursor_char_next;
Efl.Text_Cursor.cursor_char_prev;
+ Efl.Text_Cursor.cursor_cluster_next;
+ Efl.Text_Cursor.cursor_cluster_prev;
Efl.Text_Cursor.cursor_paragraph_char_first;
Efl.Text_Cursor.cursor_paragraph_char_last;
Efl.Text_Cursor.cursor_word_start;
@@ -339,6 +341,7 @@ class Efl.Canvas.Text (Efl.Canvas.Object, Efl.Text,
Efl.Text_Cursor.cursor_paragraph_prev;
Efl.Text_Cursor.cursor_line_jump_by;
Efl.Text_Cursor.cursor_coord_set;
+ Efl.Text_Cursor.cursor_cluster_coord_set;
Efl.Text_Cursor.cursor_text_insert;
Efl.Text_Cursor.cursor_char_delete;
Efl.Text_Annotate.annotation { set; get; }
diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c
index f523f131e9..16f717ce41 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -77,6 +77,7 @@
#include "linebreak.h"
#include "wordbreak.h"
+#include "graphemebreak.h"
#include "evas_filter.h"
#include "efl_canvas_filter_internal.eo.h"
@@ -9271,20 +9272,122 @@ _efl_canvas_text_efl_text_cursor_cursor_word_end(Eo *eo_obj, Efl_Canvas_Text_Dat
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
-EAPI Eina_Bool
-evas_textblock_cursor_char_next(Efl_Text_Cursor_Cursor *cur)
+static char *
+_evas_textblock_grapheme_breaks_new(Evas_Object_Textblock_Item *it, size_t len)
{
- int ind;
+ char *grapheme_breaks = NULL;
+ const char *lang = (it->format->font.fdesc) ? it->format->font.fdesc->lang : "";
+
+ grapheme_breaks = malloc(len);
+ if (!grapheme_breaks) return NULL;
+
+ set_graphemebreaks_utf32((const utf32_t *)
+ eina_ustrbuf_string_get(
+ it->text_node->unicode),
+ len, lang, grapheme_breaks);
+
+ return grapheme_breaks;
+}
+
+static size_t
+_evas_textblock_cursor_cluster_pos_get(Evas_Textblock_Cursor *cur, Eina_Bool inc)
+{
+ Evas_Object_Textblock_Paragraph *par;
+ Efl_Canvas_Text_Data *o;
+ size_t cur_pos = cur->pos;
+ size_t ret = cur->pos;
+
+ if (!inc) cur_pos--;
+
+ if (!cur->node->par)
+ {
+ o = efl_data_scope_get(cur->obj, MY_CLASS);
+ if (o) _relayout_if_needed(cur->obj, o);
+ }
+
+ par = cur->node->par;
+
+ if (par)
+ {
+ Eina_List *l;
+ Evas_Object_Textblock_Item *it, *last_it = NULL;
+ EINA_LIST_FOREACH(par->logical_items, l, it)
+ {
+ if (it->text_pos > cur_pos)
+ {
+ if (!last_it) last_it = it;
+ break;
+ }
+ last_it = it;
+ }
+
+ if (last_it)
+ {
+ it = last_it;
+ if (it->type == EVAS_TEXTBLOCK_ITEM_TEXT)
+ {
+ size_t len = eina_ustrbuf_length_get(it->text_node->unicode);
+ char *grapheme_breaks = _evas_textblock_grapheme_breaks_new(it, len);
+
+ if (grapheme_breaks)
+ {
+ size_t grapheme_breaks_index = cur_pos;
+
+ if (inc)
+ {
+ while ((grapheme_breaks_index < len) &&
+ (grapheme_breaks[grapheme_breaks_index] != GRAPHEMEBREAK_BREAK))
+ {
+ grapheme_breaks_index++;
+ }
+
+ ret = grapheme_breaks_index + 1;
+ }
+ else
+ {
+ while ((grapheme_breaks_index > 0) &&
+ (grapheme_breaks[grapheme_breaks_index - 1] != GRAPHEMEBREAK_BREAK))
+ {
+ grapheme_breaks_index--;
+ }
+
+ ret = grapheme_breaks_index;
+ }
+
+ free(grapheme_breaks);
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+static Eina_Bool
+_evas_textblock_cursor_next(Evas_Textblock_Cursor *cur, Eina_Bool per_cluster)
+{
+ Evas_Object_Protected_Data *obj;
const Eina_Unicode *text;
+ int ind;
if (!cur) return EINA_FALSE;
- Evas_Object_Protected_Data *obj = efl_data_scope_get(cur->obj, EFL_CANVAS_OBJECT_CLASS);
- evas_object_async_block(obj);
TB_NULL_CHECK(cur->node, EINA_FALSE);
+ obj = efl_data_scope_get(cur->obj, EFL_CANVAS_OBJECT_CLASS);
+ evas_object_async_block(obj);
+
ind = cur->pos;
text = eina_ustrbuf_string_get(cur->node->unicode);
- if (text[ind]) ind++;
+
+ if (text[ind])
+ {
+ if (per_cluster)
+ ind = _evas_textblock_cursor_cluster_pos_get(cur, EINA_TRUE);
+
+ if (ind <= (int)cur->pos)
+ ind = cur->pos + 1;
+ }
+
/* Only allow pointing a null if it's the last paragraph.
* because we don't have a PS there. */
if (text[ind])
@@ -9311,23 +9414,30 @@ evas_textblock_cursor_char_next(Efl_Text_Cursor_Cursor *cur)
}
}
-EOLIAN static void
-_efl_canvas_text_efl_text_cursor_cursor_char_next(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
-{
- ASYNC_BLOCK;
- evas_textblock_cursor_char_next(cur);
- efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
-}
-
static Eina_Bool
-_evas_textblock_cursor_char_prev(Efl_Text_Cursor_Cursor *cur)
+_evas_textblock_cursor_prev(Evas_Textblock_Cursor *cur, Eina_Bool per_cluster)
{
+ Evas_Object_Protected_Data *obj;
if (!cur) return EINA_FALSE;
TB_NULL_CHECK(cur->node, EINA_FALSE);
+ obj = efl_data_scope_get(cur->obj, EFL_CANVAS_OBJECT_CLASS);
+ evas_object_async_block(obj);
+
if (cur->pos != 0)
{
+ if (per_cluster)
+ {
+ size_t ret = _evas_textblock_cursor_cluster_pos_get(cur, EINA_FALSE);
+
+ if (ret != cur->pos)
+ {
+ cur->pos = ret;
+ return EINA_TRUE;
+ }
+ }
+
cur->pos--;
return EINA_TRUE;
}
@@ -9335,18 +9445,59 @@ _evas_textblock_cursor_char_prev(Efl_Text_Cursor_Cursor *cur)
}
EAPI Eina_Bool
+evas_textblock_cursor_char_next(Efl_Text_Cursor_Cursor *cur)
+{
+ return _evas_textblock_cursor_next(cur, EINA_FALSE);
+}
+
+EOLIAN static void
+_efl_canvas_text_efl_text_cursor_cursor_char_next(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
+{
+ ASYNC_BLOCK;
+ if (_evas_textblock_cursor_next(cur, EINA_FALSE))
+ efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
+}
+
+EAPI Eina_Bool
evas_textblock_cursor_char_prev(Efl_Text_Cursor_Cursor *cur)
{
- if (!cur) return EINA_FALSE;
- return _evas_textblock_cursor_char_prev(cur);
+ return _evas_textblock_cursor_prev(cur, EINA_FALSE);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_char_prev(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
ASYNC_BLOCK;
- _evas_textblock_cursor_char_prev(cur);
- efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
+ if (_evas_textblock_cursor_prev(cur, EINA_FALSE))
+ efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_next(Efl_Text_Cursor_Cursor *cur)
+{
+ return _evas_textblock_cursor_next(cur, EINA_TRUE);
+}
+
+EOLIAN static void
+_efl_canvas_text_efl_text_cursor_cursor_cluster_next(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
+{
+ ASYNC_BLOCK;
+ if (_evas_textblock_cursor_next(cur, EINA_TRUE))
+ efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_prev(Efl_Text_Cursor_Cursor *cur)
+{
+ return _evas_textblock_cursor_prev(cur, EINA_TRUE);
+}
+
+EOLIAN static void
+_efl_canvas_text_efl_text_cursor_cursor_cluster_prev(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
+{
+ ASYNC_BLOCK;
+ if (_evas_textblock_cursor_prev(cur, EINA_TRUE))
+ efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EAPI void
@@ -12031,15 +12182,16 @@ _efl_canvas_text_visible_range_get(Eo *eo_obj EINA_UNUSED,
return EINA_TRUE;
}
-
-EAPI Eina_Bool
-evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+static Eina_Bool
+_evas_textblock_cursor_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y, Eina_Bool per_cluster)
{
Evas_Object_Textblock_Paragraph *found_par;
Evas_Object_Textblock_Line *ln;
Evas_Object_Textblock_Item *it = NULL;
Eina_Bool ret = EINA_FALSE;
+ if (!cur) return ret;
+
Evas_Object_Protected_Data *obj = efl_data_scope_get(cur->obj, EFL_CANVAS_OBJECT_CLASS);
evas_object_async_block(obj);
Efl_Canvas_Text_Data *o = efl_data_scope_get(cur->obj, MY_CLASS);
@@ -12112,6 +12264,63 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x,
&cx, &cy, &cw, &ch);
if (pos < 0)
goto end;
+
+ if ((pos > 0) && per_cluster)
+ {
+ size_t len = eina_ustrbuf_length_get(it->text_node->unicode);
+ char *grapheme_breaks = _evas_textblock_grapheme_breaks_new(it, len);
+
+ /* If current position is not breakable,
+ * try to move cursor to a nearest breakable position. */
+ if (grapheme_breaks && (grapheme_breaks[pos + it->text_pos - 1] != GRAPHEMEBREAK_BREAK))
+ {
+ size_t left_index = pos + it->text_pos - 1;
+ size_t right_index = pos + it->text_pos - 1;
+ int lx, rx;
+
+ /* To the left */
+ while ((left_index > 0) &&
+ (grapheme_breaks[left_index] != GRAPHEMEBREAK_BREAK))
+ {
+ left_index--;
+ }
+
+ ENFN->font_pen_coords_get(ENC,
+ ti->parent.format->font.font,
+ &ti->text_props,
+ left_index - it->text_pos + 1,
+ &lx, NULL, NULL, NULL);
+
+ /* To the right */
+ while ((right_index < len) &&
+ (grapheme_breaks[right_index] != GRAPHEMEBREAK_BREAK))
+ {
+ right_index++;
+ }
+
+ ENFN->font_pen_coords_get(ENC,
+ ti->parent.format->font.font,
+ &ti->text_props,
+ right_index - it->text_pos + 1,
+ &rx, NULL, NULL, NULL);
+
+ /* Decide a nearest position by checking its geometry. */
+ if (((ti->text_props.bidi_dir != EVAS_BIDI_DIRECTION_RTL) &&
+ ((ln->x + it->x + rx - x) >= (x - (lx + ln->x + it->x)))) ||
+ ((ti->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL) &&
+ ((ln->x + it->x + lx - x) >= (x - (rx + ln->x + it->x)))))
+ {
+ pos = left_index - it->text_pos + 1;
+ }
+ else
+ {
+ pos = right_index - it->text_pos + 1;
+ }
+ }
+
+ free(grapheme_breaks);
+ }
+
cur->pos = pos + it->text_pos;
cur->node = it->text_node;
ret = EINA_TRUE;
@@ -12167,6 +12376,18 @@ end:
return ret;
}
+EAPI Eina_Bool
+evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+{
+ return _evas_textblock_cursor_coord_set(cur, x, y, EINA_FALSE);
+}
+
+EAPI Eina_Bool
+evas_textblock_cursor_cluster_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y)
+{
+ return _evas_textblock_cursor_coord_set(cur, x, y, EINA_TRUE);
+}
+
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_coord_set(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur EINA_UNUSED,
Evas_Coord x, Evas_Coord y)
@@ -12175,6 +12396,14 @@ _efl_canvas_text_efl_text_cursor_cursor_coord_set(Eo *eo_obj EINA_UNUSED, Efl_Ca
evas_textblock_cursor_char_coord_set(cur, x, y);
}
+EOLIAN static void
+_efl_canvas_text_efl_text_cursor_cursor_cluster_coord_set(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur EINA_UNUSED,
+ Evas_Coord x, Evas_Coord y)
+{
+ ASYNC_BLOCK;
+ evas_textblock_cursor_cluster_coord_set(cur, x, y);
+}
+
EAPI int
evas_textblock_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y)
{
@@ -13279,6 +13508,7 @@ evas_object_textblock_init(Evas_Object *eo_obj)
linebreak_init = EINA_TRUE;
init_linebreak();
init_wordbreak();
+ init_graphemebreak();
}
o = obj->private_data;
@@ -15194,7 +15424,7 @@ _efl_canvas_text_efl_text_annotate_range_annotations_get(const Eo *eo_obj, Efl_C
if (!it->start_node || !it->end_node) continue;
_textblock_cursor_pos_at_fnode_set(eo_obj, &start2, it->start_node);
_textblock_cursor_pos_at_fnode_set(eo_obj, &end2, it->end_node);
- _evas_textblock_cursor_char_prev(&end2);
+ evas_textblock_cursor_char_prev(&end2);
if (!((evas_textblock_cursor_compare(&start2, end) > 0) ||
(evas_textblock_cursor_compare(&end2, start) < 0)))
{
diff --git a/src/lib/evas/canvas/evas_textblock_legacy.h b/src/lib/evas/canvas/evas_textblock_legacy.h
index 0d84075fa0..2c8ee05f57 100644
--- a/src/lib/evas/canvas/evas_textblock_legacy.h
+++ b/src/lib/evas/canvas/evas_textblock_legacy.h
@@ -605,6 +605,22 @@ EAPI Eina_Bool evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *obj);
EAPI Eina_Bool evas_textblock_cursor_char_next(Evas_Textblock_Cursor *obj);
/**
+ * @brief Advances the cursor one grapheme cluster backwards.
+ *
+ * @return @c true on success, @c false otherwise.
+ */
+EAPI Eina_Bool evas_textblock_cursor_cluster_prev(Evas_Textblock_Cursor *obj);
+
+/**
+ * @brief Advances the cursor one grapheme cluster forward.
+ *
+ * @return @c true on success, @c false otherwise.
+ *
+ * @ingroup Evas_Textblock_Cursor
+ */
+EAPI Eina_Bool evas_textblock_cursor_cluster_next(Evas_Textblock_Cursor *obj);
+
+/**
* @brief Advances to the start of the next text node
*
* @return @c true if managed to advance, @c false otherwise
@@ -860,6 +876,16 @@ EAPI Evas_Textblock_Cursor *evas_object_textblock_cursor_new(const Evas_Object *
EAPI Eina_Bool evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *obj, Evas_Coord x, Evas_Coord y);
/**
+ * @brief Sets the position of the cursor according to the X and Y coordinates and
+ * grapheme clusters of text.
+ *
+ * @param[in] y y coord to set by.
+ *
+ * @return @c true on success, @c false otherwise.
+ */
+EAPI Eina_Bool evas_textblock_cursor_cluster_coord_set(Evas_Textblock_Cursor *obj, Evas_Coord x, Evas_Coord y);
+
+/**
* Free the cursor and unassociate it from the object.
* @note do not use it to free unassociated cursors.
*
diff --git a/src/static_libs/libunibreak/ChangeLog b/src/static_libs/libunibreak/ChangeLog
index cad33cfd26..8df529f0c9 100644
--- a/src/static_libs/libunibreak/ChangeLog
+++ b/src/static_libs/libunibreak/ChangeLog
@@ -1,3 +1,95 @@
+2016-12-15 Wu Yongwei <wuyongwei@gmail.com>
+
+ * src/Makefile.am (include_HEADERS): Move graphemebreakdef.h to
+ EXTRA_DIST.
+ (EXTRA_DIST): Add graphemebreakdef.h and test_skips.h.
+
+2016-12-14 Wu Yongwei <wuyongwei@gmail.com>
+
+ * src/linebreak.c: Adjust documentation comment.
+ * src/wordbreak.c: Ditto.
+ * src/graphemebreak.c: Ditto.
+
+2016-12-14 Wu Yongwei <wuyongwei@gmail.com>
+
+ * Doxyfile (FULL_PATH_NAMES): Set to `NO'.
+ (DOT_IMAGE_FORMAT): Set to `svg'.
+ (SEARCHENGINE): Set to `YES'.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ Update for the libunibreak 4.0 release.
+ * NEWS: Add information about libunibreak 4.0.
+ * Doxyfile (PROJECT_NUMBER): Change to `4.0'.
+ * configure.ac (AC_INIT): Change the library version to `4.0'.
+ * src/Makefile.am (libunibreak_la_LDFLAGS): Set the version-info to
+ `4:0:1'.
+ * src/unibreakbase.h (UNIBREAK_VERSION): Set to 0x0400.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ * src/Makefile.am (include_HEADERS): Add a missing file
+ graphemebreakdef.h.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ * bootstrap: Add a missing `--copy' argument to glibtoolize.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ * README.md: Update for grapheme break and links.
+ * LICENCE: Add Andreas Röver and update copyright information.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ * Doxyfile (EXCLUDE): Add `src/tests.c'.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ * src/wordbreak.c: Update Unicode version and link information.
+ * src/wordbreak.h: Ditto.
+ * src/wordbreakdef.h: Ditto.
+ * src/graphemebreak.c: Ditto.
+ * src/graphemebreak.h: Ditto.
+ * src/graphemebreakdef.h: Ditto.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ * src/linebreak.c: Remove `@version' and update copyright header.
+ * src/linebreak.h: Ditto.
+ * src/linebreakdef.c: Ditto.
+ * src/linebreakdef.h: Ditto.
+ * src/wordbreak.c: Ditto.
+ * src/wordbreak.h: Ditto.
+ * src/wordbreakdef.h: Ditto.
+ * src/graphemebreak.c: Ditto.
+ * src/graphemebreak.h: Ditto.
+ * src/graphemebreakdef.h: Ditto.
+ * src/unibreakbase.c: Ditto.
+ * src/unibreakbase.h: Ditto.
+ * src/unibreakdef.c: Ditto.
+ * src/unibreakdef.h: Ditto.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ * src/Makefile.msvc: Add graphemebreak.c.
+ * src/graphemebreak.c: Add a workaround of stdbool.h for MSVC
+ versions earlier than 2013.
+ * src/graphemebreak.h: Make include order consistent.
+ * src/linebreak.c (ends_with): Make the code compile under C89.
+
+2016-12-10 Wu Yongwei <wuyongwei@gmail.com>
+
+ * src/Makefile.gcc (CFILES): Add graphemebreak.c.
+ (graphemebreakdata): New phony target.
+ (GraphemeBreakProperty.txt): New target.
+ (distclean): Add WordBreakProperty.txt and GraphemeBreakProperty.txt
+ as well.
+
+2016-12-05 Tom Hacohen <tom@stosb.com>
+
+ * src/test_skips.h: New file.
+
2016-12-04 Wu Yongwei <wuyongwei@gmail.com>
Simpify implementation about RI pairing.
diff --git a/src/static_libs/libunibreak/LICENCE b/src/static_libs/libunibreak/LICENCE
index 3eda8d5061..3fba16ad53 100644
--- a/src/static_libs/libunibreak/LICENCE
+++ b/src/static_libs/libunibreak/LICENCE
@@ -1,6 +1,7 @@
-Copyright (C) 2008-2015 Wu Yongwei <wuyongwei at gmail dot com>
-Copyright (C) 2012-2015 Tom Hacohen <tom at stosb dot com>
+Copyright (C) 2008-2016 Wu Yongwei <wuyongwei at gmail dot com>
+Copyright (C) 2012-2016 Tom Hacohen <tom at stosb dot com>
Copyright (C) 2013 Petr Filipsky <philodej at gmail dot com>
+Copyright (C) 2016 Andreas Röver <roever at users dot sf dot net>
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
diff --git a/src/static_libs/libunibreak/NEWS b/src/static_libs/libunibreak/NEWS
index 7de7feba18..d217628da8 100644
--- a/src/static_libs/libunibreak/NEWS
+++ b/src/static_libs/libunibreak/NEWS
@@ -1,3 +1,10 @@
+New in libunibreak 4.0
+
+- Update the code and data to conform to Unicode 9.0.0
+- Add grapheme breaking support
+- Tested and enhanced according to the Unicode test suite
+- Make bug fixes
+
New in libunibreak 3.0
- Update the code and data to conform to Unicode 7.0.0
diff --git a/src/static_libs/libunibreak/README.md b/src/static_libs/libunibreak/README.md
index 52cd7388b5..f37fd902aa 100644
--- a/src/static_libs/libunibreak/README.md
+++ b/src/static_libs/libunibreak/README.md
@@ -9,8 +9,8 @@ breaking and word breaking algorithms as described in [Unicode Standard
Annex 14] [1] and [Unicode Standard Annex 29] [2]. Check the project's
[home page] [3] for up-to-date information.
- [1]: http://www.unicode.org/reports/tr14/tr14-30.html
- [2]: http://www.unicode.org/reports/tr29/tr29-21.html
+ [1]: http://www.unicode.org/reports/tr14/tr14-37.html
+ [2]: http://www.unicode.org/reports/tr29/tr29-29.html
[3]: https://github.com/adah1972/libunibreak
@@ -46,6 +46,8 @@ There are three ways to build the library:
*LineBreak.txt*.
- type `make wordbreakdata` to regenerate *wordbreakdata.c* from
*WordBreakProperty.txt*.
+ - type `make graphemebreakdata` to regenerate *graphemebreakdata.c*
+ from *GraphemeBreakProperty.txt*.
2. On systems where GCC and Binutils are supported, one can type
@@ -61,6 +63,8 @@ There are three ways to build the library:
*LineBreak.txt*.
- type `make wordbreakdata` to regenerate *wordbreakdata.c* from
*WordBreakProperty.txt*.
+ - type `make graphemebreakdata` to regenerate *graphemebreakdata.c*
+ from *GraphemeBreakProperty.txt*.
3. On Windows, apart from using method 1 (Cygwin/MSYS) and method 2
(MinGW), MSVC can also be used. Type
@@ -77,9 +81,9 @@ There are three ways to build the library:
Documentation
-------------
-Check the generated document *doc/html/linebreak\_8h.html* and
-*doc/html/wordbreak\_8h.html* in the downloaded file for the public
-interfaces exposed to applications.
+Check the generated document *doc/html/linebreak\_8h.html*,
+*doc/html/wordbreak\_8h.html*, and *doc/html/graphemebreak\_8h.html* in
+the downloaded file for the public interfaces exposed to applications.
<!--
diff --git a/src/static_libs/libunibreak/graphemebreak.c b/src/static_libs/libunibreak/graphemebreak.c
new file mode 100644
index 0000000000..77c3d5f55c
--- /dev/null
+++ b/src/static_libs/libunibreak/graphemebreak.c
@@ -0,0 +1,283 @@
+/*
+ * Grapheme breaking in a Unicode sequence. Designed to be used in a
+ * generic text renderer.
+ *
+ * Copyright (C) 2016 Andreas Röver <roever at users dot sf dot net>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute
+ * it freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must
+ * not claim that you wrote the original software. If you use this
+ * software in a product, an acknowledgement in the product
+ * documentation would be appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must
+ * not be misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ * The main reference is Unicode Standard Annex 29 (UAX #29):
+ * <URL:http://unicode.org/reports/tr29>
+ *
+ * When this library was designed, this annex was at Revision 29, for
+ * Unicode 9.0.0:
+ * <URL:http://www.unicode.org/reports/tr29/tr29-29.html>
+ *
+ * The Unicode Terms of Use are available at
+ * <URL:http://www.unicode.org/copyright.html>
+ */
+
+/**
+ * @file graphemebreak.c
+ *
+ * Implementation of the grapheme breaking algorithm as described in Unicode
+ * Standard Annex 29.
+ *
+ * @author Andreas Roever
+ */
+
+#if defined(_MSC_VER) && _MSC_VER < 1800
+typedef int bool;
+#define false 0
+#define true 1
+#else
+#include <stdbool.h>
+#endif
+
+#include <string.h>
+#include "graphemebreak.h"
+#include "graphemebreakdata.c"
+#include "unibreakdef.h"
+
+#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0]))
+
+/**
+ * Initializes the wordbreak internals. It currently does nothing, but
+ * it may in the future.
+ */
+void init_graphemebreak(void)
+{
+}
+
+/**
+ * Gets the grapheme breaking class of a character.
+ *
+ * @param ch character to check
+ * @return the grapheme breaking class if found; \c GBP_Other otherwise
+ */
+static enum GraphemeBreakClass get_char_gb_class(utf32_t ch)
+{
+ int min = 0;
+ int max = ARRAY_LEN(gb_prop_default) - 1;
+ int mid;
+
+ do
+ {
+ mid = (min + max) / 2;
+
+ if (ch < gb_prop_default[mid].start)
+ max = mid - 1;
+ else if (ch > gb_prop_default[mid].end)
+ min = mid + 1;
+ else
+ return gb_prop_default[mid].prop;
+ } while (min <= max);
+
+ return GBP_Other;
+}
+
+/**
+ * Sets the grapheme breaking information for a generic input string.
+ *
+ * @param[in] s input string
+ * @param[in] len length of the input
+ * @param[out] brks pointer to the output breaking data, containing
+ * #GRAPHEMEBREAK_BREAK or #GRAPHEMEBREAK_NOBREAK
+ * @param[in] get_next_char function to get the next UTF-32 character
+ */
+static void set_graphemebreaks(const void *s, size_t len, char *brks,
+ get_next_char_t get_next_char)
+{
+ size_t posNext = 0;
+ bool rule10Left = false; // is the left side of rule 10 fulfilled?
+ bool evenRegionalIndicators = true; // is the number of preceeding
+ // GBP_RegionalIndicator characters
+ // even
+
+ utf32_t ch = get_next_char(s, len, &posNext);
+ enum GraphemeBreakClass current_class = get_char_gb_class(ch);
+
+ // initialize whole output to inside char
+ memset(brks, GRAPHEMEBREAK_INSIDEACHAR, len);
+
+ while (true)
+ {
+ enum GraphemeBreakClass prev_class = current_class;
+
+ // safe position if current character so that we can store the
+ // result there later on
+ size_t brksPos = posNext - 1;
+
+ // get nect character
+ ch = get_next_char(s, len, &posNext);
+
+ if (ch == EOS)
+ {
+ // done, place one final break after the last character as per
+ // algorithm rule GB1
+ brks[brksPos] = GRAPHEMEBREAK_BREAK;
+ break;
+ }
+
+ // get class of current character
+ current_class = get_char_gb_class(ch);
+
+ // update some helper variables
+ if ((prev_class == GBP_E_Base) || (prev_class == GBP_E_Base_GAZ))
+ {
+ rule10Left = true;
+ }
+ else if (prev_class != GBP_Extend)
+ {
+ rule10Left = false;
+ }
+
+ if (prev_class == GBP_Regional_Indicator)
+ {
+ evenRegionalIndicators = !evenRegionalIndicators;
+ }
+ else
+ {
+ evenRegionalIndicators = true;
+ }
+
+ // check all rules
+ if (prev_class == GBP_CR && current_class == GBP_LF)
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB3
+ }
+ else if ((prev_class == GBP_CR) || (prev_class == GBP_LF) ||
+ (prev_class == GBP_Control) || (current_class == GBP_CR) ||
+ (current_class == GBP_LF) ||
+ (current_class == GBP_Control))
+ {
+ brks[brksPos] = GRAPHEMEBREAK_BREAK; // Rule: GB4 + GB5
+ }
+ else if ((prev_class == GBP_L) &&
+ ((current_class == GBP_L) || (current_class == GBP_V) ||
+ (current_class == GBP_LV) || (current_class == GBP_LVT)))
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB6
+ }
+ else if (((prev_class == GBP_LV) || (prev_class == GBP_V)) &&
+ ((current_class == GBP_V) || (current_class == GBP_T)))
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB7
+ }
+ else if (((prev_class == GBP_LVT) || (prev_class == GBP_T)) &&
+ (current_class == GBP_T))
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB8
+ }
+ else if ((current_class == GBP_Extend) ||
+ (current_class == GBP_ZWJ))
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB9
+ }
+ else if (current_class == GBP_SpacingMark)
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB9a
+ }
+ else if (prev_class == GBP_Prepend)
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB9b
+ }
+ else if (rule10Left && (current_class == GBP_E_Modifier))
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB10
+ }
+ else if ((prev_class == GBP_ZWJ) &&
+ ((current_class == GBP_Glue_After_Zwj) ||
+ (current_class == GBP_E_Base_GAZ)))
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB11
+ }
+ else if (!evenRegionalIndicators &&
+ (current_class == GBP_Regional_Indicator))
+ {
+ brks[brksPos] = GRAPHEMEBREAK_NOBREAK; // Rule: GB12 + GB13
+ }
+ else
+ {
+ brks[brksPos] = GRAPHEMEBREAK_BREAK; // Rule: GB999
+ }
+ }
+}
+
+/**
+ * Sets the grapheme breaking information for a UTF-8 input string.
+ *
+ * @param[in] s input UTF-8 string
+ * @param[in] len length of the input
+ * @param[in] lang language of the input (reserved for future use)
+ * @param[out] brks pointer to the output breaking data, containing
+ * #GRAPHEMEBREAK_BREAK or #GRAPHEMEBREAK_NOBREAK.
+ * First element in output array is for the break behind
+ * the first character the pointer must point to an
+ * array with at least as many elements as there
+ * are characters in the string
+ */
+void set_graphemebreaks_utf8(const utf8_t *s, size_t len, const char *lang,
+ char *brks)
+{
+ (void)lang;
+ set_graphemebreaks(s, len, brks,
+ (get_next_char_t)ub_get_next_char_utf8);
+}
+
+/**
+ * Sets the grapheme breaking information for a UTF-16 input string.
+ *
+ * @param[in] s input UTF-16 string
+ * @param[in] len length of the input
+ * @param[in] lang language of the input (reserved for future use)
+ * @param[out] brks pointer to the output breaking data, containing
+ * #GRAPHEMEBREAK_BREAK or #GRAPHEMEBREAK_NOBREAK.
+ * First element in output array is for the break behind
+ * the first character the pointer must point to an
+ * array with at least as many elements as there
+ * are characters in the string
+ */
+void set_graphemebreaks_utf16(const utf16_t *s, size_t len,
+ const char *lang, char *brks)
+{
+ (void)lang;
+ set_graphemebreaks(s, len, brks,
+ (get_next_char_t)ub_get_next_char_utf16);
+}
+
+/**
+ * Sets the grapheme breaking information for a UTF-32 input string.
+ *
+ * @param[in] s input UTF-32 string
+ * @param[in] len length of the input
+ * @param[in] lang language of the input (reserved for future use)
+ * @param[out] brks pointer to the output breaking data, containing
+ * #GRAPHEMEBREAK_BREAK or #GRAPHEMEBREAK_NOBREAK.
+ * First element in output array is for the break behind
+ * the first character the pointer must point to an
+ * array with at least as many elements as there
+ * are characters in the string
+ */
+void set_graphemebreaks_utf32(const utf32_t *s, size_t len,
+ const char *lang, char *brks)
+{
+ (void)lang;
+ set_graphemebreaks(s, len, brks,
+ (get_next_char_t)ub_get_next_char_utf32);
+}
diff --git a/src/static_libs/libunibreak/graphemebreak.h b/src/static_libs/libunibreak/graphemebreak.h
new file mode 100644
index 0000000000..c01768233a
--- /dev/null
+++ b/src/static_libs/libunibreak/graphemebreak.h
@@ -0,0 +1,69 @@
+/*
+ * Grapheme breaking in a Unicode sequence. Designed to be used in a
+ * generic text renderer.
+ *
+ * Copyright (C) 2016 Andreas Röver <roever at users dot sf dot net>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute
+ * it freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must
+ * not claim that you wrote the original software. If you use this
+ * software in a product, an acknowledgement in the product
+ * documentation would be appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must
+ * not be misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ * The main reference is Unicode Standard Annex 29 (UAX #29):
+ * <URL:http://unicode.org/reports/tr29>
+ *
+ * When this library was designed, this annex was at Revision 29, for
+ * Unicode 9.0.0:
+ * <URL:http://www.unicode.org/reports/tr29/tr29-29.html>
+ *
+ * The Unicode Terms of Use are available at
+ * <URL:http://www.unicode.org/copyright.html>
+ */
+
+/**
+ * @file graphemebreak.h
+ *
+ * Header file for the grapheme breaking algorithm.
+ *
+ * @author Andreas Röver
+ */
+
+#ifndef GRAPHEMEBREAK_H
+#define GRAPHEMEBREAK_H
+
+#include <stddef.h>
+#include "unibreakbase.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRAPHEMEBREAK_BREAK 0 /**< Between 2 graphemes */
+#define GRAPHEMEBREAK_NOBREAK 1 /**< Inside a grapheme */
+#define GRAPHEMEBREAK_INSIDEACHAR 2 /**< Inside a unicode character */
+
+void init_graphemebreak(void);
+void set_graphemebreaks_utf8(const utf8_t *s, size_t len, const char *lang,
+ char *brks);
+void set_graphemebreaks_utf16(const utf16_t *s, size_t len,
+ const char *lang, char *brks);
+void set_graphemebreaks_utf32(const utf32_t *s, size_t len,
+ const char *lang, char *brks);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/static_libs/libunibreak/graphemebreakdata.c b/src/static_libs/libunibreak/graphemebreakdata.c
new file mode 100644
index 0000000000..cab9bebd80
--- /dev/null
+++ b/src/static_libs/libunibreak/graphemebreakdata.c
@@ -0,0 +1,1337 @@
+/* The content of this file is generated from:
+# GraphemeBreakProperty-9.0.0.txt
+# Date: 2016-06-03, 22:23:55 GMT
+*/
+
+#include "graphemebreakdef.h"
+
+static const struct GraphemeBreakProperties gb_prop_default[] = {
+ {0x0000, 0x0009, GBP_Control},
+ {0x000A, 0x000A, GBP_LF},
+ {0x000B, 0x000C, GBP_Control},
+ {0x000D, 0x000D, GBP_CR},
+ {0x000E, 0x001F, GBP_Control},
+ {0x007F, 0x009F, GBP_Control},
+ {0x00AD, 0x00AD, GBP_Control},
+ {0x0300, 0x036F, GBP_Extend},
+ {0x0483, 0x0487, GBP_Extend},
+ {0x0488, 0x0489, GBP_Extend},
+ {0x0591, 0x05BD, GBP_Extend},
+ {0x05BF, 0x05BF, GBP_Extend},
+ {0x05C1, 0x05C2, GBP_Extend},
+ {0x05C4, 0x05C5, GBP_Extend},
+ {0x05C7, 0x05C7, GBP_Extend},
+ {0x0600, 0x0605, GBP_Prepend},
+ {0x0610, 0x061A, GBP_Extend},
+ {0x061C, 0x061C, GBP_Control},
+ {0x064B, 0x065F, GBP_Extend},
+ {0x0670, 0x0670, GBP_Extend},
+ {0x06D6, 0x06DC, GBP_Extend},
+ {0x06DD, 0x06DD, GBP_Prepend},
+ {0x06DF, 0x06E4, GBP_Extend},
+ {0x06E7, 0x06E8, GBP_Extend},
+ {0x06EA, 0x06ED, GBP_Extend},
+ {0x070F, 0x070F, GBP_Prepend},
+ {0x0711, 0x0711, GBP_Extend},
+ {0x0730, 0x074A, GBP_Extend},
+ {0x07A6, 0x07B0, GBP_Extend},
+ {0x07EB, 0x07F3, GBP_Extend},
+ {0x0816, 0x0819, GBP_Extend},
+ {0x081B, 0x0823, GBP_Extend},
+ {0x0825, 0x0827, GBP_Extend},
+ {0x0829, 0x082D, GBP_Extend},
+ {0x0859, 0x085B, GBP_Extend},
+ {0x08D4, 0x08E1, GBP_Extend},
+ {0x08E2, 0x08E2, GBP_Prepend},
+ {0x08E3, 0x0902, GBP_Extend},
+ {0x0903, 0x0903, GBP_SpacingMark},
+ {0x093A, 0x093A, GBP_Extend},
+ {0x093B, 0x093B, GBP_SpacingMark},
+ {0x093C, 0x093C, GBP_Extend},
+ {0x093E, 0x0940, GBP_SpacingMark},
+ {0x0941, 0x0948, GBP_Extend},
+ {0x0949, 0x094C, GBP_SpacingMark},
+ {0x094D, 0x094D, GBP_Extend},
+ {0x094E, 0x094F, GBP_SpacingMark},
+ {0x0951, 0x0957, GBP_Extend},
+ {0x0962, 0x0963, GBP_Extend},
+ {0x0981, 0x0981, GBP_Extend},
+ {0x0982, 0x0983, GBP_SpacingMark},
+ {0x09BC, 0x09BC, GBP_Extend},
+ {0x09BE, 0x09BE, GBP_Extend},
+ {0x09BF, 0x09C0, GBP_SpacingMark},
+ {0x09C1, 0x09C4, GBP_Extend},
+ {0x09C7, 0x09C8, GBP_SpacingMark},
+ {0x09CB, 0x09CC, GBP_SpacingMark},
+ {0x09CD, 0x09CD, GBP_Extend},
+ {0x09D7, 0x09D7, GBP_Extend},
+ {0x09E2, 0x09E3, GBP_Extend},
+ {0x0A01, 0x0A02, GBP_Extend},
+ {0x0A03, 0x0A03, GBP_SpacingMark},
+ {0x0A3C, 0x0A3C, GBP_Extend},
+ {0x0A3E, 0x0A40, GBP_SpacingMark},
+ {0x0A41, 0x0A42, GBP_Extend},
+ {0x0A47, 0x0A48, GBP_Extend},
+ {0x0A4B, 0x0A4D, GBP_Extend},
+ {0x0A51, 0x0A51, GBP_Extend},
+ {0x0A70, 0x0A71, GBP_Extend},
+ {0x0A75, 0x0A75, GBP_Extend},
+ {0x0A81, 0x0A82, GBP_Extend},
+ {0x0A83, 0x0A83, GBP_SpacingMark},
+ {0x0ABC, 0x0ABC, GBP_Extend},
+ {0x0ABE, 0x0AC0, GBP_SpacingMark},
+ {0x0AC1, 0x0AC5, GBP_Extend},
+ {0x0AC7, 0x0AC8, GBP_Extend},
+ {0x0AC9, 0x0AC9, GBP_SpacingMark},
+ {0x0ACB, 0x0ACC, GBP_SpacingMark},
+ {0x0ACD, 0x0ACD, GBP_Extend},
+ {0x0AE2, 0x0AE3, GBP_Extend},
+ {0x0B01, 0x0B01, GBP_Extend},
+ {0x0B02, 0x0B03, GBP_SpacingMark},
+ {0x0B3C, 0x0B3C, GBP_Extend},
+ {0x0B3E, 0x0B3E, GBP_Extend},
+ {0x0B3F, 0x0B3F, GBP_Extend},
+ {0x0B40, 0x0B40, GBP_SpacingMark},
+ {0x0B41, 0x0B44, GBP_Extend},
+ {0x0B47, 0x0B48, GBP_SpacingMark},
+ {0x0B4B, 0x0B4C, GBP_SpacingMark},
+ {0x0B4D, 0x0B4D, GBP_Extend},
+ {0x0B56, 0x0B56, GBP_Extend},
+ {0x0B57, 0x0B57, GBP_Extend},
+ {0x0B62, 0x0B63, GBP_Extend},
+ {0x0B82, 0x0B82, GBP_Extend},
+ {0x0BBE, 0x0BBE, GBP_Extend},
+ {0x0BBF, 0x0BBF, GBP_SpacingMark},
+ {0x0BC0, 0x0BC0, GBP_Extend},
+ {0x0BC1, 0x0BC2, GBP_SpacingMark},
+ {0x0BC6, 0x0BC8, GBP_SpacingMark},
+ {0x0BCA, 0x0BCC, GBP_SpacingMark},
+ {0x0BCD, 0x0BCD, GBP_Extend},
+ {0x0BD7, 0x0BD7, GBP_Extend},
+ {0x0C00, 0x0C00, GBP_Extend},
+ {0x0C01, 0x0C03, GBP_SpacingMark},
+ {0x0C3E, 0x0C40, GBP_Extend},
+ {0x0C41, 0x0C44, GBP_SpacingMark},
+ {0x0C46, 0x0C48, GBP_Extend},
+ {0x0C4A, 0x0C4D, GBP_Extend},
+ {0x0C55, 0x0C56, GBP_Extend},
+ {0x0C62, 0x0C63, GBP_Extend},
+ {0x0C81, 0x0C81, GBP_Extend},
+ {0x0C82, 0x0C83, GBP_SpacingMark},
+ {0x0CBC, 0x0CBC, GBP_Extend},
+ {0x0CBE, 0x0CBE, GBP_SpacingMark},
+ {0x0CBF, 0x0CBF, GBP_Extend},
+ {0x0CC0, 0x0CC1, GBP_SpacingMark},
+ {0x0CC2, 0x0CC2, GBP_Extend},
+ {0x0CC3, 0x0CC4, GBP_SpacingMark},
+ {0x0CC6, 0x0CC6, GBP_Extend},
+ {0x0CC7, 0x0CC8, GBP_SpacingMark},
+ {0x0CCA, 0x0CCB, GBP_SpacingMark},
+ {0x0CCC, 0x0CCD, GBP_Extend},
+ {0x0CD5, 0x0CD6, GBP_Extend},
+ {0x0CE2, 0x0CE3, GBP_Extend},
+ {0x0D01, 0x0D01, GBP_Extend},
+ {0x0D02, 0x0D03, GBP_SpacingMark},
+ {0x0D3E, 0x0D3E, GBP_Extend},
+ {0x0D3F, 0x0D40, GBP_SpacingMark},
+ {0x0D41, 0x0D44, GBP_Extend},
+ {0x0D46, 0x0D48, GBP_SpacingMark},
+ {0x0D4A, 0x0D4C, GBP_SpacingMark},
+ {0x0D4D, 0x0D4D, GBP_Extend},
+ {0x0D4E, 0x0D4E, GBP_Prepend},
+ {0x0D57, 0x0D57, GBP_Extend},
+ {0x0D62, 0x0D63, GBP_Extend},
+ {0x0D82, 0x0D83, GBP_SpacingMark},
+ {0x0DCA, 0x0DCA, GBP_Extend},
+ {0x0DCF, 0x0DCF, GBP_Extend},
+ {0x0DD0, 0x0DD1, GBP_SpacingMark},
+ {0x0DD2, 0x0DD4, GBP_Extend},
+ {0x0DD6, 0x0DD6, GBP_Extend},
+ {0x0DD8, 0x0DDE, GBP_SpacingMark},
+ {0x0DDF, 0x0DDF, GBP_Extend},
+ {0x0DF2, 0x0DF3, GBP_SpacingMark},
+ {0x0E31, 0x0E31, GBP_Extend},
+ {0x0E33, 0x0E33, GBP_SpacingMark},
+ {0x0E34, 0x0E3A, GBP_Extend},
+ {0x0E47, 0x0E4E, GBP_Extend},
+ {0x0EB1, 0x0EB1, GBP_Extend},
+ {0x0EB3, 0x0EB3, GBP_SpacingMark},
+ {0x0EB4, 0x0EB9, GBP_Extend},
+ {0x0EBB, 0x0EBC, GBP_Extend},
+ {0x0EC8, 0x0ECD, GBP_Extend},
+ {0x0F18, 0x0F19, GBP_Extend},
+ {0x0F35, 0x0F35, GBP_Extend},
+ {0x0F37, 0x0F37, GBP_Extend},
+ {0x0F39, 0x0F39, GBP_Extend},
+ {0x0F3E, 0x0F3F, GBP_SpacingMark},
+ {0x0F71, 0x0F7E, GBP_Extend},
+ {0x0F7F, 0x0F7F, GBP_SpacingMark},
+ {0x0F80, 0x0F84, GBP_Extend},
+ {0x0F86, 0x0F87, GBP_Extend},
+ {0x0F8D, 0x0F97, GBP_Extend},
+ {0x0F99, 0x0FBC, GBP_Extend},
+ {0x0FC6, 0x0FC6, GBP_Extend},
+ {0x102D, 0x1030, GBP_Extend},
+ {0x1031, 0x1031, GBP_SpacingMark},
+ {0x1032, 0x1037, GBP_Extend},
+ {0x1039, 0x103A, GBP_Extend},
+ {0x103B, 0x103C, GBP_SpacingMark},
+ {0x103D, 0x103E, GBP_Extend},
+ {0x1056, 0x1057, GBP_SpacingMark},
+ {0x1058, 0x1059, GBP_Extend},
+ {0x105E, 0x1060, GBP_Extend},
+ {0x1071, 0x1074, GBP_Extend},
+ {0x1082, 0x1082, GBP_Extend},
+ {0x1084, 0x1084, GBP_SpacingMark},
+ {0x1085, 0x1086, GBP_Extend},
+ {0x108D, 0x108D, GBP_Extend},
+ {0x109D, 0x109D, GBP_Extend},
+ {0x1100, 0x115F, GBP_L},
+ {0x1160, 0x11A7, GBP_V},
+ {0x11A8, 0x11FF, GBP_T},
+ {0x135D, 0x135F, GBP_Extend},
+ {0x1712, 0x1714, GBP_Extend},
+ {0x1732, 0x1734, GBP_Extend},
+ {0x1752, 0x1753, GBP_Extend},
+ {0x1772, 0x1773, GBP_Extend},
+ {0x17B4, 0x17B5, GBP_Extend},
+ {0x17B6, 0x17B6, GBP_SpacingMark},
+ {0x17B7, 0x17BD, GBP_Extend},
+ {0x17BE, 0x17C5, GBP_SpacingMark},
+ {0x17C6, 0x17C6, GBP_Extend},
+ {0x17C7, 0x17C8, GBP_SpacingMark},
+ {0x17C9, 0x17D3, GBP_Extend},
+ {0x17DD, 0x17DD, GBP_Extend},
+ {0x180B, 0x180D, GBP_Extend},
+ {0x180E, 0x180E, GBP_Control},
+ {0x1885, 0x1886, GBP_Extend},
+ {0x18A9, 0x18A9, GBP_Extend},
+ {0x1920, 0x1922, GBP_Extend},
+ {0x1923, 0x1926, GBP_SpacingMark},
+ {0x1927, 0x1928, GBP_Extend},
+ {0x1929, 0x192B, GBP_SpacingMark},
+ {0x1930, 0x1931, GBP_SpacingMark},
+ {0x1932, 0x1932, GBP_Extend},
+ {0x1933, 0x1938, GBP_SpacingMark},
+ {0x1939, 0x193B, GBP_Extend},
+ {0x1A17, 0x1A18, GBP_Extend},
+ {0x1A19, 0x1A1A, GBP_SpacingMark},
+ {0x1A1B, 0x1A1B, GBP_Extend},
+ {0x1A55, 0x1A55, GBP_SpacingMark},
+ {0x1A56, 0x1A56, GBP_Extend},
+ {0x1A57, 0x1A57, GBP_SpacingMark},
+ {0x1A58, 0x1A5E, GBP_Extend},
+ {0x1A60, 0x1A60, GBP_Extend},
+ {0x1A62, 0x1A62, GBP_Extend},
+ {0x1A65, 0x1A6C, GBP_Extend},
+ {0x1A6D, 0x1A72, GBP_SpacingMark},
+ {0x1A73, 0x1A7C, GBP_Extend},
+ {0x1A7F, 0x1A7F, GBP_Extend},
+ {0x1AB0, 0x1ABD, GBP_Extend},
+ {0x1ABE, 0x1ABE, GBP_Extend},
+ {0x1B00, 0x1B03, GBP_Extend},
+ {0x1B04, 0x1B04, GBP_SpacingMark},
+ {0x1B34, 0x1B34, GBP_Extend},
+ {0x1B35, 0x1B35, GBP_SpacingMark},
+ {0x1B36, 0x1B3A, GBP_Extend},
+ {0x1B3B, 0x1B3B, GBP_SpacingMark},
+ {0x1B3C, 0x1B3C, GBP_Extend},
+ {0x1B3D, 0x1B41, GBP_SpacingMark},
+ {0x1B42, 0x1B42, GBP_Extend},
+ {0x1B43, 0x1B44, GBP_SpacingMark},
+ {0x1B6B, 0x1B73, GBP_Extend},
+ {0x1B80, 0x1B81, GBP_Extend},
+ {0x1B82, 0x1B82, GBP_SpacingMark},
+ {0x1BA1, 0x1BA1, GBP_SpacingMark},
+ {0x1BA2, 0x1BA5, GBP_Extend},
+ {0x1BA6, 0x1BA7, GBP_SpacingMark},
+ {0x1BA8, 0x1BA9, GBP_Extend},
+ {0x1BAA, 0x1BAA, GBP_SpacingMark},
+ {0x1BAB, 0x1BAD, GBP_Extend},
+ {0x1BE6, 0x1BE6, GBP_Extend},
+ {0x1BE7, 0x1BE7, GBP_SpacingMark},
+ {0x1BE8, 0x1BE9, GBP_Extend},
+ {0x1BEA, 0x1BEC, GBP_SpacingMark},
+ {0x1BED, 0x1BED, GBP_Extend},
+ {0x1BEE, 0x1BEE, GBP_SpacingMark},
+ {0x1BEF, 0x1BF1, GBP_Extend},
+ {0x1BF2, 0x1BF3, GBP_SpacingMark},
+ {0x1C24, 0x1C2B, GBP_SpacingMark},
+ {0x1C2C, 0x1C33, GBP_Extend},
+ {0x1C34, 0x1C35, GBP_SpacingMark},
+ {0x1C36, 0x1C37, GBP_Extend},
+ {0x1CD0, 0x1CD2, GBP_Extend},
+ {0x1CD4, 0x1CE0, GBP_Extend},
+ {0x1CE1, 0x1CE1, GBP_SpacingMark},
+ {0x1CE2, 0x1CE8, GBP_Extend},
+ {0x1CED, 0x1CED, GBP_Extend},
+ {0x1CF2, 0x1CF3, GBP_SpacingMark},
+ {0x1CF4, 0x1CF4, GBP_Extend},
+ {0x1CF8, 0x1CF9, GBP_Extend},
+ {0x1DC0, 0x1DF5, GBP_Extend},
+ {0x1DFB, 0x1DFF, GBP_Extend},
+ {0x200B, 0x200B, GBP_Control},
+ {0x200C, 0x200C, GBP_Extend},
+ {0x200D, 0x200D, GBP_ZWJ},
+ {0x200E, 0x200F, GBP_Control},
+ {0x2028, 0x2028, GBP_Control},
+ {0x2029, 0x2029, GBP_Control},
+ {0x202A, 0x202E, GBP_Control},
+ {0x2060, 0x2064, GBP_Control},
+ {0x2065, 0x2065, GBP_Control},
+ {0x2066, 0x206F, GBP_Control},
+ {0x20D0, 0x20DC, GBP_Extend},
+ {0x20DD, 0x20E0, GBP_Extend},
+ {0x20E1, 0x20E1, GBP_Extend},
+ {0x20E2, 0x20E4, GBP_Extend},
+ {0x20E5, 0x20F0, GBP_Extend},
+ {0x261D, 0x261D, GBP_E_Base},
+ {0x26F9, 0x26F9, GBP_E_Base},
+ {0x270A, 0x270D, GBP_E_Base},
+ {0x2764, 0x2764, GBP_Glue_After_Zwj},
+ {0x2CEF, 0x2CF1, GBP_Extend},
+ {0x2D7F, 0x2D7F, GBP_Extend},
+ {0x2DE0, 0x2DFF, GBP_Extend},
+ {0x302A, 0x302D, GBP_Extend},
+ {0x302E, 0x302F, GBP_Extend},
+ {0x3099, 0x309A, GBP_Extend},
+ {0xA66F, 0xA66F, GBP_Extend},
+ {0xA670, 0xA672, GBP_Extend},
+ {0xA674, 0xA67D, GBP_Extend},
+ {0xA69E, 0xA69F, GBP_Extend},
+ {0xA6F0, 0xA6F1, GBP_Extend},
+ {0xA802, 0xA802, GBP_Extend},
+ {0xA806, 0xA806, GBP_Extend},
+ {0xA80B, 0xA80B, GBP_Extend},
+ {0xA823, 0xA824, GBP_SpacingMark},
+ {0xA825, 0xA826, GBP_Extend},
+ {0xA827, 0xA827, GBP_SpacingMark},
+ {0xA880, 0xA881, GBP_SpacingMark},
+ {0xA8B4, 0xA8C3, GBP_SpacingMark},
+ {0xA8C4, 0xA8C5, GBP_Extend},
+ {0xA8E0, 0xA8F1, GBP_Extend},
+ {0xA926, 0xA92D, GBP_Extend},
+ {0xA947, 0xA951, GBP_Extend},
+ {0xA952, 0xA953, GBP_SpacingMark},
+ {0xA960, 0xA97C, GBP_L},
+ {0xA980, 0xA982, GBP_Extend},
+ {0xA983, 0xA983, GBP_SpacingMark},
+ {0xA9B3, 0xA9B3, GBP_Extend},
+ {0xA9B4, 0xA9B5, GBP_SpacingMark},
+ {0xA9B6, 0xA9B9, GBP_Extend},
+ {0xA9BA, 0xA9BB, GBP_SpacingMark},
+ {0xA9BC, 0xA9BC, GBP_Extend},
+ {0xA9BD, 0xA9C0, GBP_SpacingMark},
+ {0xA9E5, 0xA9E5, GBP_Extend},
+ {0xAA29, 0xAA2E, GBP_Extend},
+ {0xAA2F, 0xAA30, GBP_SpacingMark},
+ {0xAA31, 0xAA32, GBP_Extend},
+ {0xAA33, 0xAA34, GBP_SpacingMark},
+ {0xAA35, 0xAA36, GBP_Extend},
+ {0xAA43, 0xAA43, GBP_Extend},
+ {0xAA4C, 0xAA4C, GBP_Extend},
+ {0xAA4D, 0xAA4D, GBP_SpacingMark},
+ {0xAA7C, 0xAA7C, GBP_Extend},
+ {0xAAB0, 0xAAB0, GBP_Extend},
+ {0xAAB2, 0xAAB4, GBP_Extend},
+ {0xAAB7, 0xAAB8, GBP_Extend},
+ {0xAABE, 0xAABF, GBP_Extend},
+ {0xAAC1, 0xAAC1, GBP_Extend},
+ {0xAAEB, 0xAAEB, GBP_SpacingMark},
+ {0xAAEC, 0xAAED, GBP_Extend},
+ {0xAAEE, 0xAAEF, GBP_SpacingMark},
+ {0xAAF5, 0xAAF5, GBP_SpacingMark},
+ {0xAAF6, 0xAAF6, GBP_Extend},
+ {0xABE3, 0xABE4, GBP_SpacingMark},
+ {0xABE5, 0xABE5, GBP_Extend},
+ {0xABE6, 0xABE7, GBP_SpacingMark},
+ {0xABE8, 0xABE8, GBP_Extend},
+ {0xABE9, 0xABEA, GBP_SpacingMark},
+ {0xABEC, 0xABEC, GBP_SpacingMark},
+ {0xABED, 0xABED, GBP_Extend},
+ {0xAC00, 0xAC00, GBP_LV},
+ {0xAC01, 0xAC1B, GBP_LVT},
+ {0xAC1C, 0xAC1C, GBP_LV},
+ {0xAC1D, 0xAC37, GBP_LVT},
+ {0xAC38, 0xAC38, GBP_LV},
+ {0xAC39, 0xAC53, GBP_LVT},
+ {0xAC54, 0xAC54, GBP_LV},
+ {0xAC55, 0xAC6F, GBP_LVT},
+ {0xAC70, 0xAC70, GBP_LV},
+ {0xAC71, 0xAC8B, GBP_LVT},
+ {0xAC8C, 0xAC8C, GBP_LV},
+ {0xAC8D, 0xACA7, GBP_LVT},
+ {0xACA8, 0xACA8, GBP_LV},
+ {0xACA9, 0xACC3, GBP_LVT},
+ {0xACC4, 0xACC4, GBP_LV},
+ {0xACC5, 0xACDF, GBP_LVT},
+ {0xACE0, 0xACE0, GBP_LV},
+ {0xACE1, 0xACFB, GBP_LVT},
+ {0xACFC, 0xACFC, GBP_LV},
+ {0xACFD, 0xAD17, GBP_LVT},
+ {0xAD18, 0xAD18, GBP_LV},
+ {0xAD19, 0xAD33, GBP_LVT},
+ {0xAD34, 0xAD34, GBP_LV},
+ {0xAD35, 0xAD4F, GBP_LVT},
+ {0xAD50, 0xAD50, GBP_LV},
+ {0xAD51, 0xAD6B, GBP_LVT},
+ {0xAD6C, 0xAD6C, GBP_LV},
+ {0xAD6D, 0xAD87, GBP_LVT},
+ {0xAD88, 0xAD88, GBP_LV},
+ {0xAD89, 0xADA3, GBP_LVT},
+ {0xADA4, 0xADA4, GBP_LV},
+ {0xADA5, 0xADBF, GBP_LVT},
+ {0xADC0, 0xADC0, GBP_LV},
+ {0xADC1, 0xADDB, GBP_LVT},
+ {0xADDC, 0xADDC, GBP_LV},
+ {0xADDD, 0xADF7, GBP_LVT},
+ {0xADF8, 0xADF8, GBP_LV},
+ {0xADF9, 0xAE13, GBP_LVT},
+ {0xAE14, 0xAE14, GBP_LV},
+ {0xAE15, 0xAE2F, GBP_LVT},
+ {0xAE30, 0xAE30, GBP_LV},
+ {0xAE31, 0xAE4B, GBP_LVT},
+ {0xAE4C, 0xAE4C, GBP_LV},
+ {0xAE4D, 0xAE67, GBP_LVT},
+ {0xAE68, 0xAE68, GBP_LV},
+ {0xAE69, 0xAE83, GBP_LVT},
+ {0xAE84, 0xAE84, GBP_LV},
+ {0xAE85, 0xAE9F, GBP_LVT},
+ {0xAEA0, 0xAEA0, GBP_LV},
+ {0xAEA1, 0xAEBB, GBP_LVT},
+ {0xAEBC, 0xAEBC, GBP_LV},
+ {0xAEBD, 0xAED7, GBP_LVT},
+ {0xAED8, 0xAED8, GBP_LV},
+ {0xAED9, 0xAEF3, GBP_LVT},
+ {0xAEF4, 0xAEF4, GBP_LV},
+ {0xAEF5, 0xAF0F, GBP_LVT},
+ {0xAF10, 0xAF10, GBP_LV},
+ {0xAF11, 0xAF2B, GBP_LVT},
+ {0xAF2C, 0xAF2C, GBP_LV},
+ {0xAF2D, 0xAF47, GBP_LVT},
+ {0xAF48, 0xAF48, GBP_LV},
+ {0xAF49, 0xAF63, GBP_LVT},
+ {0xAF64, 0xAF64, GBP_LV},
+ {0xAF65, 0xAF7F, GBP_LVT},
+ {0xAF80, 0xAF80, GBP_LV},
+ {0xAF81, 0xAF9B, GBP_LVT},
+ {0xAF9C, 0xAF9C, GBP_LV},
+ {0xAF9D, 0xAFB7, GBP_LVT},
+ {0xAFB8, 0xAFB8, GBP_LV},
+ {0xAFB9, 0xAFD3, GBP_LVT},
+ {0xAFD4, 0xAFD4, GBP_LV},
+ {0xAFD5, 0xAFEF, GBP_LVT},
+ {0xAFF0, 0xAFF0, GBP_LV},
+ {0xAFF1, 0xB00B, GBP_LVT},
+ {0xB00C, 0xB00C, GBP_LV},
+ {0xB00D, 0xB027, GBP_LVT},
+ {0xB028, 0xB028, GBP_LV},
+ {0xB029, 0xB043, GBP_LVT},
+ {0xB044, 0xB044, GBP_LV},
+ {0xB045, 0xB05F, GBP_LVT},
+ {0xB060, 0xB060, GBP_LV},
+ {0xB061, 0xB07B, GBP_LVT},
+ {0xB07C, 0xB07C, GBP_LV},
+ {0xB07D, 0xB097, GBP_LVT},
+ {0xB098, 0xB098, GBP_LV},
+ {0xB099, 0xB0B3, GBP_LVT},
+ {0xB0B4, 0xB0B4, GBP_LV},
+ {0xB0B5, 0xB0CF, GBP_LVT},
+ {0xB0D0, 0xB0D0, GBP_LV},
+ {0xB0D1, 0xB0EB, GBP_LVT},
+ {0xB0EC, 0xB0EC, GBP_LV},
+ {0xB0ED, 0xB107, GBP_LVT},
+ {0xB108, 0xB108, GBP_LV},
+ {0xB109, 0xB123, GBP_LVT},
+ {0xB124, 0xB124, GBP_LV},
+ {0xB125, 0xB13F, GBP_LVT},
+ {0xB140, 0xB140, GBP_LV},
+ {0xB141, 0xB15B, GBP_LVT},
+ {0xB15C, 0xB15C, GBP_LV},
+ {0xB15D, 0xB177, GBP_LVT},
+ {0xB178, 0xB178, GBP_LV},
+ {0xB179, 0xB193, GBP_LVT},
+ {0xB194, 0xB194, GBP_LV},
+ {0xB195, 0xB1AF, GBP_LVT},
+ {0xB1B0, 0xB1B0, GBP_LV},
+ {0xB1B1, 0xB1CB, GBP_LVT},
+ {0xB1CC, 0xB1CC, GBP_LV},
+ {0xB1CD, 0xB1E7, GBP_LVT},
+ {0xB1E8, 0xB1E8, GBP_LV},
+ {0xB1E9, 0xB203, GBP_LVT},
+ {0xB204, 0xB204, GBP_LV},
+ {0xB205, 0xB21F, GBP_LVT},
+ {0xB220, 0xB220, GBP_LV},
+ {0xB221, 0xB23B, GBP_LVT},
+ {0xB23C, 0xB23C, GBP_LV},
+ {0xB23D, 0xB257, GBP_LVT},
+ {0xB258, 0xB258, GBP_LV},
+ {0xB259, 0xB273, GBP_LVT},
+ {0xB274, 0xB274, GBP_LV},
+ {0xB275, 0xB28F, GBP_LVT},
+ {0xB290, 0xB290, GBP_LV},
+ {0xB291, 0xB2AB, GBP_LVT},
+ {0xB2AC, 0xB2AC, GBP_LV},
+ {0xB2AD, 0xB2C7, GBP_LVT},
+ {0xB2C8, 0xB2C8, GBP_LV},
+ {0xB2C9, 0xB2E3, GBP_LVT},
+ {0xB2E4, 0xB2E4, GBP_LV},
+ {0xB2E5, 0xB2FF, GBP_LVT},
+ {0xB300, 0xB300, GBP_LV},
+ {0xB301, 0xB31B, GBP_LVT},
+ {0xB31C, 0xB31C, GBP_LV},
+ {0xB31D, 0xB337, GBP_LVT},
+ {0xB338, 0xB338, GBP_LV},
+ {0xB339, 0xB353, GBP_LVT},
+ {0xB354, 0xB354, GBP_LV},
+ {0xB355, 0xB36F, GBP_LVT},
+ {0xB370, 0xB370, GBP_LV},
+ {0xB371, 0xB38B, GBP_LVT},
+ {0xB38C, 0xB38C, GBP_LV},
+ {0xB38D, 0xB3A7, GBP_LVT},
+ {0xB3A8, 0xB3A8, GBP_LV},
+ {0xB3A9, 0xB3C3, GBP_LVT},
+ {0xB3C4, 0xB3C4, GBP_LV},
+ {0xB3C5, 0xB3DF, GBP_LVT},
+ {0xB3E0, 0xB3E0, GBP_LV},
+ {0xB3E1, 0xB3FB, GBP_LVT},
+ {0xB3FC, 0xB3FC, GBP_LV},
+ {0xB3FD, 0xB417, GBP_LVT},
+ {0xB418, 0xB418, GBP_LV},
+ {0xB419, 0xB433, GBP_LVT},
+ {0xB434, 0xB434, GBP_LV},
+ {0xB435, 0xB44F, GBP_LVT},
+ {0xB450, 0xB450, GBP_LV},
+ {0xB451, 0xB46B, GBP_LVT},
+ {0xB46C, 0xB46C, GBP_LV},
+ {0xB46D, 0xB487, GBP_LVT},
+ {0xB488, 0xB488, GBP_LV},
+ {0xB489, 0xB4A3, GBP_LVT},
+ {0xB4A4, 0xB4A4, GBP_LV},
+ {0xB4A5, 0xB4BF, GBP_LVT},
+ {0xB4C0, 0xB4C0, GBP_LV},
+ {0xB4C1, 0xB4DB, GBP_LVT},
+ {0xB4DC, 0xB4DC, GBP_LV},
+ {0xB4DD, 0xB4F7, GBP_LVT},
+ {0xB4F8, 0xB4F8, GBP_LV},
+ {0xB4F9, 0xB513, GBP_LVT},
+ {0xB514, 0xB514, GBP_LV},
+ {0xB515, 0xB52F, GBP_LVT},
+ {0xB530, 0xB530, GBP_LV},
+ {0xB531, 0xB54B, GBP_LVT},
+ {0xB54C, 0xB54C, GBP_LV},
+ {0xB54D, 0xB567, GBP_LVT},
+ {0xB568, 0xB568, GBP_LV},
+ {0xB569, 0xB583, GBP_LVT},
+ {0xB584, 0xB584, GBP_LV},
+ {0xB585, 0xB59F, GBP_LVT},
+ {0xB5A0, 0xB5A0, GBP_LV},
+ {0xB5A1, 0xB5BB, GBP_LVT},
+ {0xB5BC, 0xB5BC, GBP_LV},
+ {0xB5BD, 0xB5D7, GBP_LVT},
+ {0xB5D8, 0xB5D8, GBP_LV},
+ {0xB5D9, 0xB5F3, GBP_LVT},
+ {0xB5F4, 0xB5F4, GBP_LV},
+ {0xB5F5, 0xB60F, GBP_LVT},
+ {0xB610, 0xB610, GBP_LV},
+ {0xB611, 0xB62B, GBP_LVT},
+ {0xB62C, 0xB62C, GBP_LV},
+ {0xB62D, 0xB647, GBP_LVT},
+ {0xB648, 0xB648, GBP_LV},
+ {0xB649, 0xB663, GBP_LVT},
+ {0xB664, 0xB664, GBP_LV},
+ {0xB665, 0xB67F, GBP_LVT},
+ {0xB680, 0xB680, GBP_LV},
+ {0xB681, 0xB69B, GBP_LVT},
+ {0xB69C, 0xB69C, GBP_LV},
+ {0xB69D, 0xB6B7, GBP_LVT},
+ {0xB6B8, 0xB6B8, GBP_LV},
+ {0xB6B9, 0xB6D3, GBP_LVT},
+ {0xB6D4, 0xB6D4, GBP_LV},
+ {0xB6D5, 0xB6EF, GBP_LVT},
+ {0xB6F0, 0xB6F0, GBP_LV},
+ {0xB6F1, 0xB70B, GBP_LVT},
+ {0xB70C, 0xB70C, GBP_LV},
+ {0xB70D, 0xB727, GBP_LVT},
+ {0xB728, 0xB728, GBP_LV},
+ {0xB729, 0xB743, GBP_LVT},
+ {0xB744, 0xB744, GBP_LV},
+ {0xB745, 0xB75F, GBP_LVT},
+ {0xB760, 0xB760, GBP_LV},
+ {0xB761, 0xB77B, GBP_LVT},
+ {0xB77C, 0xB77C, GBP_LV},
+ {0xB77D, 0xB797, GBP_LVT},
+ {0xB798, 0xB798, GBP_LV},
+ {0xB799, 0xB7B3, GBP_LVT},
+ {0xB7B4, 0xB7B4, GBP_LV},
+ {0xB7B5, 0xB7CF, GBP_LVT},
+ {0xB7D0, 0xB7D0, GBP_LV},
+ {0xB7D1, 0xB7EB, GBP_LVT},
+ {0xB7EC, 0xB7EC, GBP_LV},
+ {0xB7ED, 0xB807, GBP_LVT},
+ {0xB808, 0xB808, GBP_LV},
+ {0xB809, 0xB823, GBP_LVT},
+ {0xB824, 0xB824, GBP_LV},
+ {0xB825, 0xB83F, GBP_LVT},
+ {0xB840, 0xB840, GBP_LV},
+ {0xB841, 0xB85B, GBP_LVT},
+ {0xB85C, 0xB85C, GBP_LV},
+ {0xB85D, 0xB877, GBP_LVT},
+ {0xB878, 0xB878, GBP_LV},
+ {0xB879, 0xB893, GBP_LVT},
+ {0xB894, 0xB894, GBP_LV},
+ {0xB895, 0xB8AF, GBP_LVT},
+ {0xB8B0, 0xB8B0, GBP_LV},
+ {0xB8B1, 0xB8CB, GBP_LVT},
+ {0xB8CC, 0xB8CC, GBP_LV},
+ {0xB8CD, 0xB8E7, GBP_LVT},
+ {0xB8E8, 0xB8E8, GBP_LV},
+ {0xB8E9, 0xB903, GBP_LVT},
+ {0xB904, 0xB904, GBP_LV},
+ {0xB905, 0xB91F, GBP_LVT},
+ {0xB920, 0xB920, GBP_LV},
+ {0xB921, 0xB93B, GBP_LVT},
+ {0xB93C, 0xB93C, GBP_LV},
+ {0xB93D, 0xB957, GBP_LVT},
+ {0xB958, 0xB958, GBP_LV},
+ {0xB959, 0xB973, GBP_LVT},
+ {0xB974, 0xB974, GBP_LV},
+ {0xB975, 0xB98F, GBP_LVT},
+ {0xB990, 0xB990, GBP_LV},
+ {0xB991, 0xB9AB, GBP_LVT},
+ {0xB9AC, 0xB9AC, GBP_LV},
+ {0xB9AD, 0xB9C7, GBP_LVT},
+ {0xB9C8, 0xB9C8, GBP_LV},
+ {0xB9C9, 0xB9E3, GBP_LVT},
+ {0xB9E4, 0xB9E4, GBP_LV},
+ {0xB9E5, 0xB9FF, GBP_LVT},
+ {0xBA00, 0xBA00, GBP_LV},
+ {0xBA01, 0xBA1B, GBP_LVT},
+ {0xBA1C, 0xBA1C, GBP_LV},
+ {0xBA1D, 0xBA37, GBP_LVT},
+ {0xBA38, 0xBA38, GBP_LV},
+ {0xBA39, 0xBA53, GBP_LVT},
+ {0xBA54, 0xBA54, GBP_LV},
+ {0xBA55, 0xBA6F, GBP_LVT},
+ {0xBA70, 0xBA70, GBP_LV},
+ {0xBA71, 0xBA8B, GBP_LVT},
+ {0xBA8C, 0xBA8C, GBP_LV},
+ {0xBA8D, 0xBAA7, GBP_LVT},
+ {0xBAA8, 0xBAA8, GBP_LV},
+ {0xBAA9, 0xBAC3, GBP_LVT},
+ {0xBAC4, 0xBAC4, GBP_LV},
+ {0xBAC5, 0xBADF, GBP_LVT},
+ {0xBAE0, 0xBAE0, GBP_LV},
+ {0xBAE1, 0xBAFB, GBP_LVT},
+ {0xBAFC, 0xBAFC, GBP_LV},
+ {0xBAFD, 0xBB17, GBP_LVT},
+ {0xBB18, 0xBB18, GBP_LV},
+ {0xBB19, 0xBB33, GBP_LVT},
+ {0xBB34, 0xBB34, GBP_LV},
+ {0xBB35, 0xBB4F, GBP_LVT},
+ {0xBB50, 0xBB50, GBP_LV},
+ {0xBB51, 0xBB6B, GBP_LVT},
+ {0xBB6C, 0xBB6C, GBP_LV},
+ {0xBB6D, 0xBB87, GBP_LVT},
+ {0xBB88, 0xBB88, GBP_LV},
+ {0xBB89, 0xBBA3, GBP_LVT},
+ {0xBBA4, 0xBBA4, GBP_LV},
+ {0xBBA5, 0xBBBF, GBP_LVT},
+ {0xBBC0, 0xBBC0, GBP_LV},
+ {0xBBC1, 0xBBDB, GBP_LVT},
+ {0xBBDC, 0xBBDC, GBP_LV},
+ {0xBBDD, 0xBBF7, GBP_LVT},
+ {0xBBF8, 0xBBF8, GBP_LV},
+ {0xBBF9, 0xBC13, GBP_LVT},
+ {0xBC14, 0xBC14, GBP_LV},
+ {0xBC15, 0xBC2F, GBP_LVT},
+ {0xBC30, 0xBC30, GBP_LV},
+ {0xBC31, 0xBC4B, GBP_LVT},
+ {0xBC4C, 0xBC4C, GBP_LV},
+ {0xBC4D, 0xBC67, GBP_LVT},
+ {0xBC68, 0xBC68, GBP_LV},
+ {0xBC69, 0xBC83, GBP_LVT},
+ {0xBC84, 0xBC84, GBP_LV},
+ {0xBC85, 0xBC9F, GBP_LVT},
+ {0xBCA0, 0xBCA0, GBP_LV},
+ {0xBCA1, 0xBCBB, GBP_LVT},
+ {0xBCBC, 0xBCBC, GBP_LV},
+ {0xBCBD, 0xBCD7, GBP_LVT},
+ {0xBCD8, 0xBCD8, GBP_LV},
+ {0xBCD9, 0xBCF3, GBP_LVT},
+ {0xBCF4, 0xBCF4, GBP_LV},
+ {0xBCF5, 0xBD0F, GBP_LVT},
+ {0xBD10, 0xBD10, GBP_LV},
+ {0xBD11, 0xBD2B, GBP_LVT},
+ {0xBD2C, 0xBD2C, GBP_LV},
+ {0xBD2D, 0xBD47, GBP_LVT},
+ {0xBD48, 0xBD48, GBP_LV},
+ {0xBD49, 0xBD63, GBP_LVT},
+ {0xBD64, 0xBD64, GBP_LV},
+ {0xBD65, 0xBD7F, GBP_LVT},
+ {0xBD80, 0xBD80, GBP_LV},
+ {0xBD81, 0xBD9B, GBP_LVT},
+ {0xBD9C, 0xBD9C, GBP_LV},
+ {0xBD9D, 0xBDB7, GBP_LVT},
+ {0xBDB8, 0xBDB8, GBP_LV},
+ {0xBDB9, 0xBDD3, GBP_LVT},
+ {0xBDD4, 0xBDD4, GBP_LV},
+ {0xBDD5, 0xBDEF, GBP_LVT},
+ {0xBDF0, 0xBDF0, GBP_LV},
+ {0xBDF1, 0xBE0B, GBP_LVT},
+ {0xBE0C, 0xBE0C, GBP_LV},
+ {0xBE0D, 0xBE27, GBP_LVT},
+ {0xBE28, 0xBE28, GBP_LV},
+ {0xBE29, 0xBE43, GBP_LVT},
+ {0xBE44, 0xBE44, GBP_LV},
+ {0xBE45, 0xBE5F, GBP_LVT},
+ {0xBE60, 0xBE60, GBP_LV},
+ {0xBE61, 0xBE7B, GBP_LVT},
+ {0xBE7C, 0xBE7C, GBP_LV},
+ {0xBE7D, 0xBE97, GBP_LVT},
+ {0xBE98, 0xBE98, GBP_LV},
+ {0xBE99, 0xBEB3, GBP_LVT},
+ {0xBEB4, 0xBEB4, GBP_LV},
+ {0xBEB5, 0xBECF, GBP_LVT},
+ {0xBED0, 0xBED0, GBP_LV},
+ {0xBED1, 0xBEEB, GBP_LVT},
+ {0xBEEC, 0xBEEC, GBP_LV},
+ {0xBEED, 0xBF07, GBP_LVT},
+ {0xBF08, 0xBF08, GBP_LV},
+ {0xBF09, 0xBF23, GBP_LVT},
+ {0xBF24, 0xBF24, GBP_LV},
+ {0xBF25, 0xBF3F, GBP_LVT},
+ {0xBF40, 0xBF40, GBP_LV},
+ {0xBF41, 0xBF5B, GBP_LVT},
+ {0xBF5C, 0xBF5C, GBP_LV},
+ {0xBF5D, 0xBF77, GBP_LVT},
+ {0xBF78, 0xBF78, GBP_LV},
+ {0xBF79, 0xBF93, GBP_LVT},
+ {0xBF94, 0xBF94, GBP_LV},
+ {0xBF95, 0xBFAF, GBP_LVT},
+ {0xBFB0, 0xBFB0, GBP_LV},
+ {0xBFB1, 0xBFCB, GBP_LVT},
+ {0xBFCC, 0xBFCC, GBP_LV},
+ {0xBFCD, 0xBFE7, GBP_LVT},
+ {0xBFE8, 0xBFE8, GBP_LV},
+ {0xBFE9, 0xC003, GBP_LVT},
+ {0xC004, 0xC004, GBP_LV},
+ {0xC005, 0xC01F, GBP_LVT},
+ {0xC020, 0xC020, GBP_LV},
+ {0xC021, 0xC03B, GBP_LVT},
+ {0xC03C, 0xC03C, GBP_LV},
+ {0xC03D, 0xC057, GBP_LVT},
+ {0xC058, 0xC058, GBP_LV},
+ {0xC059, 0xC073, GBP_LVT},
+ {0xC074, 0xC074, GBP_LV},
+ {0xC075, 0xC08F, GBP_LVT},
+ {0xC090, 0xC090, GBP_LV},
+ {0xC091, 0xC0AB, GBP_LVT},
+ {0xC0AC, 0xC0AC, GBP_LV},
+ {0xC0AD, 0xC0C7, GBP_LVT},
+ {0xC0C8, 0xC0C8, GBP_LV},
+ {0xC0C9, 0xC0E3, GBP_LVT},
+ {0xC0E4, 0xC0E4, GBP_LV},
+ {0xC0E5, 0xC0FF, GBP_LVT},
+ {0xC100, 0xC100, GBP_LV},
+ {0xC101, 0xC11B, GBP_LVT},
+ {0xC11C, 0xC11C, GBP_LV},
+ {0xC11D, 0xC137, GBP_LVT},
+ {0xC138, 0xC138, GBP_LV},
+ {0xC139, 0xC153, GBP_LVT},
+ {0xC154, 0xC154, GBP_LV},
+ {0xC155, 0xC16F, GBP_LVT},
+ {0xC170, 0xC170, GBP_LV},
+ {0xC171, 0xC18B, GBP_LVT},
+ {0xC18C, 0xC18C, GBP_LV},
+ {0xC18D, 0xC1A7, GBP_LVT},
+ {0xC1A8, 0xC1A8, GBP_LV},
+ {0xC1A9, 0xC1C3, GBP_LVT},
+ {0xC1C4, 0xC1C4, GBP_LV},
+ {0xC1C5, 0xC1DF, GBP_LVT},
+ {0xC1E0, 0xC1E0, GBP_LV},
+ {0xC1E1, 0xC1FB, GBP_LVT},
+ {0xC1FC, 0xC1FC, GBP_LV},
+ {0xC1FD, 0xC217, GBP_LVT},
+ {0xC218, 0xC218, GBP_LV},
+ {0xC219, 0xC233, GBP_LVT},
+ {0xC234, 0xC234, GBP_LV},
+ {0xC235, 0xC24F, GBP_LVT},
+ {0xC250, 0xC250, GBP_LV},
+ {0xC251, 0xC26B, GBP_LVT},
+ {0xC26C, 0xC26C, GBP_LV},
+ {0xC26D, 0xC287, GBP_LVT},
+ {0xC288, 0xC288, GBP_LV},
+ {0xC289, 0xC2A3, GBP_LVT},
+ {0xC2A4, 0xC2A4, GBP_LV},
+ {0xC2A5, 0xC2BF, GBP_LVT},
+ {0xC2C0, 0xC2C0, GBP_LV},
+ {0xC2C1, 0xC2DB, GBP_LVT},
+ {0xC2DC, 0xC2DC, GBP_LV},
+ {0xC2DD, 0xC2F7, GBP_LVT},
+ {0xC2F8, 0xC2F8, GBP_LV},
+ {0xC2F9, 0xC313, GBP_LVT},
+ {0xC314, 0xC314, GBP_LV},
+ {0xC315, 0xC32F, GBP_LVT},
+ {0xC330, 0xC330, GBP_LV},
+ {0xC331, 0xC34B, GBP_LVT},
+ {0xC34C, 0xC34C, GBP_LV},
+ {0xC34D, 0xC367, GBP_LVT},
+ {0xC368, 0xC368, GBP_LV},
+ {0xC369, 0xC383, GBP_LVT},
+ {0xC384, 0xC384, GBP_LV},
+ {0xC385, 0xC39F, GBP_LVT},
+ {0xC3A0, 0xC3A0, GBP_LV},
+ {0xC3A1, 0xC3BB, GBP_LVT},
+ {0xC3BC, 0xC3BC, GBP_LV},
+ {0xC3BD, 0xC3D7, GBP_LVT},
+ {0xC3D8, 0xC3D8, GBP_LV},
+ {0xC3D9, 0xC3F3, GBP_LVT},
+ {0xC3F4, 0xC3F4, GBP_LV},
+ {0xC3F5, 0xC40F, GBP_LVT},
+ {0xC410, 0xC410, GBP_LV},
+ {0xC411, 0xC42B, GBP_LVT},
+ {0xC42C, 0xC42C, GBP_LV},
+ {0xC42D, 0xC447, GBP_LVT},
+ {0xC448, 0xC448, GBP_LV},
+ {0xC449, 0xC463, GBP_LVT},
+ {0xC464, 0xC464, GBP_LV},
+ {0xC465, 0xC47F, GBP_LVT},
+ {0xC480, 0xC480, GBP_LV},
+ {0xC481, 0xC49B, GBP_LVT},
+ {0xC49C, 0xC49C, GBP_LV},
+ {0xC49D, 0xC4B7, GBP_LVT},
+ {0xC4B8, 0xC4B8, GBP_LV},
+ {0xC4B9, 0xC4D3, GBP_LVT},
+ {0xC4D4, 0xC4D4, GBP_LV},
+ {0xC4D5, 0xC4EF, GBP_LVT},
+ {0xC4F0, 0xC4F0, GBP_LV},
+ {0xC4F1, 0xC50B, GBP_LVT},
+ {0xC50C, 0xC50C, GBP_LV},
+ {0xC50D, 0xC527, GBP_LVT},
+ {0xC528, 0xC528, GBP_LV},
+ {0xC529, 0xC543, GBP_LVT},
+ {0xC544, 0xC544, GBP_LV},
+ {0xC545, 0xC55F, GBP_LVT},
+ {0xC560, 0xC560, GBP_LV},
+ {0xC561, 0xC57B, GBP_LVT},
+ {0xC57C, 0xC57C, GBP_LV},
+ {0xC57D, 0xC597, GBP_LVT},
+ {0xC598, 0xC598, GBP_LV},
+ {0xC599, 0xC5B3, GBP_LVT},
+ {0xC5B4, 0xC5B4, GBP_LV},
+ {0xC5B5, 0xC5CF, GBP_LVT},
+ {0xC5D0, 0xC5D0, GBP_LV},
+ {0xC5D1, 0xC5EB, GBP_LVT},
+ {0xC5EC, 0xC5EC, GBP_LV},
+ {0xC5ED, 0xC607, GBP_LVT},
+ {0xC608, 0xC608, GBP_LV},
+ {0xC609, 0xC623, GBP_LVT},
+ {0xC624, 0xC624, GBP_LV},
+ {0xC625, 0xC63F, GBP_LVT},
+ {0xC640, 0xC640, GBP_LV},
+ {0xC641, 0xC65B, GBP_LVT},
+ {0xC65C, 0xC65C, GBP_LV},
+ {0xC65D, 0xC677, GBP_LVT},
+ {0xC678, 0xC678, GBP_LV},
+ {0xC679, 0xC693, GBP_LVT},
+ {0xC694, 0xC694, GBP_LV},
+ {0xC695, 0xC6AF, GBP_LVT},
+ {0xC6B0, 0xC6B0, GBP_LV},
+ {0xC6B1, 0xC6CB, GBP_LVT},
+ {0xC6CC, 0xC6CC, GBP_LV},
+ {0xC6CD, 0xC6E7, GBP_LVT},
+ {0xC6E8, 0xC6E8, GBP_LV},
+ {0xC6E9, 0xC703, GBP_LVT},
+ {0xC704, 0xC704, GBP_LV},
+ {0xC705, 0xC71F, GBP_LVT},
+ {0xC720, 0xC720, GBP_LV},
+ {0xC721, 0xC73B, GBP_LVT},
+ {0xC73C, 0xC73C, GBP_LV},
+ {0xC73D, 0xC757, GBP_LVT},
+ {0xC758, 0xC758, GBP_LV},
+ {0xC759, 0xC773, GBP_LVT},
+ {0xC774, 0xC774, GBP_LV},
+ {0xC775, 0xC78F, GBP_LVT},
+ {0xC790, 0xC790, GBP_LV},
+ {0xC791, 0xC7AB, GBP_LVT},
+ {0xC7AC, 0xC7AC, GBP_LV},
+ {0xC7AD, 0xC7C7, GBP_LVT},
+ {0xC7C8, 0xC7C8, GBP_LV},
+ {0xC7C9, 0xC7E3, GBP_LVT},
+ {0xC7E4, 0xC7E4, GBP_LV},
+ {0xC7E5, 0xC7FF, GBP_LVT},
+ {0xC800, 0xC800, GBP_LV},
+ {0xC801, 0xC81B, GBP_LVT},
+ {0xC81C, 0xC81C, GBP_LV},
+ {0xC81D, 0xC837, GBP_LVT},
+ {0xC838, 0xC838, GBP_LV},
+ {0xC839, 0xC853, GBP_LVT},
+ {0xC854, 0xC854, GBP_LV},
+ {0xC855, 0xC86F, GBP_LVT},
+ {0xC870, 0xC870, GBP_LV},
+ {0xC871, 0xC88B, GBP_LVT},
+ {0xC88C, 0xC88C, GBP_LV},
+ {0xC88D, 0xC8A7, GBP_LVT},
+ {0xC8A8, 0xC8A8, GBP_LV},
+ {0xC8A9, 0xC8C3, GBP_LVT},
+ {0xC8C4, 0xC8C4, GBP_LV},
+ {0xC8C5, 0xC8DF, GBP_LVT},
+ {0xC8E0, 0xC8E0, GBP_LV},
+ {0xC8E1, 0xC8FB, GBP_LVT},
+ {0xC8FC, 0xC8FC, GBP_LV},
+ {0xC8FD, 0xC917, GBP_LVT},
+ {0xC918, 0xC918, GBP_LV},
+ {0xC919, 0xC933, GBP_LVT},
+ {0xC934, 0xC934, GBP_LV},
+ {0xC935, 0xC94F, GBP_LVT},
+ {0xC950, 0xC950, GBP_LV},
+ {0xC951, 0xC96B, GBP_LVT},
+ {0xC96C, 0xC96C, GBP_LV},
+ {0xC96D, 0xC987, GBP_LVT},
+ {0xC988, 0xC988, GBP_LV},
+ {0xC989, 0xC9A3, GBP_LVT},
+ {0xC9A4, 0xC9A4, GBP_LV},
+ {0xC9A5, 0xC9BF, GBP_LVT},
+ {0xC9C0, 0xC9C0, GBP_LV},
+ {0xC9C1, 0xC9DB, GBP_LVT},
+ {0xC9DC, 0xC9DC, GBP_LV},
+ {0xC9DD, 0xC9F7, GBP_LVT},
+ {0xC9F8, 0xC9F8, GBP_LV},
+ {0xC9F9, 0xCA13, GBP_LVT},
+ {0xCA14, 0xCA14, GBP_LV},
+ {0xCA15, 0xCA2F, GBP_LVT},
+ {0xCA30, 0xCA30, GBP_LV},
+ {0xCA31, 0xCA4B, GBP_LVT},
+ {0xCA4C, 0xCA4C, GBP_LV},
+ {0xCA4D, 0xCA67, GBP_LVT},
+ {0xCA68, 0xCA68, GBP_LV},
+ {0xCA69, 0xCA83, GBP_LVT},
+ {0xCA84, 0xCA84, GBP_LV},
+ {0xCA85, 0xCA9F, GBP_LVT},
+ {0xCAA0, 0xCAA0, GBP_LV},
+ {0xCAA1, 0xCABB, GBP_LVT},
+ {0xCABC, 0xCABC, GBP_LV},
+ {0xCABD, 0xCAD7, GBP_LVT},
+ {0xCAD8, 0xCAD8, GBP_LV},
+ {0xCAD9, 0xCAF3, GBP_LVT},
+ {0xCAF4, 0xCAF4, GBP_LV},
+ {0xCAF5, 0xCB0F, GBP_LVT},
+ {0xCB10, 0xCB10, GBP_LV},
+ {0xCB11, 0xCB2B, GBP_LVT},
+ {0xCB2C, 0xCB2C, GBP_LV},
+ {0xCB2D, 0xCB47, GBP_LVT},
+ {0xCB48, 0xCB48, GBP_LV},
+ {0xCB49, 0xCB63, GBP_LVT},
+ {0xCB64, 0xCB64, GBP_LV},
+ {0xCB65, 0xCB7F, GBP_LVT},
+ {0xCB80, 0xCB80, GBP_LV},
+ {0xCB81, 0xCB9B, GBP_LVT},
+ {0xCB9C, 0xCB9C, GBP_LV},
+ {0xCB9D, 0xCBB7, GBP_LVT},
+ {0xCBB8, 0xCBB8, GBP_LV},
+ {0xCBB9, 0xCBD3, GBP_LVT},
+ {0xCBD4, 0xCBD4, GBP_LV},
+ {0xCBD5, 0xCBEF, GBP_LVT},
+ {0xCBF0, 0xCBF0, GBP_LV},
+ {0xCBF1, 0xCC0B, GBP_LVT},
+ {0xCC0C, 0xCC0C, GBP_LV},
+ {0xCC0D, 0xCC27, GBP_LVT},
+ {0xCC28, 0xCC28, GBP_LV},
+ {0xCC29, 0xCC43, GBP_LVT},
+ {0xCC44, 0xCC44, GBP_LV},
+ {0xCC45, 0xCC5F, GBP_LVT},
+ {0xCC60, 0xCC60, GBP_LV},
+ {0xCC61, 0xCC7B, GBP_LVT},
+ {0xCC7C, 0xCC7C, GBP_LV},
+ {0xCC7D, 0xCC97, GBP_LVT},
+ {0xCC98, 0xCC98, GBP_LV},
+ {0xCC99, 0xCCB3, GBP_LVT},
+ {0xCCB4, 0xCCB4, GBP_LV},
+ {0xCCB5, 0xCCCF, GBP_LVT},
+ {0xCCD0, 0xCCD0, GBP_LV},
+ {0xCCD1, 0xCCEB, GBP_LVT},
+ {0xCCEC, 0xCCEC, GBP_LV},
+ {0xCCED, 0xCD07, GBP_LVT},
+ {0xCD08, 0xCD08, GBP_LV},
+ {0xCD09, 0xCD23, GBP_LVT},
+ {0xCD24, 0xCD24, GBP_LV},
+ {0xCD25, 0xCD3F, GBP_LVT},
+ {0xCD40, 0xCD40, GBP_LV},
+ {0xCD41, 0xCD5B, GBP_LVT},
+ {0xCD5C, 0xCD5C, GBP_LV},
+ {0xCD5D, 0xCD77, GBP_LVT},
+ {0xCD78, 0xCD78, GBP_LV},
+ {0xCD79, 0xCD93, GBP_LVT},
+ {0xCD94, 0xCD94, GBP_LV},
+ {0xCD95, 0xCDAF, GBP_LVT},
+ {0xCDB0, 0xCDB0, GBP_LV},
+ {0xCDB1, 0xCDCB, GBP_LVT},
+ {0xCDCC, 0xCDCC, GBP_LV},
+ {0xCDCD, 0xCDE7, GBP_LVT},
+ {0xCDE8, 0xCDE8, GBP_LV},
+ {0xCDE9, 0xCE03, GBP_LVT},
+ {0xCE04, 0xCE04, GBP_LV},
+ {0xCE05, 0xCE1F, GBP_LVT},
+ {0xCE20, 0xCE20, GBP_LV},
+ {0xCE21, 0xCE3B, GBP_LVT},
+ {0xCE3C, 0xCE3C, GBP_LV},
+ {0xCE3D, 0xCE57, GBP_LVT},
+ {0xCE58, 0xCE58, GBP_LV},
+ {0xCE59, 0xCE73, GBP_LVT},
+ {0xCE74, 0xCE74, GBP_LV},
+ {0xCE75, 0xCE8F, GBP_LVT},
+ {0xCE90, 0xCE90, GBP_LV},
+ {0xCE91, 0xCEAB, GBP_LVT},
+ {0xCEAC, 0xCEAC, GBP_LV},
+ {0xCEAD, 0xCEC7, GBP_LVT},
+ {0xCEC8, 0xCEC8, GBP_LV},
+ {0xCEC9, 0xCEE3, GBP_LVT},
+ {0xCEE4, 0xCEE4, GBP_LV},
+ {0xCEE5, 0xCEFF, GBP_LVT},
+ {0xCF00, 0xCF00, GBP_LV},
+ {0xCF01, 0xCF1B, GBP_LVT},
+ {0xCF1C, 0xCF1C, GBP_LV},
+ {0xCF1D, 0xCF37, GBP_LVT},
+ {0xCF38, 0xCF38, GBP_LV},
+ {0xCF39, 0xCF53, GBP_LVT},
+ {0xCF54, 0xCF54, GBP_LV},
+ {0xCF55, 0xCF6F, GBP_LVT},
+ {0xCF70, 0xCF70, GBP_LV},
+ {0xCF71, 0xCF8B, GBP_LVT},
+ {0xCF8C, 0xCF8C, GBP_LV},
+ {0xCF8D, 0xCFA7, GBP_LVT},
+ {0xCFA8, 0xCFA8, GBP_LV},
+ {0xCFA9, 0xCFC3, GBP_LVT},
+ {0xCFC4, 0xCFC4, GBP_LV},
+ {0xCFC5, 0xCFDF, GBP_LVT},
+ {0xCFE0, 0xCFE0, GBP_LV},
+ {0xCFE1, 0xCFFB, GBP_LVT},
+ {0xCFFC, 0xCFFC, GBP_LV},
+ {0xCFFD, 0xD017, GBP_LVT},
+ {0xD018, 0xD018, GBP_LV},
+ {0xD019, 0xD033, GBP_LVT},
+ {0xD034, 0xD034, GBP_LV},
+ {0xD035, 0xD04F, GBP_LVT},
+ {0xD050, 0xD050, GBP_LV},
+ {0xD051, 0xD06B, GBP_LVT},
+ {0xD06C, 0xD06C, GBP_LV},
+ {0xD06D, 0xD087, GBP_LVT},
+ {0xD088, 0xD088, GBP_LV},
+ {0xD089, 0xD0A3, GBP_LVT},
+ {0xD0A4, 0xD0A4, GBP_LV},
+ {0xD0A5, 0xD0BF, GBP_LVT},
+ {0xD0C0, 0xD0C0, GBP_LV},
+ {0xD0C1, 0xD0DB, GBP_LVT},
+ {0xD0DC, 0xD0DC, GBP_LV},
+ {0xD0DD, 0xD0F7, GBP_LVT},
+ {0xD0F8, 0xD0F8, GBP_LV},
+ {0xD0F9, 0xD113, GBP_LVT},
+ {0xD114, 0xD114, GBP_LV},
+ {0xD115, 0xD12F, GBP_LVT},
+ {0xD130, 0xD130, GBP_LV},
+ {0xD131, 0xD14B, GBP_LVT},
+ {0xD14C, 0xD14C, GBP_LV},
+ {0xD14D, 0xD167, GBP_LVT},
+ {0xD168, 0xD168, GBP_LV},
+ {0xD169, 0xD183, GBP_LVT},
+ {0xD184, 0xD184, GBP_LV},
+ {0xD185, 0xD19F, GBP_LVT},
+ {0xD1A0, 0xD1A0, GBP_LV},
+ {0xD1A1, 0xD1BB, GBP_LVT},
+ {0xD1BC, 0xD1BC, GBP_LV},
+ {0xD1BD, 0xD1D7, GBP_LVT},
+ {0xD1D8, 0xD1D8, GBP_LV},
+ {0xD1D9, 0xD1F3, GBP_LVT},
+ {0xD1F4, 0xD1F4, GBP_LV},
+ {0xD1F5, 0xD20F, GBP_LVT},
+ {0xD210, 0xD210, GBP_LV},
+ {0xD211, 0xD22B, GBP_LVT},
+ {0xD22C, 0xD22C, GBP_LV},
+ {0xD22D, 0xD247, GBP_LVT},
+ {0xD248, 0xD248, GBP_LV},
+ {0xD249, 0xD263, GBP_LVT},
+ {0xD264, 0xD264, GBP_LV},
+ {0xD265, 0xD27F, GBP_LVT},
+ {0xD280, 0xD280, GBP_LV},
+ {0xD281, 0xD29B, GBP_LVT},
+ {0xD29C, 0xD29C, GBP_LV},
+ {0xD29D, 0xD2B7, GBP_LVT},
+ {0xD2B8, 0xD2B8, GBP_LV},
+ {0xD2B9, 0xD2D3, GBP_LVT},
+ {0xD2D4, 0xD2D4, GBP_LV},
+ {0xD2D5, 0xD2EF, GBP_LVT},
+ {0xD2F0, 0xD2F0, GBP_LV},
+ {0xD2F1, 0xD30B, GBP_LVT},
+ {0xD30C, 0xD30C, GBP_LV},
+ {0xD30D, 0xD327, GBP_LVT},
+ {0xD328, 0xD328, GBP_LV},
+ {0xD329, 0xD343, GBP_LVT},
+ {0xD344, 0xD344, GBP_LV},
+ {0xD345, 0xD35F, GBP_LVT},
+ {0xD360, 0xD360, GBP_LV},
+ {0xD361, 0xD37B, GBP_LVT},
+ {0xD37C, 0xD37C, GBP_LV},
+ {0xD37D, 0xD397, GBP_LVT},
+ {0xD398, 0xD398, GBP_LV},
+ {0xD399, 0xD3B3, GBP_LVT},
+ {0xD3B4, 0xD3B4, GBP_LV},
+ {0xD3B5, 0xD3CF, GBP_LVT},
+ {0xD3D0, 0xD3D0, GBP_LV},
+ {0xD3D1, 0xD3EB, GBP_LVT},
+ {0xD3EC, 0xD3EC, GBP_LV},
+ {0xD3ED, 0xD407, GBP_LVT},
+ {0xD408, 0xD408, GBP_LV},
+ {0xD409, 0xD423, GBP_LVT},
+ {0xD424, 0xD424, GBP_LV},
+ {0xD425, 0xD43F, GBP_LVT},
+ {0xD440, 0xD440, GBP_LV},
+ {0xD441, 0xD45B, GBP_LVT},
+ {0xD45C, 0xD45C, GBP_LV},
+ {0xD45D, 0xD477, GBP_LVT},
+ {0xD478, 0xD478, GBP_LV},
+ {0xD479, 0xD493, GBP_LVT},
+ {0xD494, 0xD494, GBP_LV},
+ {0xD495, 0xD4AF, GBP_LVT},
+ {0xD4B0, 0xD4B0, GBP_LV},
+ {0xD4B1, 0xD4CB, GBP_LVT},
+ {0xD4CC, 0xD4CC, GBP_LV},
+ {0xD4CD, 0xD4E7, GBP_LVT},
+ {0xD4E8, 0xD4E8, GBP_LV},
+ {0xD4E9, 0xD503, GBP_LVT},
+ {0xD504, 0xD504, GBP_LV},
+ {0xD505, 0xD51F, GBP_LVT},
+ {0xD520, 0xD520, GBP_LV},
+ {0xD521, 0xD53B, GBP_LVT},
+ {0xD53C, 0xD53C, GBP_LV},
+ {0xD53D, 0xD557, GBP_LVT},
+ {0xD558, 0xD558, GBP_LV},
+ {0xD559, 0xD573, GBP_LVT},
+ {0xD574, 0xD574, GBP_LV},
+ {0xD575, 0xD58F, GBP_LVT},
+ {0xD590, 0xD590, GBP_LV},
+ {0xD591, 0xD5AB, GBP_LVT},
+ {0xD5AC, 0xD5AC, GBP_LV},
+ {0xD5AD, 0xD5C7, GBP_LVT},
+ {0xD5C8, 0xD5C8, GBP_LV},
+ {0xD5C9, 0xD5E3, GBP_LVT},
+ {0xD5E4, 0xD5E4, GBP_LV},
+ {0xD5E5, 0xD5FF, GBP_LVT},
+ {0xD600, 0xD600, GBP_LV},
+ {0xD601, 0xD61B, GBP_LVT},
+ {0xD61C, 0xD61C, GBP_LV},
+ {0xD61D, 0xD637, GBP_LVT},
+ {0xD638, 0xD638, GBP_LV},
+ {0xD639, 0xD653, GBP_LVT},
+ {0xD654, 0xD654, GBP_LV},
+ {0xD655, 0xD66F, GBP_LVT},
+ {0xD670, 0xD670, GBP_LV},
+ {0xD671, 0xD68B, GBP_LVT},
+ {0xD68C, 0xD68C, GBP_LV},
+ {0xD68D, 0xD6A7, GBP_LVT},
+ {0xD6A8, 0xD6A8, GBP_LV},
+ {0xD6A9, 0xD6C3, GBP_LVT},
+ {0xD6C4, 0xD6C4, GBP_LV},
+ {0xD6C5, 0xD6DF, GBP_LVT},
+ {0xD6E0, 0xD6E0, GBP_LV},
+ {0xD6E1, 0xD6FB, GBP_LVT},
+ {0xD6FC, 0xD6FC, GBP_LV},
+ {0xD6FD, 0xD717, GBP_LVT},
+ {0xD718, 0xD718, GBP_LV},
+ {0xD719, 0xD733, GBP_LVT},
+ {0xD734, 0xD734, GBP_LV},
+ {0xD735, 0xD74F, GBP_LVT},
+ {0xD750, 0xD750, GBP_LV},
+ {0xD751, 0xD76B, GBP_LVT},
+ {0xD76C, 0xD76C, GBP_LV},
+ {0xD76D, 0xD787, GBP_LVT},
+ {0xD788, 0xD788, GBP_LV},
+ {0xD789, 0xD7A3, GBP_LVT},
+ {0xD7B0, 0xD7C6, GBP_V},
+ {0xD7CB, 0xD7FB, GBP_T},
+ {0xD800, 0xDFFF, GBP_Control},
+ {0xFB1E, 0xFB1E, GBP_Extend},
+ {0xFE00, 0xFE0F, GBP_Extend},
+ {0xFE20, 0xFE2F, GBP_Extend},
+ {0xFEFF, 0xFEFF, GBP_Control},
+ {0xFF9E, 0xFF9F, GBP_Extend},
+ {0xFFF0, 0xFFF8, GBP_Control},
+ {0xFFF9, 0xFFFB, GBP_Control},
+ {0x101FD, 0x101FD, GBP_Extend},
+ {0x102E0, 0x102E0, GBP_Extend},
+ {0x10376, 0x1037A, GBP_Extend},
+ {0x10A01, 0x10A03, GBP_Extend},
+ {0x10A05, 0x10A06, GBP_Extend},
+ {0x10A0C, 0x10A0F, GBP_Extend},
+ {0x10A38, 0x10A3A, GBP_Extend},
+ {0x10A3F, 0x10A3F, GBP_Extend},
+ {0x10AE5, 0x10AE6, GBP_Extend},
+ {0x11000, 0x11000, GBP_SpacingMark},
+ {0x11001, 0x11001, GBP_Extend},
+ {0x11002, 0x11002, GBP_SpacingMark},
+ {0x11038, 0x11046, GBP_Extend},
+ {0x1107F, 0x11081, GBP_Extend},
+ {0x11082, 0x11082, GBP_SpacingMark},
+ {0x110B0, 0x110B2, GBP_SpacingMark},
+ {0x110B3, 0x110B6, GBP_Extend},
+ {0x110B7, 0x110B8, GBP_SpacingMark},
+ {0x110B9, 0x110BA, GBP_Extend},
+ {0x110BD, 0x110BD, GBP_Prepend},
+ {0x11100, 0x11102, GBP_Extend},
+ {0x11127, 0x1112B, GBP_Extend},
+ {0x1112C, 0x1112C, GBP_SpacingMark},
+ {0x1112D, 0x11134, GBP_Extend},
+ {0x11173, 0x11173, GBP_Extend},
+ {0x11180, 0x11181, GBP_Extend},
+ {0x11182, 0x11182, GBP_SpacingMark},
+ {0x111B3, 0x111B5, GBP_SpacingMark},
+ {0x111B6, 0x111BE, GBP_Extend},
+ {0x111BF, 0x111C0, GBP_SpacingMark},
+ {0x111C2, 0x111C3, GBP_Prepend},
+ {0x111CA, 0x111CC, GBP_Extend},
+ {0x1122C, 0x1122E, GBP_SpacingMark},
+ {0x1122F, 0x11231, GBP_Extend},
+ {0x11232, 0x11233, GBP_SpacingMark},
+ {0x11234, 0x11234, GBP_Extend},
+ {0x11235, 0x11235, GBP_SpacingMark},
+ {0x11236, 0x11237, GBP_Extend},
+ {0x1123E, 0x1123E, GBP_Extend},
+ {0x112DF, 0x112DF, GBP_Extend},
+ {0x112E0, 0x112E2, GBP_SpacingMark},
+ {0x112E3, 0x112EA, GBP_Extend},
+ {0x11300, 0x11301, GBP_Extend},
+ {0x11302, 0x11303, GBP_SpacingMark},
+ {0x1133C, 0x1133C, GBP_Extend},
+ {0x1133E, 0x1133E, GBP_Extend},
+ {0x1133F, 0x1133F, GBP_SpacingMark},
+ {0x11340, 0x11340, GBP_Extend},
+ {0x11341, 0x11344, GBP_SpacingMark},
+ {0x11347, 0x11348, GBP_SpacingMark},
+ {0x1134B, 0x1134D, GBP_SpacingMark},
+ {0x11357, 0x11357, GBP_Extend},
+ {0x11362, 0x11363, GBP_SpacingMark},
+ {0x11366, 0x1136C, GBP_Extend},
+ {0x11370, 0x11374, GBP_Extend},
+ {0x11435, 0x11437, GBP_SpacingMark},
+ {0x11438, 0x1143F, GBP_Extend},
+ {0x11440, 0x11441, GBP_SpacingMark},
+ {0x11442, 0x11444, GBP_Extend},
+ {0x11445, 0x11445, GBP_SpacingMark},
+ {0x11446, 0x11446, GBP_Extend},
+ {0x114B0, 0x114B0, GBP_Extend},
+ {0x114B1, 0x114B2, GBP_SpacingMark},
+ {0x114B3, 0x114B8, GBP_Extend},
+ {0x114B9, 0x114B9, GBP_SpacingMark},
+ {0x114BA, 0x114BA, GBP_Extend},
+ {0x114BB, 0x114BC, GBP_SpacingMark},
+ {0x114BD, 0x114BD, GBP_Extend},
+ {0x114BE, 0x114BE, GBP_SpacingMark},
+ {0x114BF, 0x114C0, GBP_Extend},
+ {0x114C1, 0x114C1, GBP_SpacingMark},
+ {0x114C2, 0x114C3, GBP_Extend},
+ {0x115AF, 0x115AF, GBP_Extend},
+ {0x115B0, 0x115B1, GBP_SpacingMark},
+ {0x115B2, 0x115B5, GBP_Extend},
+ {0x115B8, 0x115BB, GBP_SpacingMark},
+ {0x115BC, 0x115BD, GBP_Extend},
+ {0x115BE, 0x115BE, GBP_SpacingMark},
+ {0x115BF, 0x115C0, GBP_Extend},
+ {0x115DC, 0x115DD, GBP_Extend},
+ {0x11630, 0x11632, GBP_SpacingMark},
+ {0x11633, 0x1163A, GBP_Extend},
+ {0x1163B, 0x1163C, GBP_SpacingMark},
+ {0x1163D, 0x1163D, GBP_Extend},
+ {0x1163E, 0x1163E, GBP_SpacingMark},
+ {0x1163F, 0x11640, GBP_Extend},
+ {0x116AB, 0x116AB, GBP_Extend},
+ {0x116AC, 0x116AC, GBP_SpacingMark},
+ {0x116AD, 0x116AD, GBP_Extend},
+ {0x116AE, 0x116AF, GBP_SpacingMark},
+ {0x116B0, 0x116B5, GBP_Extend},
+ {0x116B6, 0x116B6, GBP_SpacingMark},
+ {0x116B7, 0x116B7, GBP_Extend},
+ {0x1171D, 0x1171F, GBP_Extend},
+ {0x11720, 0x11721, GBP_SpacingMark},
+ {0x11722, 0x11725, GBP_Extend},
+ {0x11726, 0x11726, GBP_SpacingMark},
+ {0x11727, 0x1172B, GBP_Extend},
+ {0x11C2F, 0x11C2F, GBP_SpacingMark},
+ {0x11C30, 0x11C36, GBP_Extend},
+ {0x11C38, 0x11C3D, GBP_Extend},
+ {0x11C3E, 0x11C3E, GBP_SpacingMark},
+ {0x11C3F, 0x11C3F, GBP_Extend},
+ {0x11C92, 0x11CA7, GBP_Extend},
+ {0x11CA9, 0x11CA9, GBP_SpacingMark},
+ {0x11CAA, 0x11CB0, GBP_Extend},
+ {0x11CB1, 0x11CB1, GBP_SpacingMark},
+ {0x11CB2, 0x11CB3, GBP_Extend},
+ {0x11CB4, 0x11CB4, GBP_SpacingMark},
+ {0x11CB5, 0x11CB6, GBP_Extend},
+ {0x16AF0, 0x16AF4, GBP_Extend},
+ {0x16B30, 0x16B36, GBP_Extend},
+ {0x16F51, 0x16F7E, GBP_SpacingMark},
+ {0x16F8F, 0x16F92, GBP_Extend},
+ {0x1BC9D, 0x1BC9E, GBP_Extend},
+ {0x1BCA0, 0x1BCA3, GBP_Control},
+ {0x1D165, 0x1D165, GBP_Extend},
+ {0x1D166, 0x1D166, GBP_SpacingMark},
+ {0x1D167, 0x1D169, GBP_Extend},
+ {0x1D16D, 0x1D16D, GBP_SpacingMark},
+ {0x1D16E, 0x1D172, GBP_Extend},
+ {0x1D173, 0x1D17A, GBP_Control},
+ {0x1D17B, 0x1D182, GBP_Extend},
+ {0x1D185, 0x1D18B, GBP_Extend},
+ {0x1D1AA, 0x1D1AD, GBP_Extend},
+ {0x1D242, 0x1D244, GBP_Extend},
+ {0x1DA00, 0x1DA36, GBP_Extend},
+ {0x1DA3B, 0x1DA6C, GBP_Extend},
+ {0x1DA75, 0x1DA75, GBP_Extend},
+ {0x1DA84, 0x1DA84, GBP_Extend},
+ {0x1DA9B, 0x1DA9F, GBP_Extend},
+ {0x1DAA1, 0x1DAAF, GBP_Extend},
+ {0x1E000, 0x1E006, GBP_Extend},
+ {0x1E008, 0x1E018, GBP_Extend},
+ {0x1E01B, 0x1E021, GBP_Extend},
+ {0x1E023, 0x1E024, GBP_Extend},
+ {0x1E026, 0x1E02A, GBP_Extend},
+ {0x1E8D0, 0x1E8D6, GBP_Extend},
+ {0x1E944, 0x1E94A, GBP_Extend},
+ {0x1F1E6, 0x1F1FF, GBP_Regional_Indicator},
+ {0x1F385, 0x1F385, GBP_E_Base},
+ {0x1F3C3, 0x1F3C4, GBP_E_Base},
+ {0x1F3CA, 0x1F3CB, GBP_E_Base},
+ {0x1F3FB, 0x1F3FF, GBP_E_Modifier},
+ {0x1F442, 0x1F443, GBP_E_Base},
+ {0x1F446, 0x1F450, GBP_E_Base},
+ {0x1F466, 0x1F469, GBP_E_Base_GAZ},
+ {0x1F46E, 0x1F46E, GBP_E_Base},
+ {0x1F470, 0x1F478, GBP_E_Base},
+ {0x1F47C, 0x1F47C, GBP_E_Base},
+ {0x1F481, 0x1F483, GBP_E_Base},
+ {0x1F485, 0x1F487, GBP_E_Base},
+ {0x1F48B, 0x1F48B, GBP_Glue_After_Zwj},
+ {0x1F4AA, 0x1F4AA, GBP_E_Base},
+ {0x1F575, 0x1F575, GBP_E_Base},
+ {0x1F57A, 0x1F57A, GBP_E_Base},
+ {0x1F590, 0x1F590, GBP_E_Base},
+ {0x1F595, 0x1F596, GBP_E_Base},
+ {0x1F5E8, 0x1F5E8, GBP_Glue_After_Zwj},
+ {0x1F645, 0x1F647, GBP_E_Base},
+ {0x1F64B, 0x1F64F, GBP_E_Base},
+ {0x1F6A3, 0x1F6A3, GBP_E_Base},
+ {0x1F6B4, 0x1F6B6, GBP_E_Base},
+ {0x1F6C0, 0x1F6C0, GBP_E_Base},
+ {0x1F918, 0x1F91E, GBP_E_Base},
+ {0x1F926, 0x1F926, GBP_E_Base},
+ {0x1F930, 0x1F930, GBP_E_Base},
+ {0x1F933, 0x1F939, GBP_E_Base},
+ {0x1F93C, 0x1F93E, GBP_E_Base},
+ {0xE0000, 0xE0000, GBP_Control},
+ {0xE0001, 0xE0001, GBP_Control},
+ {0xE0002, 0xE001F, GBP_Control},
+ {0xE0020, 0xE007F, GBP_Extend},
+ {0xE0080, 0xE00FF, GBP_Control},
+ {0xE0100, 0xE01EF, GBP_Extend},
+ {0xE01F0, 0xE0FFF, GBP_Control},
+ {0xFFFFFFFF, 0xFFFFFFFF, GBP_Undefined}
+};
diff --git a/src/static_libs/libunibreak/graphemebreakdef.h b/src/static_libs/libunibreak/graphemebreakdef.h
new file mode 100644
index 0000000000..0de1f3d623
--- /dev/null
+++ b/src/static_libs/libunibreak/graphemebreakdef.h
@@ -0,0 +1,82 @@
+/*
+ * Grapheme breaking in a Unicode sequence. Designed to be used in a
+ * generic text renderer.
+ *
+ * Copyright (C) 2016 Andreas Röver <roever at users dot sf dot net>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute
+ * it freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must
+ * not claim that you wrote the original software. If you use this
+ * software in a product, an acknowledgement in the product
+ * documentation would be appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must
+ * not be misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ * The main reference is Unicode Standard Annex 29 (UAX #29):
+ * <URL:http://unicode.org/reports/tr29>
+ *
+ * When this library was designed, this annex was at Revision 29, for
+ * Unicode 9.0.0:
+ * <URL:http://www.unicode.org/reports/tr29/tr29-29.html>
+ *
+ * The Unicode Terms of Use are available at
+ * <URL:http://www.unicode.org/copyright.html>
+ */
+
+/**
+ * @file graphemebreakdef.h
+ *
+ * Definitions of internal data structures, declarations of global
+ * variables, and function prototypes for the grapheme breaking algorithm.
+ *
+ * @author Andreas Röver
+ */
+
+#include "unibreakdef.h"
+
+/**
+ * Word break classes. This is a direct mapping of Table 2 of Unicode
+ * Standard Annex 29
+ */
+enum GraphemeBreakClass
+{
+ GBP_CR,
+ GBP_LF,
+ GBP_Control,
+ GBP_Extend,
+ GBP_ZWJ,
+ GBP_Regional_Indicator,
+ GBP_Prepend,
+ GBP_SpacingMark,
+ GBP_L,
+ GBP_V,
+ GBP_T,
+ GBP_LV,
+ GBP_LVT,
+ GBP_E_Base,
+ GBP_E_Modifier,
+ GBP_Glue_After_Zwj,
+ GBP_E_Base_GAZ,
+ GBP_Other,
+ GBP_Undefined
+};
+
+/**
+ * Struct for entries of grapheme break properties. The array of the
+ * entries \e must be sorted.
+ */
+struct GraphemeBreakProperties
+{
+ utf32_t start; /**< Starting coding point */
+ utf32_t end; /**< End coding point, including */
+ enum GraphemeBreakClass prop; /**< The grapheme breaking property */
+};
diff --git a/src/static_libs/libunibreak/linebreak.c b/src/static_libs/libunibreak/linebreak.c
index 3d87a0413d..41f23c1c08 100644
--- a/src/static_libs/libunibreak/linebreak.c
+++ b/src/static_libs/libunibreak/linebreak.c
@@ -45,7 +45,6 @@
* Implementation of the line breaking algorithm as described in Unicode
* Standard Annex 14.
*
- * @version 3.2, 2016/12/04
* @author Wu Yongwei
* @author Petr Filipsky
*/
@@ -68,7 +67,7 @@
/**
* Enumeration of break actions. They are used in the break action
- * pair table below.
+ * pair table #baTable.
*/
enum BreakAction
{
@@ -81,7 +80,7 @@ enum BreakAction
/**
* Break action pair table. This is a direct mapping of Table 2 of
- * Unicode Standard Annex 14, Revision 37.
+ * Unicode Standard Annex 14, Revision 37, except the "CB" part.
*/
static enum BreakAction baTable[LBP_CB][LBP_CB] = {
{ /* OP */
@@ -313,11 +312,12 @@ static struct LineBreakPropertiesIndex lb_prop_index[LINEBREAK_INDEX_SIZE] =
static __inline int ends_with(const char *str, const char *suffix,
unsigned suffixLen)
{
+ unsigned len;
if (str == NULL)
{
return 0;
}
- unsigned len = strlen(str);
+ len = strlen(str);
if (len >= suffixLen &&
memcmp(str + len - suffixLen, suffix, suffixLen) == 0)
{
@@ -706,6 +706,23 @@ int lb_process_next_char(
/**
* Sets the line breaking information for a generic input string.
*
+ * Currently, this implementation has customization for the following
+ * ISO 639-1 language codes (for \a lang):
+ *
+ * - de (German)
+ * - en (English)
+ * - es (Spanish)
+ * - fr (French)
+ * - ja (Japanese)
+ * - ko (Korean)
+ * - ru (Russian)
+ * - zh (Chinese)
+ *
+ * In addition, a suffix <code>"-strict"</code> may be added to indicate
+ * strict (as versus normal) line-breaking behaviour. See the <a
+ * href="http://www.unicode.org/reports/tr14/#CJ">Conditional Japanese
+ * Starter section of UAX #14</a> for more details.
+ *
* @param[in] s input string
* @param[in] len length of the input
* @param[in] lang language of the input
@@ -766,6 +783,7 @@ void set_linebreaks(
* @param[out] brks pointer to the output breaking data, containing
* #LINEBREAK_MUSTBREAK, #LINEBREAK_ALLOWBREAK,
* #LINEBREAK_NOBREAK, or #LINEBREAK_INSIDEACHAR
+ * @see #set_linebreaks for a note about \a lang.
*/
void set_linebreaks_utf8(
const utf8_t *s,
@@ -786,6 +804,7 @@ void set_linebreaks_utf8(
* @param[out] brks pointer to the output breaking data, containing
* #LINEBREAK_MUSTBREAK, #LINEBREAK_ALLOWBREAK,
* #LINEBREAK_NOBREAK, or #LINEBREAK_INSIDEACHAR
+ * @see #set_linebreaks for a note about \a lang.
*/
void set_linebreaks_utf16(
const utf16_t *s,
@@ -806,6 +825,7 @@ void set_linebreaks_utf16(
* @param[out] brks pointer to the output breaking data, containing
* #LINEBREAK_MUSTBREAK, #LINEBREAK_ALLOWBREAK,
* #LINEBREAK_NOBREAK, or #LINEBREAK_INSIDEACHAR
+ * @see #set_linebreaks for a note about \a lang.
*/
void set_linebreaks_utf32(
const utf32_t *s,
diff --git a/src/static_libs/libunibreak/linebreak.h b/src/static_libs/libunibreak/linebreak.h
index 7753b3d83b..fd7351191b 100644
--- a/src/static_libs/libunibreak/linebreak.h
+++ b/src/static_libs/libunibreak/linebreak.h
@@ -43,7 +43,6 @@
*
* Header file for the line breaking algorithm.
*
- * @version 3.1, 2016/09/10
* @author Wu Yongwei
*/
diff --git a/src/static_libs/libunibreak/linebreakdef.c b/src/static_libs/libunibreak/linebreakdef.c
index 04c3db3487..6b485cecbd 100644
--- a/src/static_libs/libunibreak/linebreakdef.c
+++ b/src/static_libs/libunibreak/linebreakdef.c
@@ -43,7 +43,6 @@
*
* Definition of language-specific data.
*
- * @version 3.1, 2016/09/10
* @author Wu Yongwei
*/
diff --git a/src/static_libs/libunibreak/linebreakdef.h b/src/static_libs/libunibreak/linebreakdef.h
index 9432ed3326..37ec7b546e 100644
--- a/src/static_libs/libunibreak/linebreakdef.h
+++ b/src/static_libs/libunibreak/linebreakdef.h
@@ -45,7 +45,6 @@
* Definitions of internal data structures, declarations of global
* variables, and function prototypes for the line breaking algorithm.
*
- * @version 3.2, 2016/12/03
* @author Wu Yongwei
* @author Petr Filipsky
*/
diff --git a/src/static_libs/libunibreak/unibreakbase.c b/src/static_libs/libunibreak/unibreakbase.c
index b0d8f3b729..686852a990 100644
--- a/src/static_libs/libunibreak/unibreakbase.c
+++ b/src/static_libs/libunibreak/unibreakbase.c
@@ -4,7 +4,7 @@
* Break processing in a Unicode sequence. Designed to be used in a
* generic text renderer.
*
- * Copyright (C) 2015 Wu Yongwei <wuyongwei at gmail dot com>
+ * Copyright (C) 2015-2016 Wu Yongwei <wuyongwei at gmail dot com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
@@ -29,7 +29,6 @@
*
* Definition of basic libunibreak information.
*
- * @version 3.0, 2015/05/10
* @author Wu Yongwei
*/
diff --git a/src/static_libs/libunibreak/unibreakbase.h b/src/static_libs/libunibreak/unibreakbase.h
index 08c012737c..ff9a6ce8a9 100644
--- a/src/static_libs/libunibreak/unibreakbase.h
+++ b/src/static_libs/libunibreak/unibreakbase.h
@@ -4,7 +4,7 @@
* Break processing in a Unicode sequence. Designed to be used in a
* generic text renderer.
*
- * Copyright (C) 2015 Wu Yongwei <wuyongwei at gmail dot com>
+ * Copyright (C) 2015-2016 Wu Yongwei <wuyongwei at gmail dot com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
@@ -29,7 +29,6 @@
*
* Header file for common definitions in the libunibreak library.
*
- * @version 3.0, 2015/05/10
* @author Wu Yongwei
*/
@@ -40,7 +39,7 @@
extern "C" {
#endif
-#define UNIBREAK_VERSION 0x0300 /**< Version of the library linebreak */
+#define UNIBREAK_VERSION 0x0400 /**< Version of the library linebreak */
extern const int unibreak_version;
#ifndef UNIBREAK_UTF_TYPES_DEFINED
diff --git a/src/static_libs/libunibreak/unibreakdef.c b/src/static_libs/libunibreak/unibreakdef.c
index 20ce2b3484..4d4f2b2863 100644
--- a/src/static_libs/libunibreak/unibreakdef.c
+++ b/src/static_libs/libunibreak/unibreakdef.c
@@ -4,7 +4,7 @@
* Break processing in a Unicode sequence. Designed to be used in a
* generic text renderer.
*
- * Copyright (C) 2015 Wu Yongwei <wuyongwei at gmail dot com>
+ * Copyright (C) 2015-2016 Wu Yongwei <wuyongwei at gmail dot com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
@@ -29,7 +29,6 @@
*
* Definition of utility functions used by the libunibreak library.
*
- * @version 3.0, 2015/05/10
* @author Wu Yongwei
*/
diff --git a/src/static_libs/libunibreak/unibreakdef.h b/src/static_libs/libunibreak/unibreakdef.h
index f5d5744990..e13016d8cd 100644
--- a/src/static_libs/libunibreak/unibreakdef.h
+++ b/src/static_libs/libunibreak/unibreakdef.h
@@ -4,7 +4,7 @@
* Break processing in a Unicode sequence. Designed to be used in a
* generic text renderer.
*
- * Copyright (C) 2015 Wu Yongwei <wuyongwei at gmail dot com>
+ * Copyright (C) 2015-2016 Wu Yongwei <wuyongwei at gmail dot com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
@@ -29,7 +29,6 @@
*
* Header file for private definitions in the libunibreak library.
*
- * @version 3.0, 2015/05/10
* @author Wu Yongwei
*/
diff --git a/src/static_libs/libunibreak/wordbreak.c b/src/static_libs/libunibreak/wordbreak.c
index d90d77b799..aece4b3c45 100644
--- a/src/static_libs/libunibreak/wordbreak.c
+++ b/src/static_libs/libunibreak/wordbreak.c
@@ -4,7 +4,7 @@
* Word breaking in a Unicode sequence. Designed to be used in a
* generic text renderer.
*
- * Copyright (C) 2013-2015 Tom Hacohen <tom at stosb dot com>
+ * Copyright (C) 2013-2016 Tom Hacohen <tom at stosb dot com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
@@ -30,9 +30,9 @@
* Unicode 6.0.0:
* <URL:http://www.unicode.org/reports/tr29/tr29-17.html>
*
- * This library has been updated according to Revision 27, for
- * Unicode 8.0.0:
- * <URL:http://www.unicode.org/reports/tr29/tr29-27.html>
+ * This library has been updated according to Revision 29, for
+ * Unicode 9.0.0:
+ * <URL:http://www.unicode.org/reports/tr29/tr29-29.html>
*
* The Unicode Terms of Use are available at
* <URL:http://www.unicode.org/copyright.html>
@@ -44,7 +44,6 @@
* Implementation of the word breaking algorithm as described in Unicode
* Standard Annex 29.
*
- * @version 3.1, 2015/05/18
* @author Tom Hacohen
*/
@@ -149,7 +148,7 @@ static void set_brks_to(
*
* @param[in] s input string
* @param[in] len length of the input
- * @param[in] lang language of the input
+ * @param[in] lang language of the input (reserved for future use)
* @param[out] brks pointer to the output breaking data, containing
* #WORDBREAK_BREAK, #WORDBREAK_NOBREAK, or
* #WORDBREAK_INSIDEACHAR
@@ -210,13 +209,7 @@ static void set_wordbreaks(
posLast = posCur;
break;
}
-#ifndef __has_attribute
-# define __has_attribute(x) 0
-#endif
-#if __has_attribute(fallthrough)
- __attribute__((fallthrough));
-#endif
- /* Fall off */
+ /* Fall off */
case WBP_Newline:
/* WB3a,3b */
@@ -329,13 +322,7 @@ static void set_wordbreaks(
wbcSeqStart = wbcCur;
posLast = posCur;
}
-#ifndef __has_attribute
-# define __has_attribute(x) 0
-#endif
-#if __has_attribute(fallthrough)
- __attribute__((fallthrough));
-#endif
- /* No break on purpose */
+ /* No break on purpose */
case WBP_MidNumLet:
if (((wbcLast == WBP_ALetter) ||
(wbcLast == WBP_Hebrew_Letter)) || /* WB6,7 */
@@ -511,7 +498,7 @@ static void set_wordbreaks(
*
* @param[in] s input UTF-8 string
* @param[in] len length of the input
- * @param[in] lang language of the input
+ * @param[in] lang language of the input (reserved for future use)
* @param[out] brks pointer to the output breaking data, containing
* #WORDBREAK_BREAK, #WORDBREAK_NOBREAK, or
* #WORDBREAK_INSIDEACHAR
@@ -531,7 +518,7 @@ void set_wordbreaks_utf8(
*
* @param[in] s input UTF-16 string
* @param[in] len length of the input
- * @param[in] lang language of the input
+ * @param[in] lang language of the input (reserved for future use)
* @param[out] brks pointer to the output breaking data, containing
* #WORDBREAK_BREAK, #WORDBREAK_NOBREAK, or
* #WORDBREAK_INSIDEACHAR
@@ -551,7 +538,7 @@ void set_wordbreaks_utf16(
*
* @param[in] s input UTF-32 string
* @param[in] len length of the input
- * @param[in] lang language of the input
+ * @param[in] lang language of the input (reserved for future use)
* @param[out] brks pointer to the output breaking data, containing
* #WORDBREAK_BREAK, #WORDBREAK_NOBREAK, or
* #WORDBREAK_INSIDEACHAR
diff --git a/src/static_libs/libunibreak/wordbreak.h b/src/static_libs/libunibreak/wordbreak.h
index b9124d7b52..1040c13280 100644
--- a/src/static_libs/libunibreak/wordbreak.h
+++ b/src/static_libs/libunibreak/wordbreak.h
@@ -4,7 +4,7 @@
* Word breaking in a Unicode sequence. Designed to be used in a
* generic text renderer.
*
- * Copyright (C) 2013-2015 Tom Hacohen <tom at stosb dot com>
+ * Copyright (C) 2013-2016 Tom Hacohen <tom at stosb dot com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
@@ -30,9 +30,9 @@
* Unicode 6.0.0:
* <URL:http://www.unicode.org/reports/tr29/tr29-17.html>
*
- * This library has been updated according to Revision 25, for
- * Unicode 7.0.0:
- * <URL:http://www.unicode.org/reports/tr29/tr29-25.html>
+ * This library has been updated according to Revision 29, for
+ * Unicode 9.0.0:
+ * <URL:http://www.unicode.org/reports/tr29/tr29-29.html>
*
* The Unicode Terms of Use are available at
* <URL:http://www.unicode.org/copyright.html>
@@ -43,7 +43,6 @@
*
* Header file for the word breaking (segmentation) algorithm.
*
- * @version 3.0, 2015/05/10
* @author Tom Hacohen
*/
diff --git a/src/static_libs/libunibreak/wordbreakdef.h b/src/static_libs/libunibreak/wordbreakdef.h
index b00aff33e9..82cd98e7c3 100644
--- a/src/static_libs/libunibreak/wordbreakdef.h
+++ b/src/static_libs/libunibreak/wordbreakdef.h
@@ -4,7 +4,7 @@
* Word breaking in a Unicode sequence. Designed to be used in a
* generic text renderer.
*
- * Copyright (C) 2013-15 Tom Hacohen <tom at stosb dot com>
+ * Copyright (C) 2013-16 Tom Hacohen <tom at stosb dot com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
@@ -30,9 +30,9 @@
* Unicode 6.0.0:
* <URL:http://www.unicode.org/reports/tr29/tr29-17.html>
*
- * This library has been updated according to Revision 25, for
- * Unicode 7.0.0:
- * <URL:http://www.unicode.org/reports/tr29/tr29-25.html>
+ * This library has been updated according to Revision 29, for
+ * Unicode 9.0.0:
+ * <URL:http://www.unicode.org/reports/tr29/tr29-29.html>
*
* The Unicode Terms of Use are available at
* <URL:http://www.unicode.org/copyright.html>
@@ -44,7 +44,6 @@
* Definitions of internal data structures, declarations of global
* variables, and function prototypes for the word breaking algorithm.
*
- * @version 3.0, 2015/05/10
* @author Tom Hacohen
*/
diff --git a/src/tests/evas/evas_test_textblock.c b/src/tests/evas/evas_test_textblock.c
index 1f6cb139b2..49f7577374 100644
--- a/src/tests/evas/evas_test_textblock.c
+++ b/src/tests/evas/evas_test_textblock.c
@@ -105,8 +105,9 @@ while (0)
EFL_START_TEST(evas_textblock_cursor)
{
START_TB_TEST();
+ Evas_Textblock_Cursor *cur2;
Evas_Coord x, y, w, h;
- size_t i, len;
+ size_t i, j, len;
Evas_Coord nw, nh;
Evas_BiDi_Direction dir;
const char *buf = "This is a<br/> test.<ps/>Lets see if this works.<ps/>עוד פסקה.";
@@ -973,6 +974,27 @@ EFL_START_TEST(evas_textblock_cursor)
}
evas_textblock_cursor_free(cur2);
}
+
+ /* Testing for grapheme cluster */
+ cur2 = evas_object_textblock_cursor_new(tb);
+ evas_object_textblock_text_markup_set(tb, "ഹലോ");
+ evas_textblock_cursor_pos_set(cur, 0);
+ evas_textblock_cursor_pos_set(cur2, 0);
+
+ i = j = 0;
+ while (evas_textblock_cursor_cluster_next(cur)) i++;
+ ck_assert_int_eq(i, 2);
+
+ while (evas_textblock_cursor_char_next(cur2)) j++;
+ ck_assert_int_eq(j, 4);
+
+ i = j = 0;
+ while (evas_textblock_cursor_cluster_prev(cur)) i++;
+ ck_assert_int_eq(i, 2);
+
+ while (evas_textblock_cursor_char_prev(cur2)) j++;
+ ck_assert_int_eq(j, 4);
+
END_TB_TEST();
}
EFL_END_TEST