LibGUI: Validate TextDocument spans when merging them, not when painting
TextDocument::merge_span_collections() automatically makes sure that the spans are valid, move forwards, are in order, and do not overlap. This means we don't have to check these things every time TextEditor paints the document. merge_span_collections() now does these checks instead. I am not certain they are still useful, but someone in the past certainly did. I have modified them to take advantage of the operator overloads and Formatter that we now have.
This commit is contained in:
parent
54d45d4ac6
commit
04deb81f71
Notes:
sideshowbarker
2024-07-17 04:34:25 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/04deb81f71 Pull-request: https://github.com/SerenityOS/serenity/pull/17556 Reviewed-by: https://github.com/awesomekling ✅
2 changed files with 22 additions and 25 deletions
|
@ -1,12 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Badge.h>
|
||||
#include <AK/CharacterTypes.h>
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/QuickSort.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
@ -1409,7 +1411,27 @@ void TextDocument::merge_span_collections()
|
|||
}
|
||||
|
||||
m_spans.clear();
|
||||
TextDocumentSpan previous_span { .range = { TextPosition(0, 0), TextPosition(0, 0) }, .attributes = {} };
|
||||
for (auto span : merged_spans) {
|
||||
// Validate spans
|
||||
if (!span.span.range.is_valid()) {
|
||||
dbgln_if(TEXTEDITOR_DEBUG, "Invalid span {} => ignoring", span.span.range);
|
||||
continue;
|
||||
}
|
||||
if (span.span.range.end() < span.span.range.start()) {
|
||||
dbgln_if(TEXTEDITOR_DEBUG, "Span {} has negative length => ignoring", span.span.range);
|
||||
continue;
|
||||
}
|
||||
if (span.span.range.end() < previous_span.range.start()) {
|
||||
dbgln_if(TEXTEDITOR_DEBUG, "Spans not sorted (Span {} ends before previous span {}) => ignoring", span.span.range, previous_span.range);
|
||||
continue;
|
||||
}
|
||||
if (span.span.range.start() < previous_span.range.end()) {
|
||||
dbgln_if(TEXTEDITOR_DEBUG, "Span {} overlaps previous span {} => ignoring", span.span.range, previous_span.range);
|
||||
continue;
|
||||
}
|
||||
|
||||
previous_span = span.span;
|
||||
m_spans.append(move(span.span));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -584,42 +584,17 @@ void TextEditor::paint_event(PaintEvent& event)
|
|||
break;
|
||||
}
|
||||
auto& span = document().spans()[span_index];
|
||||
if (!span.range.is_valid()) {
|
||||
++span_index;
|
||||
continue;
|
||||
}
|
||||
if (span.range.end().line() < line_index) {
|
||||
dbgln_if(TEXTEDITOR_DEBUG, "spans not sorted (span end {}:{} is before current line {}) => ignoring", span.range.end().line(), span.range.end().column(), line_index);
|
||||
++span_index;
|
||||
continue;
|
||||
}
|
||||
if (span.range.start().line() > line_index
|
||||
|| (span.range.start().line() == line_index && span.range.start().column() >= start_of_visual_line + visual_line_text.length())) {
|
||||
// no more spans in this line, moving on
|
||||
break;
|
||||
}
|
||||
if (span.range.start().line() == span.range.end().line() && span.range.end().column() < span.range.start().column()) {
|
||||
dbgln_if(TEXTEDITOR_DEBUG, "span from {}:{} to {}:{} has negative length => ignoring", span.range.start().line(), span.range.start().column(), span.range.end().line(), span.range.end().column());
|
||||
++span_index;
|
||||
continue;
|
||||
}
|
||||
if (span.range.end().line() == line_index && span.range.end().column() < start_of_visual_line + next_column) {
|
||||
dbgln_if(TEXTEDITOR_DEBUG, "spans not sorted (span end {}:{} is before current position {}:{}) => ignoring",
|
||||
span.range.end().line(), span.range.end().column(), line_index, start_of_visual_line + next_column);
|
||||
++span_index;
|
||||
continue;
|
||||
}
|
||||
size_t span_start;
|
||||
if (span.range.start().line() < line_index || span.range.start().column() < start_of_visual_line) {
|
||||
span_start = 0;
|
||||
} else {
|
||||
span_start = span.range.start().column() - start_of_visual_line;
|
||||
}
|
||||
if (span_start < next_column) {
|
||||
dbgln_if(TEXTEDITOR_DEBUG, "span started before the current position, maybe two spans overlap? (span start {} is before current position {}) => ignoring", span_start, next_column);
|
||||
++span_index;
|
||||
continue;
|
||||
}
|
||||
size_t span_end;
|
||||
bool span_consumed;
|
||||
if (span.range.end().line() > line_index || span.range.end().column() > start_of_visual_line + visual_line_text.length()) {
|
||||
|
|
Loading…
Add table
Reference in a new issue