105 lines
2.7 KiB
Diff
105 lines
2.7 KiB
Diff
From b1f6a30bcce020b3c377434137de9856a09b899a Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Amadeusz=20=C5=BBo=C5=82nowski?= <aidecoe@aidecoe.name>
|
|
Date: Fri, 11 Nov 2011 11:27:43 +0100
|
|
Subject: [PATCH] Make scroll UTF-8 aware. Fixes bug #3134941.
|
|
|
|
---
|
|
src/scroll.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
|
|
1 files changed, 42 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/scroll.c b/src/scroll.c
|
|
index f78f807..738db0d 100644
|
|
--- a/src/scroll.c
|
|
+++ b/src/scroll.c
|
|
@@ -34,12 +34,33 @@
|
|
|
|
struct scroll_data {
|
|
char *text;
|
|
+ unsigned int show_orig;
|
|
unsigned int show;
|
|
unsigned int step;
|
|
unsigned int start;
|
|
long resetcolor;
|
|
};
|
|
|
|
+int utf8_charlen(char c) {
|
|
+ unsigned char uc = (unsigned char) c;
|
|
+ int len = 0;
|
|
+
|
|
+ if ((uc & 0x80) == 0)
|
|
+ return 1;
|
|
+
|
|
+ while ((uc & 0x80) != 0) {
|
|
+ ++len;
|
|
+ uc <<= 1;
|
|
+ }
|
|
+
|
|
+ return (len > 0 && len <= 4) ? len : -1;
|
|
+}
|
|
+
|
|
+int is_utf8_char_tail(char c) {
|
|
+ unsigned char uc = (unsigned char) c;
|
|
+ return (uc & 0xc0) == 0x80;
|
|
+}
|
|
+
|
|
void parse_scroll_arg(struct text_object *obj, const char *arg, void *free_at_crash)
|
|
{
|
|
struct scroll_data *sd;
|
|
@@ -60,15 +81,18 @@ void parse_scroll_arg(struct text_object *obj, const char *arg, void *free_at_cr
|
|
sd->step = 1;
|
|
}
|
|
sd->text = malloc(strlen(arg + n1) + sd->show + 1);
|
|
+ // sd->show value may change when there are UTF-8 chars to be shown, so
|
|
+ // save its origin value
|
|
+ sd->show_orig = sd->show;
|
|
|
|
if (strlen(arg) > sd->show) {
|
|
for(n2 = 0; (unsigned int) n2 < sd->show; n2++) {
|
|
- sd->text[n2] = ' ';
|
|
+ sd->text[n2] = ' ';
|
|
}
|
|
sd->text[n2] = 0;
|
|
}
|
|
else
|
|
- sd->text[0] = 0;
|
|
+ sd->text[0] = 0;
|
|
|
|
strcat(sd->text, arg + n1);
|
|
sd->start = 0;
|
|
@@ -82,9 +106,13 @@ void print_scroll(struct text_object *obj, char *p, int p_max_size, struct infor
|
|
{
|
|
struct scroll_data *sd = obj->data.opaque;
|
|
unsigned int j, colorchanges = 0, frontcolorchanges = 0, visibcolorchanges = 0, strend;
|
|
+ int charlen = 0;
|
|
+ unsigned int utf8lenfix = 0;
|
|
char *pwithcolors;
|
|
char buf[max_user_text];
|
|
|
|
+ sd->show = sd->show_orig;
|
|
+
|
|
if (!sd)
|
|
return;
|
|
|
|
@@ -109,6 +137,18 @@ void print_scroll(struct text_object *obj, char *p, int p_max_size, struct infor
|
|
while(*(buf + sd->start) == SPECIAL_CHAR) {
|
|
sd->start++;
|
|
}
|
|
+ //skip parts of UTF-8 character which messes up display
|
|
+ while(is_utf8_char_tail(*(buf + sd->start))) {
|
|
+ sd->start++;
|
|
+ }
|
|
+ //extend length to be shown for wide characters
|
|
+ j = 0;
|
|
+ while(j < sd->show + visibcolorchanges + utf8lenfix) {
|
|
+ charlen = utf8_charlen(*(buf + sd->start + j));
|
|
+ utf8lenfix += (charlen > 1 ? charlen - 1 : 0);
|
|
+ j += charlen;
|
|
+ }
|
|
+ sd->show = sd->show_orig + utf8lenfix;
|
|
//place all chars that should be visible in p, including colorchanges
|
|
for(j=0; j < sd->show + visibcolorchanges; j++) {
|
|
p[j] = *(buf + sd->start + j);
|
|
--
|
|
1.7.8.rc1
|
|
|