Пример #1
0
static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
			  int subline, int ypos, int max)
{
        INDENT_FUNC indent_func;
	LINE_CACHE_REC *cache;
        const unsigned char *text, *end, *text_newline;
	unsigned char *tmp;
	int xpos, color, drawcount, first, need_move, need_clrtoeol, char_width;

	if (view->dirty) /* don't bother drawing anything - redraw is coming */
                return 0;

	cache = textbuffer_view_get_line_cache(view, line);
	if (subline >= cache->count)
                return 0;

        color = ATTR_RESET;
        need_move = TRUE; need_clrtoeol = FALSE;
	xpos = drawcount = 0; first = TRUE;
	text_newline = text =
		subline == 0 ? line->text : cache->lines[subline-1].start;
	for (;;) {
		if (text == text_newline) {
			if (need_clrtoeol && xpos < term_width) {
				term_set_color(view->window, ATTR_RESET);
				term_clrtoeol(view->window);
			}

			if (first)
				first = FALSE;
			else {
				ypos++;
                                if (--max == 0)
					break;
			}

			if (subline > 0) {
                                /* continuing previous line - indent it */
				indent_func = cache->lines[subline-1].indent_func;
				if (indent_func == NULL)
					xpos = cache->lines[subline-1].indent;
                                color = cache->lines[subline-1].color;
			} else {
				indent_func = NULL;
			}

			if (xpos == 0 && indent_func == NULL)
                                need_clrtoeol = TRUE;
			else {
				/* line was indented - need to clear the
                                   indented area first */
				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)
				term_move(view->window, xpos, ypos);

			term_set_color(view->window, color);

			if (subline == cache->count-1) {
				text_newline = NULL;
				need_move = FALSE;
			} else {
				/* get the beginning of the next subline */
				text_newline = cache->lines[subline].start;
				need_move = !cache->lines[subline].continues;
			}
                        drawcount++;
			subline++;
		}

		if (*text == '\0') {
			/* command */
			text++;
			if (*text == LINE_CMD_EOL || *text == LINE_CMD_FORMAT)
                                break;

			if (*text == LINE_CMD_CONTINUE) {
                                /* jump to next block */
				memcpy(&tmp, text+1, sizeof(unsigned char *));
				text = tmp;
				continue;
			} else if (*text == LINE_CMD_INDENT_FUNC) {
				text += sizeof(INDENT_FUNC);
			} else {
				update_cmd_color(*text, &color);
				term_set_color(view->window, color);
			}
			text++;
			continue;
		}

		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++)
					term_addch(view->window, *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);
				term_set_color(view->window, color);
			}
		}
		text++;
	}

	if (need_clrtoeol && xpos < term_width) {
		term_set_color(view->window, ATTR_RESET);
		term_clrtoeol(view->window);
	}

        return drawcount;
}
Пример #2
0
static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
			  int subline, int ypos, int max)
{
        INDENT_FUNC indent_func;
	LINE_CACHE_REC *cache;
        const unsigned char *text, *end, *text_newline;
	unsigned char *tmp;
	unichar chr;
	int xpos, color, fg24, bg24, drawcount, first, need_move, need_clrtoeol, char_width;

	if (view->dirty) /* don't bother drawing anything - redraw is coming */
                return 0;

	cache = textbuffer_view_get_line_cache(view, line);
	if (subline >= cache->count)
                return 0;

        color = ATTR_RESET;
        need_move = TRUE; need_clrtoeol = FALSE;
	xpos = drawcount = 0; first = TRUE;
	text_newline = text =
		subline == 0 ? line->text : cache->lines[subline-1].start;
	for (;;) {
		if (text == text_newline) {
			if (need_clrtoeol && xpos < term_width) {
				term_set_color(view->window, ATTR_RESET);
				term_clrtoeol(view->window);
			}

			if (first)
				first = FALSE;
			else {
				ypos++;
                                if (--max == 0)
					break;
			}

			if (subline > 0) {
                                /* continuing previous line - indent it */
				indent_func = cache->lines[subline-1].indent_func;
				if (indent_func == NULL)
					xpos = cache->lines[subline-1].indent;
                                color = cache->lines[subline-1].color;
#ifdef TERM_TRUECOLOR
                                fg24 = cache->lines[subline-1].fg24;
                                bg24 = cache->lines[subline-1].bg24;
#endif
			} else {
				indent_func = NULL;
			}

			if (xpos == 0 && indent_func == NULL)
                                need_clrtoeol = TRUE;
			else {
				/* line was indented - need to clear the
                                   indented area first */
				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)
				term_move(view->window, xpos, ypos);

			term_set_color2(view->window, color, fg24, bg24);

			if (subline == cache->count-1) {
				text_newline = NULL;
				need_move = FALSE;
			} else {
				/* get the beginning of the next subline */
				text_newline = cache->lines[subline].start;
				need_move = !cache->lines[subline].continues;
			}
                        drawcount++;
			subline++;
		}

		if (*text == '\0') {
			/* command */
			text++;
			if (*text == LINE_CMD_EOL)
                                break;

			if (*text == LINE_CMD_CONTINUE) {
                                /* jump to next block */
				memcpy(&tmp, text+1, sizeof(unsigned char *));
				text = tmp;
				continue;
			} else {
				if (*text == LINE_COLOR_EXT)
					color = (color & BGATTR & ~ATTR_FGCOLOR24) | *++text;
				else if (*text == LINE_COLOR_EXT_BG)
					color = (color & FGATTR & ~ATTR_BGCOLOR24) | (*++text << BG_SHIFT);
#ifdef TERM_TRUECOLOR
				else if (*text == LINE_COLOR_24)
					unformat_24bit_line_color(&text, 1, &color, &fg24, &bg24);
#endif
				else
					update_cmd_color(*text, &color);
				term_set_color2(view->window, color, fg24, bg24);
			}
			text++;
			continue;
		}

		if (view->utf8) {
			chr = read_unichar(text, &end, &char_width);
		} else {
			chr = *text;
			end = text;
			if (term_type == TERM_TYPE_BIG5 &&
			    is_big5(end[0], end[1]))
				char_width = 2;
			else
				char_width = 1;
			end += char_width;
		}

		xpos += char_width;
		if (xpos <= term_width) {
			if (unichar_isprint(chr)) {
				if (view->utf8)
				term_add_unichar(view->window, chr);
				else
				for (; text < end; text++)
					term_addch(view->window, *text);
			} else {
				/* low-ascii */
				term_set_color(view->window, ATTR_RESET|ATTR_REVERSE);
				term_addch(view->window, (chr & 127)+'A'-1);
				term_set_color2(view->window, color, fg24, bg24);
			}
		}
		text = end;
	}

	if (need_clrtoeol && xpos < term_width) {
		term_set_color(view->window, ATTR_RESET);
		term_clrtoeol(view->window);
	}

        return drawcount;
}