Beispiel #1
0
size_t split_line(SplitStringLine *result, unsigned wid, std::wstring_view str, size_t offset, unsigned options) {
	str.remove_prefix(offset);
	const wchar_t *s = str.data();
	size_t slen = str.length();

	size_t cur = 0;     // Current position
	unsigned curwid = 0;// Used screen width

	for (;;) {
		if (cur >= slen) {
			result->begin = offset;
			result->len = slen;
			result->wid = curwid;
			return (offset + slen);
		}
		if (!(options & SPLIT_NEWLINE_AS_SPACE) && s[cur] == L'\n') {
			result->begin = offset;
			result->len = cur;
			result->wid = curwid;
			return (offset + cur + 1); // Skip the newline character
		}
		unsigned w = ucs_width (s[cur]);
		if (curwid + w > wid) {
			break;
		}
		curwid += w;
		++cur;
	}
	// Not the whold string. Neither has a newline character been encountered
	// Now scan backward to find a proper line-breaking point
	unsigned extra_skip = 0;
	if (!(options & SPLIT_CUT_WORD)) {
		unsigned xcur = cur;
		for (;;) {
			if (xcur == 0) { // This means that a single word is longer than a line. We have to split it
				break;
			}
			if ((!ucs_isalnum (s[xcur-1]) || !ucs_isalnum (s[xcur])) &&
					allow_line_end (s[xcur-1]) &&
					allow_line_beginning (s[xcur])) {
				cur = xcur;
				break;
			}
			curwid -= ucs_width (s[--xcur]);
		}
		while (cur+extra_skip+1<slen && s[cur+extra_skip]==L' ') {
			++extra_skip;
		}
	}
	result->begin = offset;
	result->len = cur;
	result->wid = curwid;
	return (offset + cur + extra_skip);
}