mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Preliminary support for UTF8 with /SET term_utf8 ON. Input line is still
messed up, but lines should wrap properly in text buffer. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2354 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
0cdc8a7f6a
commit
46b318b831
@ -61,6 +61,7 @@ irssi_SOURCES = \
|
||||
textbuffer-commands.c \
|
||||
textbuffer-reformat.c \
|
||||
textbuffer-view.c \
|
||||
utf8.c \
|
||||
irssi.c \
|
||||
module-formats.c
|
||||
|
||||
@ -77,6 +78,7 @@ noinst_HEADERS = \
|
||||
textbuffer.h \
|
||||
textbuffer-view.h \
|
||||
textbuffer-reformat.h \
|
||||
utf8.h \
|
||||
module.h \
|
||||
module-formats.h
|
||||
|
||||
|
@ -43,7 +43,8 @@ static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window,
|
||||
gui->parent = parent;
|
||||
gui->view = textbuffer_view_create(textbuffer_create(),
|
||||
window->width, window->height,
|
||||
settings_get_bool("scroll"));
|
||||
settings_get_bool("scroll"),
|
||||
settings_get_bool("term_utf8"));
|
||||
textbuffer_view_set_default_indent(gui->view,
|
||||
settings_get_int("indent"),
|
||||
!settings_get_bool("indent_always"),
|
||||
|
@ -115,6 +115,7 @@ void term_common_init(void)
|
||||
settings_add_bool("lookandfeel", "colors", TRUE);
|
||||
settings_add_bool("lookandfeel", "term_force_colors", FALSE);
|
||||
settings_add_bool("lookandfeel", "term_auto_detach", FALSE);
|
||||
settings_add_bool("lookandfeel", "term_utf8", FALSE);
|
||||
|
||||
force_colors = FALSE;
|
||||
term_use_colors = term_has_colors() && settings_get_bool("colors");
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "module.h"
|
||||
#include "textbuffer-view.h"
|
||||
#include "utf8.h"
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
@ -149,7 +150,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
LINE_CACHE_SUB_REC *sub;
|
||||
GSList *lines;
|
||||
unsigned char cmd;
|
||||
char *ptr, *last_space_ptr;
|
||||
const unsigned char *ptr, *last_space_ptr;
|
||||
int xpos, pos, indent_pos, last_space, last_color, color, linecount;
|
||||
|
||||
g_return_val_if_fail(line->text != NULL, NULL);
|
||||
@ -229,6 +230,9 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (view->utf8)
|
||||
get_utf8_char(&ptr);
|
||||
|
||||
xpos++;
|
||||
if (*ptr++ == ' ') {
|
||||
last_space = xpos-1;
|
||||
@ -392,9 +396,19 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
}
|
||||
|
||||
if (xpos < term_width) {
|
||||
if ((*text & 127) >= 32)
|
||||
if ((*text & 127) >= 32) {
|
||||
if (view->utf8) {
|
||||
/* UTF8 - print multiple chars */
|
||||
const unsigned char *end = text;
|
||||
|
||||
get_utf8_char(&end);
|
||||
while (text < end) {
|
||||
term_addch(view->window, *text);
|
||||
else {
|
||||
text++;
|
||||
}
|
||||
}
|
||||
term_addch(view->window, *text);
|
||||
} else {
|
||||
/* low-ascii */
|
||||
term_set_color(view->window, ATTR_RESET|ATTR_REVERSE);
|
||||
term_addch(view->window, (*text & 127)+'A'-1);
|
||||
@ -468,7 +482,7 @@ static void textbuffer_view_init_ypos(TEXT_BUFFER_VIEW_REC *view)
|
||||
/* Create new view. */
|
||||
TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer,
|
||||
int width, int height,
|
||||
int scroll)
|
||||
int scroll, int utf8)
|
||||
{
|
||||
TEXT_BUFFER_VIEW_REC *view;
|
||||
|
||||
@ -482,6 +496,7 @@ TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer,
|
||||
view->width = width;
|
||||
view->height = height;
|
||||
view->scroll = scroll;
|
||||
view->utf8 = utf8;
|
||||
|
||||
view->cache = textbuffer_cache_get(view->siblings, width);
|
||||
textbuffer_view_init_bottom(view);
|
||||
@ -597,6 +612,11 @@ void textbuffer_view_set_scroll(TEXT_BUFFER_VIEW_REC *view, int scroll)
|
||||
view->scroll = scroll;
|
||||
}
|
||||
|
||||
void textbuffer_view_set_utf8(TEXT_BUFFER_VIEW_REC *view, int utf8)
|
||||
{
|
||||
view->utf8 = utf8;
|
||||
}
|
||||
|
||||
static int view_get_linecount_all(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
{
|
||||
int linecount;
|
||||
|
@ -11,7 +11,7 @@ typedef int (*INDENT_FUNC) (TEXT_BUFFER_VIEW_REC *view,
|
||||
LINE_REC *line, int ypos);
|
||||
|
||||
typedef struct {
|
||||
unsigned char *start;
|
||||
const unsigned char *start;
|
||||
int indent;
|
||||
INDENT_FUNC indent_func;
|
||||
int color;
|
||||
@ -55,6 +55,7 @@ struct _TEXT_BUFFER_VIEW_REC {
|
||||
INDENT_FUNC default_indent_func;
|
||||
unsigned int longword_noindent:1;
|
||||
unsigned int scroll:1; /* scroll down automatically when at bottom */
|
||||
unsigned int utf8:1; /* use UTF8 in this view */
|
||||
|
||||
TEXT_BUFFER_CACHE_REC *cache;
|
||||
int ypos; /* cursor position - visible area is 0..height-1 */
|
||||
@ -84,7 +85,7 @@ struct _TEXT_BUFFER_VIEW_REC {
|
||||
/* Create new view. */
|
||||
TEXT_BUFFER_VIEW_REC *textbuffer_view_create(TEXT_BUFFER_REC *buffer,
|
||||
int width, int height,
|
||||
int scroll);
|
||||
int scroll, int utf8);
|
||||
/* Destroy the view. */
|
||||
void textbuffer_view_destroy(TEXT_BUFFER_VIEW_REC *view);
|
||||
/* Change the default indent position */
|
||||
@ -95,6 +96,7 @@ void textbuffer_view_set_default_indent(TEXT_BUFFER_VIEW_REC *view,
|
||||
void textbuffer_views_unregister_indent_func(INDENT_FUNC indent_func);
|
||||
|
||||
void textbuffer_view_set_scroll(TEXT_BUFFER_VIEW_REC *view, int scroll);
|
||||
void textbuffer_view_set_utf8(TEXT_BUFFER_VIEW_REC *view, int utf8);
|
||||
|
||||
/* Resize the view. */
|
||||
void textbuffer_view_resize(TEXT_BUFFER_VIEW_REC *view, int width, int height);
|
||||
|
64
src/fe-text/utf8.c
Normal file
64
src/fe-text/utf8.c
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
#define UTF8_COMPUTE(Char, Mask, Len) \
|
||||
if (Char < 128) \
|
||||
{ \
|
||||
Len = 1; \
|
||||
Mask = 0x7f; \
|
||||
} \
|
||||
else if ((Char & 0xe0) == 0xc0) \
|
||||
{ \
|
||||
Len = 2; \
|
||||
Mask = 0x1f; \
|
||||
} \
|
||||
else if ((Char & 0xf0) == 0xe0) \
|
||||
{ \
|
||||
Len = 3; \
|
||||
Mask = 0x0f; \
|
||||
} \
|
||||
else if ((Char & 0xf8) == 0xf0) \
|
||||
{ \
|
||||
Len = 4; \
|
||||
Mask = 0x07; \
|
||||
} \
|
||||
else if ((Char & 0xfc) == 0xf8) \
|
||||
{ \
|
||||
Len = 5; \
|
||||
Mask = 0x03; \
|
||||
} \
|
||||
else if ((Char & 0xfe) == 0xfc) \
|
||||
{ \
|
||||
Len = 6; \
|
||||
Mask = 0x01; \
|
||||
} \
|
||||
else \
|
||||
Len = -1;
|
||||
|
||||
#define UTF8_GET(Result, Chars, Count, Mask, Len) \
|
||||
(Result) = (Chars)[0] & (Mask); \
|
||||
for ((Count) = 1; (Count) < (Len); ++(Count)) \
|
||||
{ \
|
||||
if (((Chars)[(Count)] & 0xc0) != 0x80) \
|
||||
{ \
|
||||
(Result) = -1; \
|
||||
break; \
|
||||
} \
|
||||
(Result) <<= 6; \
|
||||
(Result) |= ((Chars)[(Count)] & 0x3f); \
|
||||
}
|
||||
|
||||
void get_utf8_char(const unsigned char **ptr)
|
||||
{
|
||||
int i, mask = 0, len;
|
||||
unsigned int result;
|
||||
unsigned char c = (unsigned char) **ptr;
|
||||
|
||||
UTF8_COMPUTE(c, mask, len);
|
||||
if (len == -1)
|
||||
return;
|
||||
|
||||
UTF8_GET(result, *ptr, i, mask, len);
|
||||
if (result == -1)
|
||||
return;
|
||||
|
||||
*ptr += len-1;
|
||||
}
|
6
src/fe-text/utf8.h
Normal file
6
src/fe-text/utf8.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __UTF8_H
|
||||
#define __UTF8_H
|
||||
|
||||
void get_utf8_char(const unsigned char **ptr);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user