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); }