summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2015-09-03 14:43:30 +0200
committerTor Andersson <tor.andersson@artifex.com>2015-10-06 11:21:23 +0200
commite526430ba459b09ed854c462a75e0dbb5ff210d7 (patch)
tree11a22744ac9b0b8114447a116300cd83ce04d7ca /platform
parente982f5c7dd626b5b6051a835dd33c817100f7c2d (diff)
downloadmupdf-e526430ba459b09ed854c462a75e0dbb5ff210d7.tar.xz
gl: Use UTF-8 string internally in text field.
Diffstat (limited to 'platform')
-rw-r--r--platform/gl/gl-app.h4
-rw-r--r--platform/gl/gl-input.c114
-rw-r--r--platform/gl/gl-main.c21
3 files changed, 78 insertions, 61 deletions
diff --git a/platform/gl/gl-app.h b/platform/gl/gl-app.h
index 14dd679c..37b7941a 100644
--- a/platform/gl/gl-app.h
+++ b/platform/gl/gl-app.h
@@ -69,8 +69,8 @@ float ui_measure_string(fz_context *ctx, char *str);
struct input
{
- int text[256];
- int *end, *p, *q;
+ char text[256];
+ char *end, *p, *q;
};
int ui_input(int x0, int y0, int x1, int y1, struct input *input);
diff --git a/platform/gl/gl-input.c b/platform/gl/gl-input.c
index 870db9c7..93f6b897 100644
--- a/platform/gl/gl-input.c
+++ b/platform/gl/gl-input.c
@@ -1,37 +1,49 @@
#include "gl-app.h"
-static void draw_string_part(float x, float y, const int *s, const int *e)
+static void draw_string_part(float x, float y, const char *s, const char *e)
{
+ int c;
ui_begin_text(ctx);
while (s < e)
- x += ui_draw_character(ctx, *s++, x, y + ui.baseline);
+ {
+ s += fz_chartorune(&c, s);
+ x += ui_draw_character(ctx, c, x, y + ui.baseline);
+ }
ui_end_text(ctx);
}
-static float measure_string_part(const int *s, const int *e)
+static float measure_string_part(const char *s, const char *e)
{
+ int c;
float w = 0;
while (s < e)
- w += ui_measure_character(ctx, *s++);
+ {
+ s += fz_chartorune(&c, s);
+ w += ui_measure_character(ctx, c);
+ }
return w;
}
-static int *find_string_location(int *s, int *e, float w, float x)
+static char *find_string_location(char *s, char *e, float w, float x)
{
+ int c;
while (s < e)
{
- float cw = ui_measure_character(ctx, *s);
+ int n = fz_chartorune(&c, s);
+ float cw = ui_measure_character(ctx, c);
if (w + (cw / 2) >= x)
return s;
w += cw;
- ++s;
+ s += n;
}
return e;
}
-static inline int myisalnum(int c)
+static inline int myisalnum(char *s)
{
- int cat = ucdn_get_general_category(c);
+ int cat, c;
+ fz_chartorune(&c, s);
+ cat = ucdn_get_general_category(c);
if (cat >= UCDN_GENERAL_CATEGORY_LL && cat <= UCDN_GENERAL_CATEGORY_LU)
return 1;
if (cat >= UCDN_GENERAL_CATEGORY_ND && cat <= UCDN_GENERAL_CATEGORY_NO)
@@ -39,25 +51,41 @@ static inline int myisalnum(int c)
return 0;
}
-static int *skip_word_left(int *p, int *start)
+static char *prev_char(char *p)
{
- while (p > start && !myisalnum(p[-1])) --p;
- while (p > start && myisalnum(p[-1])) --p;
+ --p;
+ while ((*p & 0xC0) == 0x80) /* skip middle and final multibytes */
+ --p;
return p;
}
-static int *skip_word_right(int *p, int *end)
+static char *next_char(char *p)
{
- while (p < end && !myisalnum(p[0])) ++p;
- while (p < end && myisalnum(p[0])) ++p;
+ ++p;
+ while ((*p & 0xC0) == 0x80) /* skip middle and final multibytes */
+ ++p;
+ return p;
+}
+
+static char *prev_word(char *p, char *start)
+{
+ while (p > start && !myisalnum(prev_char(p))) p = prev_char(p);
+ while (p > start && myisalnum(prev_char(p))) p = prev_char(p);
+ return p;
+}
+
+static char *next_word(char *p, char *end)
+{
+ while (p < end && !myisalnum(p)) p = next_char(p);
+ while (p < end && myisalnum(p)) p = next_char(p);
return p;
}
static void ui_input_delete_selection(struct input *input)
{
- int *p = input->p < input->q ? input->p : input->q;
- int *q = input->p > input->q ? input->p : input->q;
- memmove(p, q, (input->end - q) * sizeof (*p));
+ char *p = input->p < input->q ? input->p : input->q;
+ char *q = input->p > input->q ? input->p : input->q;
+ memmove(p, q, input->end - q);
input->end -= q - p;
input->p = input->q = p;
}
@@ -69,51 +97,51 @@ static int ui_input_key(struct input *input)
case KEY_LEFT:
if (ui.mod == GLFW_MOD_CONTROL + GLFW_MOD_SHIFT)
{
- input->q = skip_word_left(input->q, input->text);
+ input->q = prev_word(input->q, input->text);
}
else if (ui.mod == GLFW_MOD_CONTROL)
{
if (input->p != input->q)
input->p = input->q = input->p < input->q ? input->p : input->q;
else
- input->p = input->q = skip_word_left(input->q, input->text);
+ input->p = input->q = prev_word(input->q, input->text);
}
else if (ui.mod == GLFW_MOD_SHIFT)
{
if (input->q > input->text)
- input->q = --(input->q);
+ input->q = prev_char(input->q);
}
else if (ui.mod == 0)
{
if (input->p != input->q)
input->p = input->q = input->p < input->q ? input->p : input->q;
else if (input->q > input->text)
- input->p = input->q = --(input->q);
+ input->p = input->q = prev_char(input->q);
}
break;
case KEY_RIGHT:
if (ui.mod == GLFW_MOD_CONTROL + GLFW_MOD_SHIFT)
{
- input->q = skip_word_right(input->q, input->end);
+ input->q = next_word(input->q, input->end);
}
else if (ui.mod == GLFW_MOD_CONTROL)
{
if (input->p != input->q)
input->p = input->q = input->p > input->q ? input->p : input->q;
else
- input->p = input->q = skip_word_right(input->q, input->end);
+ input->p = input->q = next_word(input->q, input->end);
}
else if (ui.mod == GLFW_MOD_SHIFT)
{
if (input->q < input->end)
- input->q = ++(input->q);
+ input->q = next_char(input->q);
}
else if (ui.mod == 0)
{
if (input->p != input->q)
input->p = input->q = input->p > input->q ? input->p : input->q;
else if (input->q < input->end)
- input->p = input->q = ++(input->q);
+ input->p = input->q = next_char(input->q);
}
break;
case KEY_UP:
@@ -159,9 +187,11 @@ static int ui_input_key(struct input *input)
ui_input_delete_selection(input);
else if (input->p < input->end)
{
- memmove(input->p, input->p + 1, (input->end - input->p - 1) * sizeof (*input->p));
+ char *np = next_char(input->p);
+ memmove(input->p, np, input->end - np);
+ input->end -= np - input->p;
+ *input->end = 0;
input->q = input->p;
- --(input->end);
}
break;
case KEY_ESCAPE:
@@ -171,11 +201,13 @@ static int ui_input_key(struct input *input)
case KEY_BACKSPACE:
if (input->p != input->q)
ui_input_delete_selection(input);
- else if (input->p > input->text && input->end > input->text)
+ else if (input->p > input->text)
{
- memmove(input->p - 1, input->p, (input->end - input->p) * sizeof (*input->p));
- input->q = --(input->p);
- --(input->end);
+ char *pp = prev_char(input->p);
+ memmove(pp, input->p, input->end - input->p);
+ input->end -= input->p - pp;
+ *input->end = 0;
+ input->q = input->p = pp;
}
break;
case KEY_CTL_A:
@@ -186,10 +218,10 @@ static int ui_input_key(struct input *input)
break;
case KEY_CTL_W:
if (input->p != input->q)
- ui_input_delete_selection(input);
+ ui_input_delete_selection(input);
else
{
- input->p = skip_word_left(input->p, input->text);
+ input->p = prev_word(input->p, input->text);
ui_input_delete_selection(input);
}
break;
@@ -204,11 +236,15 @@ static int ui_input_key(struct input *input)
{
if (input->p != input->q)
ui_input_delete_selection(input);
- if (input->end < input->text + nelem(input->text))
+ if (input->end < input->text + nelem(input->text) - 1)
{
- memmove(input->p + 1, input->p, (input->end - input->p) * sizeof (*input->p));
- ++(input->end);
- *(input->p++) = ui.key;
+ char buf[8];
+ int n = fz_runetochar(buf, ui.key);
+ memmove(input->p + n, input->p, input->end - input->p);
+ memmove(input->p, buf, n);
+ input->p += n;
+ input->end += n;
+ *input->end = 0;
}
input->q = input->p;
}
@@ -221,7 +257,7 @@ static int ui_input_key(struct input *input)
int ui_input(int x0, int y0, int x1, int y1, struct input *input)
{
float px, qx, ex;
- int *p, *q;
+ char *p, *q;
int state;
if (ui.x >= x0 && ui.x < x1 && ui.y >= y0 && ui.y < y1)
diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c
index d85b7df7..8acb0baa 100644
--- a/platform/gl/gl-main.c
+++ b/platform/gl/gl-main.c
@@ -309,25 +309,6 @@ static void pop_future(void)
push_history();
}
-static char *
-utf8_from_rune_string(fz_context *ctx, const int *s, const int *e)
-{
- const int *src = s;
- char *d, *dst;
- int len = 1;
-
- while (src < e)
- len += fz_runelen(*src++);
-
- dst = d = fz_malloc(ctx, len);
- src = s;
- while (src < e)
- dst += fz_runetochar(dst, *src++);
- *dst = 0;
-
- return d;
-}
-
void do_search_page(int number, char *needle, fz_cookie *cookie)
{
fz_page *page = fz_load_page(ctx, doc, number);
@@ -1101,7 +1082,7 @@ static void run_main_loop(void)
}
if (search_input.end > search_input.text)
{
- search_needle = utf8_from_rune_string(ctx, search_input.text, search_input.end);
+ search_needle = fz_strdup(ctx, search_input.text);
search_active = 1;
search_page = currentpage;
}