コード例 #1
0
ファイル: editor.c プロジェクト: icewwn/fbbs-1
/**
 * 计算字符串的显示宽度
 * @param str UTF-8编码字符串
 * @param size 字符串的长度
 * @return 字符串在编辑器终端上的显示宽度
 */
static size_t display_width(const char *str, size_t size)
{
	size_t width = 0;
	for (wchar_t wc = next_wchar(&str, &size); wc && wc != WEOF; ) {
		width += display_width_wchar(wc);
		wc = next_wchar(&str, &size);
	}
	return width;
}
コード例 #2
0
ファイル: editor.c プロジェクト: icewwn/fbbs-1
static const char *seek_to_display_width(const char *str, size_t size,
		size_t width)
{
	const char *last = str;
	for (wchar_t wc = next_wchar(&str, &size); wc && wc != WEOF; ) {
		size_t w = display_width_wchar(wc);
		if (w > width) {
			return last;
		} else {
			last = str;
			width -= w;
		}
		wc = next_wchar(&str, &size);
	}
	return last;
}
コード例 #3
0
ファイル: post.c プロジェクト: fbbs/fbbs
static const char *update_quote_width(const char *begin, const char *end,
		bool utf8, size_t *width)
{
	const char *ptr = begin;
	while (ptr < end && *width) {
		if (utf8) {
			size_t left = end - ptr;
			const char *next = ptr;
			wchar_t wc = next_wchar(&next, &left);
			if (!wc || wc == WEOF)
				return ptr;
			int w = fb_wcwidth(wc);
			if (w <= 0)
				w = next - ptr > 0 ? next - ptr : 1;
			if (*width < w)
				return ptr;
			*width -= w;
			ptr = next;
		} else {
			if (*ptr & 0x80) {
				if (*width < 2)
					return ptr;
				*width -= 2;
				ptr += 2;
			} else {
				*width -= 1;
				++ptr;
			}
		}
	}
	return ptr > end ? end : ptr;
}
コード例 #4
0
ファイル: screen.c プロジェクト: erichuang1994/fbbs
size_t screen_display_width(const char *ptr, bool utf8)
{
	size_t width = 0;
	bool ansi = false;
	while (*ptr) {
		if (ansi) {
			if (isalpha(*ptr))
				ansi = false;
		} else {
			if (*ptr == '\033') {
				ansi = true;
			} else {
				if (utf8) {
					wchar_t wc = next_wchar(&ptr, NULL);
					if (wc == WEOF)
						break;
					width += fb_wcwidth(wc);
					--ptr;
				} else {
					++width;
				}
			}
		}
		++ptr;
	}
	return width;
}
コード例 #5
0
ファイル: post.c プロジェクト: fbbs/fbbs
/**
 * Find newline in [begin, end), truncate at TRUNCATE_WIDTH.
 * @param begin The head pointer.
 * @param end The off-the-end pointer.
 * @param utf8 是否以UTF-8编码
 * @return Off-the-end pointer to the first (truncated) line.
 */
static const char *get_truncated_line(const char *begin, const char *end,
		bool utf8)
{
	const char *code = "[0123456789;";
	bool ansi = false;

	int width = TRUNCATE_WIDTH;
	if (end - begin >= 2 && *begin == ':' && *(begin + 1) == ' ')
		width += 2;

	for (const char *s = begin; s < end; ++s) {
		if (*s == '\n')
			return s + 1;

		if (*s == '\033') {
			ansi = true;
			continue;
		}

		if (ansi) {
			if (!memchr(code, *s, sizeof(code) - 1))
				ansi = false;
			continue;
		}

		if (*s & 0x80) {
			if (utf8) {
				const char *ptr = s;
				size_t size = end - s;
				wchar_t wc = next_wchar(&ptr, &size);
				if (wc == WEOF || wc == 0) {
					++s;
				} else {
					width -= fb_wcwidth(wc);
					if (width < 0)
						return s;
					s = ptr - 1;
				}
			} else {
				width -= 2;
				if (width < 0)
					return s;
				++s;
			}
			if (width == 0)
				return (s + 1 > end ? end : s + 1);
		} else {
			if (--width == 0)
				return s + 1;
		}
	}
	return end;
}
コード例 #6
0
ファイル: editor.c プロジェクト: icewwn/fbbs-1
static wchar_t get_next_wchar(editor_t *editor)
{
	const char *buffer = NULL;
	size_t bytes = 0;
	char utf8_buffer[8] = { '\0' };

	int ch = terminal_getchar();
	editor->input_buffer[(int) editor->pending_bytes++] = ch;

	if (terminal_is_utf8()) {
		buffer = editor->input_buffer;
		bytes = editor->pending_bytes;
	} else {
		if (editor->pending_bytes > 1) {
			convert(CONVERT_G2U, editor->input_buffer, editor->pending_bytes,
					utf8_buffer, sizeof(utf8_buffer), NULL, NULL);
			editor->pending_bytes = 0;
			if (utf8_buffer[0] != '\0') {
				buffer = utf8_buffer;
				bytes = strlen(utf8_buffer);
			}
		} else if (!(ch & 0x80)) {
			editor->pending_bytes = 0;
			return ch;
		}
	}

	if (buffer) {
		wchar_t wc = next_wchar(&buffer, &bytes);
		if ((wc && wc != WEOF)
				|| editor->pending_bytes == sizeof(editor->input_buffer)) {
			editor->pending_bytes = 0;
			return wc;
		}
	}
	return 0;
}