Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define G_LOG_DOMAIN "TextBufferView"
+
#include "module.h"
#include "textbuffer-view.h"
#include "utf8.h"
+#ifdef HAVE_CUIX
+#include "cuix.h"
+#endif
typedef struct {
char *name;
LINE_CACHE_SUB_REC *sub;
GSList *lines;
unsigned char cmd;
- const unsigned char *ptr, *last_space_ptr;
+ const unsigned char *ptr, *next_ptr, *last_space_ptr;
int xpos, pos, indent_pos, last_space, last_color, color, linecount;
+ int char_len;
+ unichar chr;
g_return_val_if_fail(line->text != NULL, NULL);
continue;
}
- if (xpos == view->width && sub != NULL &&
+ if (!view->utf8) {
+ /* MH */
+ if (term_type != TERM_TYPE_BIG5 ||
+ ptr[1] == '\0' || !is_big5(ptr[0], ptr[1]))
+ char_len = 1;
+ else
+ char_len = 2;
+ next_ptr = ptr+char_len;
+ } else {
+ char_len = 1;
+ while (ptr[char_len] != '\0' && char_len < 6)
+ char_len++;
+
+ next_ptr = ptr;
+ if (get_utf8_char(&next_ptr, char_len, &chr) < 0)
+ char_len = 1;
+ else
+ char_len = utf8_width(chr);
+ next_ptr++;
+ }
+
+ if (xpos + char_len > view->width && sub != NULL &&
(last_space <= indent_pos || last_space <= 10) &&
view->longword_noindent) {
/* long word, remove the indentation from this line */
sub->indent = 0;
}
- if (xpos == view->width) {
+ if (xpos + char_len > view->width) {
xpos = indent_func == NULL ? indent_pos :
indent_func(view, line, -1);
continue;
}
- if (view->utf8)
- get_utf8_char(&ptr);
-
- xpos++;
- if (*ptr++ == ' ') {
- last_space = xpos-1;
+ if (!view->utf8 && char_len > 1) {
+ last_space = xpos;
+ last_space_ptr = next_ptr;
+ last_color = color;
+ } else if (*ptr == ' ') {
+ last_space = xpos;
last_space_ptr = ptr;
last_color = color;
}
+
+ xpos += char_len;
+ ptr = next_ptr;
}
rec = g_malloc(sizeof(LINE_CACHE_REC)-sizeof(LINE_CACHE_SUB_REC) +
if (rec->count > 1) {
for (pos = 0; lines != NULL; pos++) {
- memcpy(&rec->lines[pos], lines->data,
+ void *data = lines->data;
+
+ memcpy(&rec->lines[pos], data,
sizeof(LINE_CACHE_SUB_REC));
- g_free(lines->data);
- lines = g_slist_remove(lines, lines->data);
+ lines = g_slist_remove(lines, data);
+ g_free(data);
}
}
{
INDENT_FUNC indent_func;
LINE_CACHE_REC *cache;
- const unsigned char *text, *text_newline;
+ const unsigned char *text, *end, *text_newline;
unsigned char *tmp;
- int xpos, color, drawcount, first, need_move, need_clrtoeol;
+ int xpos, color, drawcount, first, need_move, need_clrtoeol, char_width;
if (view->dirty) /* don't bother drawing anything - redraw is coming */
return 0;
if (subline > 0) {
/* continuing previous line - indent it */
indent_func = cache->lines[subline-1].indent_func;
- xpos = indent_func != NULL ?
- indent_func(view, line, ypos) :
- cache->lines[subline-1].indent;
+ if (indent_func == NULL)
+ xpos = cache->lines[subline-1].indent;
color = cache->lines[subline-1].color;
+ } else {
+ indent_func = NULL;
}
- if (xpos == 0)
+ if (xpos == 0 && indent_func == NULL)
need_clrtoeol = TRUE;
else {
/* line was indented - need to clear the
term_set_color(view->window, ATTR_RESET);
term_move(view->window, 0, ypos);
term_clrtoeol(view->window);
+
+ if (indent_func != NULL)
+ xpos = indent_func(view, line, ypos);
}
if (need_move || xpos > 0)
continue;
}
- if (xpos < term_width) {
- const unsigned char *end = text;
- if (view->utf8)
- get_utf8_char(&end);
+ end = text;
+ if (view->utf8) {
+ unichar chr;
+ if (get_utf8_char(&end, 6, &chr)<0)
+ char_width = 1;
+ else
+ char_width = utf8_width(chr);
+ } else {
+ if (term_type == TERM_TYPE_BIG5 &&
+ is_big5(end[0], end[1]))
+ char_width = 2;
+ else
+ char_width = 1;
+ end += char_width-1;
+ }
+ xpos += char_width;
+ if (xpos <= term_width) {
if (*text >= 32 &&
(end != text || (*text & 127) >= 32)) {
for (; text < end; text++)
}
}
text++;
- xpos++;
}
if (need_clrtoeol && xpos < term_width) {
break;
}
+ if ((*lines)->next == NULL)
+ break;
+
*lines = (*lines)->next;
}
{
LINE_CACHE_REC *cache;
- g_return_val_if_fail(view != NULL, NULL);
- g_return_val_if_fail(line != NULL, NULL);
+ g_assert(view != NULL);
+ g_assert(line != NULL);
cache = g_hash_table_lookup(view->cache->line_cache, line);
if (cache == NULL)
if (new_line != NULL) {
g_hash_table_insert(view->bookmarks,
tmp->data, new_line);
+ } else {
+ g_free(tmp->data);
}
}
g_slist_free(rec.remove_list);
if (view->startline == line) {
/* removing the first line in screen */
+ int is_last = view->startline->next == NULL;
+
realcount = view_scroll(view, &view->startline,
&view->subline,
linecount, FALSE);
view->ypos -= realcount;
view->empty_linecount += linecount-realcount;
+ if (is_last == 1)
+ view->startline = NULL;
}
} else {
if (textbuffer_line_exists_after(view->bottom_startline,
void textbuffer_view_init(void)
{
linecache_tag = g_timeout_add(LINE_CACHE_CHECK_TIME, (GSourceFunc) sig_check_linecache, NULL);
+#ifdef HAVE_CUIX
+ cuix_active = 0;
+#endif
}
void textbuffer_view_deinit(void)