summaryrefslogtreecommitdiff
path: root/src/Fl_Text_Buffer.cxx
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2024-08-04 00:32:05 +0200
committerMatthias Melcher <github@matthiasm.com>2024-08-04 00:32:11 +0200
commit9bb9cb3f962bea7365e21bb1a836bf140deb6570 (patch)
tree97e66074c84b140cdce7f883925f395617e49d99 /src/Fl_Text_Buffer.cxx
parentbc7358036683fd7bd4e6a0fe29256fc70f573978 (diff)
Optimize Fl_Text_Display scrolling speed (#596).
Diffstat (limited to 'src/Fl_Text_Buffer.cxx')
-rw-r--r--src/Fl_Text_Buffer.cxx42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/Fl_Text_Buffer.cxx b/src/Fl_Text_Buffer.cxx
index 3bb8a10f0..f26afb39d 100644
--- a/src/Fl_Text_Buffer.cxx
+++ b/src/Fl_Text_Buffer.cxx
@@ -1166,6 +1166,48 @@ int Fl_Text_Buffer::count_lines(int startPos, int endPos) const {
return lineCount;
}
+/**
+ Estimate the number of newlines between \p startPos and \p endPos in buffer.
+ This call takes line wrapping into account. It assumes a line break at every
+ `lineLen` characters after the beginning of a line.
+ */
+int Fl_Text_Buffer::estimate_lines(int startPos, int endPos, int lineLen) const
+{
+ IS_UTF8_ALIGNED2(this, (startPos))
+ IS_UTF8_ALIGNED2(this, (endPos))
+
+ int gapLen = mGapEnd - mGapStart;
+ int lineCount = 0;
+ int softLineBreaks = 0, softLineBreakCount = lineLen;
+
+ int pos = startPos;
+ while (pos < mGapStart)
+ {
+ if (pos == endPos)
+ return lineCount + softLineBreaks;
+ if (mBuf[pos++] == '\n') {
+ softLineBreakCount = lineLen;
+ lineCount++;
+ }
+ if (--softLineBreakCount == 0) {
+ softLineBreakCount = lineLen;
+ softLineBreaks++;
+ }
+ }
+ while (pos < mLength) {
+ if (pos == endPos)
+ return lineCount + softLineBreaks;
+ if (mBuf[pos++ + gapLen] == '\n') {
+ softLineBreakCount = lineLen;
+ lineCount++;
+ }
+ if (--softLineBreakCount == 0) {
+ softLineBreakCount = lineLen;
+ softLineBreaks++;
+ }
+ }
+ return lineCount + softLineBreaks;
+}
/*
Skip to the first character, n lines ahead.