Beispiel #1
0
Datei: post.c Projekt: 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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
/**
 * 计算一个宽字符的显示宽度
 * @param wc 一个宽字符
 * @return 该宽字符在编辑器终端上的显示宽度
 */
static size_t display_width_wchar(wchar_t wc)
{
	if (wc == L'\n')
		return 0;
	if (wc == L'\033')
		return 1;
	int width = fb_wcwidth(wc);
	return width < 1 ? 1 : width;
}
Beispiel #4
0
Datei: post.c Projekt: 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;
}