From e1f8bd54b87b2eed2b346579d69802feef4a86de Mon Sep 17 00:00:00 2001 From: glx22 Date: Sat, 13 Jan 2024 16:44:23 +0100 Subject: [PATCH] Change: [Win32] Ignore suitable breaking point if next line still doesn't fit --- src/os/windows/string_uniscribe.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/os/windows/string_uniscribe.cpp b/src/os/windows/string_uniscribe.cpp index 040101ec3602e..6fa8db9db3237 100644 --- a/src/os/windows/string_uniscribe.cpp +++ b/src/os/windows/string_uniscribe.cpp @@ -356,10 +356,12 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF int num_chars = this->cur_range_offset; int start_offs = this->cur_range_offset; int last_cluster = this->cur_range_offset + 1; - for (std::vector::iterator r = start_run; r != last_run; r++) { + for (std::vector::iterator r = start_run; r != this->ranges.end(); r++) { log_attribs.resize(r->pos - start_run->pos + r->len); if (FAILED(ScriptBreak(this->text_buffer + r->pos + start_offs, r->len - start_offs, &r->sa, &log_attribs[r->pos - start_run->pos + start_offs]))) return nullptr; + if (r >= last_run) continue; + std::vector dx(r->len); ScriptGetLogicalWidths(&r->sa, r->len, (int)r->glyphs.size(), &r->advances[0], &r->char_to_glyph[0], &r->vis_attribs[0], &dx[0]); @@ -378,6 +380,26 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF if (num_chars == this->cur_range_offset) { /* Didn't find any suitable word break point, just break on the last cluster boundary. */ num_chars = last_cluster; + } else { + /* If next line does not fit into the available width, ignore the found suitable breaking point. */ + int next_width = 0; + int next_chars = 0; + start_offs = this->cur_range_offset; + for (std::vector::iterator r = start_run; r != this->ranges.end(); r++) { + std::vector dx(r->len); + ScriptGetLogicalWidths(&r->sa, r->len, (int)r->glyphs.size(), &r->advances[0], &r->char_to_glyph[0], &r->vis_attribs[0], &dx[0]); + + /* Get width of next line until suitable breaking point. */ + for (int c = start_offs; c < r->len && next_width <= max_width; c++, next_chars++) { + if (next_chars <= num_chars) continue; + if (log_attribs[next_chars].fSoftBreak || log_attribs[next_chars].fWhiteSpace) break; + next_width += dx[c]; + } + if (next_chars < log_attribs.size() && (log_attribs[next_chars].fSoftBreak || log_attribs[next_chars].fWhiteSpace)) break; + + start_offs = 0; + } + if (next_width > max_width) num_chars = last_cluster; } /* Eat any whitespace characters before the breaking point. */