mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-11 21:03:05 +08:00
+upd: Scintilla v5.3.4
This commit is contained in:
parent
9c9a2b3df2
commit
8b442ce38a
@ -2,4 +2,4 @@ This is only a repository to track Scintilla (https://sourceforge.net/p/scintill
|
||||
resp. (http://hg.code.sf.net/p/scintilla/code)
|
||||
resp. GitHub Mirror: (https://github.com/missdeer/scintilla)
|
||||
changes for Notepad3 (https://github.com/rizonesoft/Notepad3) development.
|
||||
|
||||
|
||||
|
||||
@ -7982,7 +7982,7 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
|
||||
|
||||
<p><b id="SCI_SETLAYOUTTHREADS">SCI_SETLAYOUTTHREADS(int threads)</b><br />
|
||||
<b id="SCI_GETLAYOUTTHREADS">SCI_GETLAYOUTTHREADS → int</b><br />
|
||||
The time taken to measure text runs on wide lines can be improved by performing the task
|
||||
The time taken to measure text runs on wide lines or when wrapping can be improved by performing the task
|
||||
concurrently on multiple threads when
|
||||
<a class="seealso" href="#SCI_SUPPORTSFEATURE">SCI_SUPPORTSFEATURE(SC_SUPPORTS_THREAD_SAFE_MEASURE_WIDTHS)</a>
|
||||
is available.
|
||||
|
||||
@ -26,9 +26,9 @@
|
||||
<table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<font size="4"> <a href="https://www.scintilla.org/scintilla533.zip">
|
||||
<font size="4"> <a href="https://www.scintilla.org/scintilla534.zip">
|
||||
Windows</a>
|
||||
<a href="https://www.scintilla.org/scintilla533.tgz">
|
||||
<a href="https://www.scintilla.org/scintilla534.tgz">
|
||||
GTK/Linux</a>
|
||||
</font>
|
||||
</td>
|
||||
@ -42,7 +42,7 @@
|
||||
containing very few restrictions.
|
||||
</p>
|
||||
<h3>
|
||||
Release 5.3.3
|
||||
Release 5.3.4
|
||||
</h3>
|
||||
<h4>
|
||||
Source Code
|
||||
@ -50,8 +50,8 @@
|
||||
The source code package contains all of the source code for Scintilla but no binary
|
||||
executable code and is available in
|
||||
<ul>
|
||||
<li><a href="https://www.scintilla.org/scintilla533.zip">zip format</a> (1.4M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla533.tgz">tgz format</a> (1.3M) commonly used on Linux and compatible operating systems</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla534.zip">zip format</a> (1.4M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla534.tgz">tgz format</a> (1.3M) commonly used on Linux and compatible operating systems</li>
|
||||
</ul>
|
||||
Instructions for building on both Windows and Linux are included in the readme file.
|
||||
<h4>
|
||||
|
||||
@ -584,7 +584,10 @@
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Released 8 February 2023.
|
||||
Released 8 March 2023.
|
||||
</li>
|
||||
<li>
|
||||
Add multithreaded wrap to significantly improve performance of wrapping large files.
|
||||
</li>
|
||||
<li>
|
||||
More typesafe bindings of *Full APIs in ScintillaCall.
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
|
||||
<meta name="Description"
|
||||
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
|
||||
<meta name="Date.Modified" content="20230208" />
|
||||
<meta name="Date.Modified" content="20230308" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
#versionlist {
|
||||
@ -56,8 +56,8 @@
|
||||
GTK, and macOS</font>
|
||||
</td>
|
||||
<td width="40%" align="right">
|
||||
<font color="#FFCC99" size="3"> Release version 5.3.3<br />
|
||||
Site last modified February 8 2023</font>
|
||||
<font color="#FFCC99" size="3"> Release version 5.3.4<br />
|
||||
Site last modified March 8 2023</font>
|
||||
</td>
|
||||
<td width="20%">
|
||||
|
||||
@ -72,12 +72,12 @@
|
||||
</tr>
|
||||
</table>
|
||||
<ul id="versionlist">
|
||||
<li>Version 5.3.4 adds multithreaded wrapping.</li>
|
||||
<li>Version 5.3.3 fixes minor bugs in APIs and platform layers.</li>
|
||||
<li>Version 5.3.2 adds SCI_REPLACETARGETMINIMAL to modify text without marking unchanged start and end text in change history.</li>
|
||||
<li>Version 5.3.1 can represent invisible text with a character to simplify editing and provide summarized views.</li>
|
||||
<li>Version 5.3.0 adds change history.</li>
|
||||
<li>Version 5.2.4 fixes failures on GTK with multi-threaded layout.</li>
|
||||
<li>Version 5.2.3 adds 64-bit safe APIs and fixes scrollbar on GTK with Xorg.</li>
|
||||
</ul>
|
||||
<ul id="menu">
|
||||
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
|
||||
|
||||
@ -161,7 +161,7 @@ def checkDocumentation():
|
||||
#~ if api not in headers:
|
||||
#~ print("No header for ", api)
|
||||
|
||||
# Examine definitions
|
||||
# Examine definitions
|
||||
#<b id="SCI_SETLAYOUTCACHE">SCI_SETLAYOUTCACHE(int cacheMode)</b>
|
||||
defPattern = re.compile(r'<b id="([A-Z_0-9]+)">([A-Z][A-Za-z0-9_() *#\"=<>/&;,\n-]+?)</b>')
|
||||
for api, sig in re.findall(defPattern, docs):
|
||||
@ -201,7 +201,7 @@ def checkDocumentation():
|
||||
with open(outName, "wt") as docFile:
|
||||
docFile.write(docs)
|
||||
|
||||
# Examine constant definitions
|
||||
# Examine constant definitions
|
||||
#<code>SC_CARETSTICKY_WHITESPACE</code> (2)
|
||||
constPattern = re.compile(r'<code>(\w+)</code> *\((\w+)\)')
|
||||
for name, val in re.findall(constPattern, docs):
|
||||
|
||||
@ -34,7 +34,7 @@ def UpdateVersionNumbers(sci, root):
|
||||
UpdateLineInFile(root / "doc/ScintillaDownload.html", " Release",
|
||||
" Release " + sci.versionDotted)
|
||||
ReplaceREInFile(root / "doc/ScintillaDownload.html",
|
||||
r"/www.scintilla.org/([a-zA-Z]+)\d\d\d",
|
||||
r"/www.scintilla.org/([a-zA-Z]+)\d{3,5}",
|
||||
r"/www.scintilla.org/\g<1>" + sci.version,
|
||||
0)
|
||||
UpdateLineInFile(root / "doc/index.html",
|
||||
|
||||
@ -49,8 +49,8 @@ class ScintillaData:
|
||||
def __init__(self, scintillaRoot):
|
||||
# Discover version information
|
||||
self.version = (scintillaRoot / "version.txt").read_text().strip()
|
||||
self.versionDotted = self.version[0] + '.' + self.version[1] + '.' + \
|
||||
self.version[2]
|
||||
self.versionDotted = self.version[0:-2] + '.' + self.version[-2] + '.' + \
|
||||
self.version[-1]
|
||||
self.versionCommad = self.versionDotted.replace(".", ", ") + ', 0'
|
||||
|
||||
with (scintillaRoot / "doc" / "index.html").open() as f:
|
||||
|
||||
@ -605,7 +605,6 @@ class CaseConverter : public ICaseConverter {
|
||||
return character < other.character;
|
||||
}
|
||||
};
|
||||
CaseConversion conversion;
|
||||
typedef std::vector<CharacterConversion> CharacterToConversion;
|
||||
CharacterToConversion characterToConversion;
|
||||
// The parallel arrays
|
||||
@ -613,8 +612,7 @@ class CaseConverter : public ICaseConverter {
|
||||
std::vector<ConversionString> conversions;
|
||||
|
||||
public:
|
||||
explicit CaseConverter(CaseConversion conversion_) : conversion(conversion_) {
|
||||
};
|
||||
CaseConverter() noexcept = default;
|
||||
// Deleted so CaseConverter objects can not be copied.
|
||||
CaseConverter(const CaseConverter &) = delete;
|
||||
CaseConverter(CaseConverter &&) = delete;
|
||||
@ -690,15 +688,13 @@ public:
|
||||
// Empty the original calculated data completely
|
||||
CharacterToConversion().swap(characterToConversion);
|
||||
}
|
||||
void AddSymmetric(int lower, int upper);
|
||||
void SetupConversions();
|
||||
void AddSymmetric(CaseConversion conversion, int lower, int upper);
|
||||
void SetupConversions(CaseConversion conversion);
|
||||
};
|
||||
|
||||
CaseConverter caseConvFold(CaseConversion::fold);
|
||||
CaseConverter caseConvUp(CaseConversion::upper);
|
||||
CaseConverter caseConvLow(CaseConversion::lower);
|
||||
CaseConverter caseConvList[3];
|
||||
|
||||
void CaseConverter::AddSymmetric(int lower, int upper) {
|
||||
void CaseConverter::AddSymmetric(CaseConversion conversion, int lower, int upper) {
|
||||
const int character = (conversion == CaseConversion::upper) ? lower : upper;
|
||||
const int source = (conversion == CaseConversion::upper) ? upper : lower;
|
||||
char converted[maxConversionLength+1]{};
|
||||
@ -720,7 +716,7 @@ std::string_view NextField(std::string_view &view) {
|
||||
return field;
|
||||
}
|
||||
|
||||
void CaseConverter::SetupConversions() {
|
||||
void CaseConverter::SetupConversions(CaseConversion conversion) {
|
||||
// First initialize for the symmetric ranges
|
||||
for (size_t i=0; i<std::size(symmetricCaseConversionRanges);) {
|
||||
const int lower = symmetricCaseConversionRanges[i++];
|
||||
@ -728,14 +724,14 @@ void CaseConverter::SetupConversions() {
|
||||
const int length = symmetricCaseConversionRanges[i++];
|
||||
const int pitch = symmetricCaseConversionRanges[i++];
|
||||
for (int j=0; j<length*pitch; j+=pitch) {
|
||||
AddSymmetric(lower+j, upper+j);
|
||||
AddSymmetric(conversion, lower+j, upper+j);
|
||||
}
|
||||
}
|
||||
// Add the symmetric singletons
|
||||
for (size_t i=0; i<std::size(symmetricCaseConversions);) {
|
||||
const int lower = symmetricCaseConversions[i++];
|
||||
const int upper = symmetricCaseConversions[i++];
|
||||
AddSymmetric(lower, upper);
|
||||
AddSymmetric(conversion, lower, upper);
|
||||
}
|
||||
// Add the complex cases
|
||||
std::string_view sComplex = complexCaseConversions;
|
||||
@ -768,21 +764,11 @@ void CaseConverter::SetupConversions() {
|
||||
}
|
||||
|
||||
CaseConverter *ConverterForConversion(CaseConversion conversion) {
|
||||
CaseConverter *pCaseConv = &caseConvFold;
|
||||
switch (conversion) {
|
||||
case CaseConversion::fold:
|
||||
pCaseConv = &caseConvFold;
|
||||
break;
|
||||
case CaseConversion::upper:
|
||||
pCaseConv = &caseConvUp;
|
||||
break;
|
||||
case CaseConversion::lower:
|
||||
default:
|
||||
pCaseConv = &caseConvLow;
|
||||
break;
|
||||
}
|
||||
const unsigned index = static_cast<unsigned>(conversion);
|
||||
assert(index < std::size(caseConvList));
|
||||
CaseConverter *pCaseConv = &caseConvList[index];
|
||||
if (!pCaseConv->Initialised()) {
|
||||
pCaseConv->SetupConversions();
|
||||
pCaseConv->SetupConversions(conversion);
|
||||
}
|
||||
return pCaseConv;
|
||||
}
|
||||
|
||||
@ -448,6 +448,10 @@ Sci_Position SCI_METHOD Document::LineStart(Sci_Position line) const noexcept {
|
||||
return cb.LineStart(line);
|
||||
}
|
||||
|
||||
Range Document::LineRange(Sci::Line line) const noexcept {
|
||||
return {cb.LineStart(line), cb.LineStart(line + 1)};
|
||||
}
|
||||
|
||||
bool Document::IsLineStartPosition(Sci::Position position) const {
|
||||
return LineStart(LineFromPosition(position)) == position;
|
||||
}
|
||||
|
||||
@ -54,6 +54,10 @@ public:
|
||||
return start == end;
|
||||
}
|
||||
|
||||
[[nodiscard]] Sci::Position Length() const noexcept {
|
||||
return (start <= end) ? (end - start) : (start - end);
|
||||
}
|
||||
|
||||
Sci::Position First() const noexcept {
|
||||
return (start <= end) ? start : end;
|
||||
}
|
||||
@ -454,6 +458,7 @@ public:
|
||||
int MarkerNumberFromLine(Sci::Line line, int which) const noexcept;
|
||||
int MarkerHandleFromLine(Sci::Line line, int which) const noexcept;
|
||||
Sci_Position SCI_METHOD LineStart(Sci_Position line) const noexcept override;
|
||||
[[nodiscard]] Range LineRange(Sci::Line line) const noexcept;
|
||||
bool IsLineStartPosition(Sci::Position position) const;
|
||||
Sci_Position SCI_METHOD LineEnd(Sci_Position line) const noexcept override;
|
||||
Sci::Position LineEndPosition(Sci::Position position) const;
|
||||
|
||||
@ -397,7 +397,7 @@ void LayoutSegments(IPositionCache *pCache,
|
||||
* Copy the given @a line and its styles from the document into local arrays.
|
||||
* Also determine the x position at which each character starts.
|
||||
*/
|
||||
void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewStyle &vstyle, LineLayout *ll, int width) {
|
||||
void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewStyle &vstyle, LineLayout *ll, int width, bool callerMultiThreaded) {
|
||||
if (!ll)
|
||||
return;
|
||||
|
||||
@ -494,7 +494,7 @@ void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewSt
|
||||
|
||||
const size_t threadsForLength = std::max(1, numCharsInLine / bytesPerLayoutThread);
|
||||
size_t threads = std::min<size_t>({ segments.size(), threadsForLength, maxLayoutThreads });
|
||||
if (!surface->SupportsFeature(Supports::ThreadSafeMeasureWidths)) {
|
||||
if (!surface->SupportsFeature(Supports::ThreadSafeMeasureWidths) || callerMultiThreaded) {
|
||||
threads = 1;
|
||||
}
|
||||
|
||||
@ -502,6 +502,7 @@ void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewSt
|
||||
|
||||
const bool textUnicode = CpUtf8 == model.pdoc->dbcsCodePage;
|
||||
const bool multiThreaded = threads > 1;
|
||||
const bool multiThreadedContext = multiThreaded || callerMultiThreaded;
|
||||
IPositionCache *pCache = posCache.get();
|
||||
|
||||
// If only 1 thread needed then use the main thread, else spin up multiple
|
||||
@ -511,8 +512,8 @@ void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewSt
|
||||
for (size_t th = 0; th < threads; th++) {
|
||||
// Find relative positions of everything except for tabs
|
||||
std::future<void> fut = std::async(policy,
|
||||
[pCache, surface, &vstyle, &ll, &segments, &nextIndex, textUnicode, multiThreaded]() {
|
||||
LayoutSegments(pCache, surface, vstyle, ll, segments, nextIndex, textUnicode, multiThreaded);
|
||||
[pCache, surface, &vstyle, &ll, &segments, &nextIndex, textUnicode, multiThreadedContext]() {
|
||||
LayoutSegments(pCache, surface, vstyle, ll, segments, nextIndex, textUnicode, multiThreadedContext);
|
||||
});
|
||||
futures.push_back(std::move(fut));
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ public:
|
||||
|
||||
std::shared_ptr<LineLayout> RetrieveLineLayout(Sci::Line lineNumber, const EditModel &model);
|
||||
void LayoutLine(const EditModel &model, Surface *surface, const ViewStyle &vstyle,
|
||||
LineLayout *ll, int width);
|
||||
LineLayout *ll, int width, bool callerMultiThreaded=false);
|
||||
|
||||
static void UpdateBidiData(const EditModel &model, const ViewStyle &vstyle, LineLayout *ll);
|
||||
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
|
||||
#include "ScintillaTypes.h"
|
||||
#include "ScintillaMessages.h"
|
||||
@ -274,6 +277,11 @@ Sci::Line Editor::TopLineOfMain() const noexcept {
|
||||
return topLine;
|
||||
}
|
||||
|
||||
Point Editor::ClientSize() const {
|
||||
const PRectangle rcClient = GetClientRectangle();
|
||||
return Point(rcClient.Width(), rcClient.Height());
|
||||
}
|
||||
|
||||
PRectangle Editor::GetClientRectangle() const {
|
||||
return wMain.GetClientPosition();
|
||||
}
|
||||
@ -290,8 +298,8 @@ PRectangle Editor::GetTextRectangle() const {
|
||||
}
|
||||
|
||||
Sci::Line Editor::LinesOnScreen() const {
|
||||
const PRectangle rcClient = GetClientRectangle();
|
||||
const int htClient = static_cast<int>(rcClient.bottom - rcClient.top);
|
||||
const Point sizeClient = ClientSize();
|
||||
const int htClient = static_cast<int>(sizeClient.y);
|
||||
//Platform::DebugPrintf("lines on screen = %d\n", htClient / lineHeight + 1);
|
||||
return htClient / vs.lineHeight;
|
||||
}
|
||||
@ -1468,6 +1476,130 @@ bool Editor::WrapOneLine(Surface *surface, Sci::Line lineToWrap) {
|
||||
return pcs->SetHeight(lineToWrap, linesWrapped);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Lines less than lengthToMultiThread are laid out in blocks in parallel.
|
||||
// Longer lines are multi-threaded inside LayoutLine.
|
||||
// This allows faster processing when lines differ greatly in length and thus time to lay out.
|
||||
constexpr Sci::Position lengthToMultiThread = 4000;
|
||||
|
||||
}
|
||||
|
||||
bool Editor::WrapBlock(Surface *surface, Sci::Line lineToWrap, Sci::Line lineToWrapEnd) {
|
||||
|
||||
const size_t linesBeingWrapped = static_cast<size_t>(lineToWrapEnd - lineToWrap);
|
||||
|
||||
std::vector<int> linesAfterWrap(linesBeingWrapped);
|
||||
|
||||
size_t threads = std::min<size_t>({ linesBeingWrapped, view.maxLayoutThreads });
|
||||
if (!surface->SupportsFeature(Supports::ThreadSafeMeasureWidths)) {
|
||||
threads = 1;
|
||||
}
|
||||
|
||||
const bool multiThreaded = threads > 1;
|
||||
|
||||
ElapsedPeriod epWrapping;
|
||||
|
||||
// Wrap all the short lines in multiple threads
|
||||
|
||||
// If only 1 thread needed then use the main thread, else spin up multiple
|
||||
const std::launch policy = multiThreaded ? std::launch::async : std::launch::deferred;
|
||||
|
||||
std::atomic<size_t> nextIndex = 0;
|
||||
|
||||
// Lines that are less likely to be re-examined should not be read from or written to the cache.
|
||||
const SignificantLines significantLines {
|
||||
pdoc->SciLineFromPosition(sel.MainCaret()),
|
||||
pcs->DocFromDisplay(topLine),
|
||||
LinesOnScreen() + 1,
|
||||
view.llc.GetLevel(),
|
||||
};
|
||||
|
||||
// Protect the line layout cache from being accessed from multiple threads simultaneously
|
||||
std::mutex mutexRetrieve;
|
||||
|
||||
std::vector<std::future<void>> futures;
|
||||
for (size_t th = 0; th < threads; th++) {
|
||||
std::future<void> fut = std::async(policy,
|
||||
[=, &surface, &nextIndex, &linesAfterWrap, &mutexRetrieve]() {
|
||||
// llTemporary is reused for non-significant lines, avoiding allocation costs.
|
||||
std::shared_ptr<LineLayout> llTemporary = std::make_shared<LineLayout>(-1, 200);
|
||||
while (true) {
|
||||
const size_t i = nextIndex.fetch_add(1, std::memory_order_acq_rel);
|
||||
if (i >= linesBeingWrapped) {
|
||||
break;
|
||||
}
|
||||
const Sci::Line lineNumber = lineToWrap + i;
|
||||
const Range rangeLine = pdoc->LineRange(lineNumber);
|
||||
const Sci::Position lengthLine = rangeLine.Length();
|
||||
if (lengthLine < lengthToMultiThread) {
|
||||
std::shared_ptr<LineLayout> ll;
|
||||
if (significantLines.LineMayCache(lineNumber)) {
|
||||
std::lock_guard<std::mutex> guard(mutexRetrieve);
|
||||
ll = view.RetrieveLineLayout(lineNumber, *this);
|
||||
} else {
|
||||
ll = llTemporary;
|
||||
ll->ReSet(lineNumber, lengthLine);
|
||||
}
|
||||
view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth, multiThreaded);
|
||||
linesAfterWrap[i] = ll->lines;
|
||||
}
|
||||
}
|
||||
});
|
||||
futures.push_back(std::move(fut));
|
||||
}
|
||||
for (const std::future<void> &f : futures) {
|
||||
f.wait();
|
||||
}
|
||||
// End of multiple threads
|
||||
|
||||
// Multiply duration by number of threads to produce (near) equivalence to duration if single threaded
|
||||
const double durationShortLines = epWrapping.Duration(true);
|
||||
const double durationShortLinesThreads = durationShortLines * threads;
|
||||
|
||||
// Wrap all the long lines in the main thread.
|
||||
// LayoutLine may then multi-thread over segments in each line.
|
||||
|
||||
std::shared_ptr<LineLayout> llLarge = std::make_shared<LineLayout>(-1, 200);
|
||||
for (size_t indexLarge = 0; indexLarge < linesBeingWrapped; indexLarge++) {
|
||||
const Sci::Line lineNumber = lineToWrap + indexLarge;
|
||||
const Range rangeLine = pdoc->LineRange(lineNumber);
|
||||
const Sci::Position lengthLine = rangeLine.Length();
|
||||
if (lengthLine >= lengthToMultiThread) {
|
||||
std::shared_ptr<LineLayout> ll;
|
||||
if (significantLines.LineMayCache(lineNumber)) {
|
||||
ll = view.RetrieveLineLayout(lineNumber, *this);
|
||||
} else {
|
||||
ll = llLarge;
|
||||
ll->ReSet(lineNumber, lengthLine);
|
||||
}
|
||||
view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth);
|
||||
linesAfterWrap[indexLarge] = ll->lines;
|
||||
}
|
||||
}
|
||||
|
||||
const double durationLongLines = epWrapping.Duration();
|
||||
const size_t bytesBeingWrapped = pdoc->LineStart(lineToWrap + linesBeingWrapped) - pdoc->LineStart(lineToWrap);
|
||||
|
||||
size_t wrapsDone = 0;
|
||||
|
||||
for (size_t i = 0; i < linesBeingWrapped; i++) {
|
||||
const Sci::Line lineNumber = lineToWrap + i;
|
||||
int linesWrapped = linesAfterWrap[i];
|
||||
if (vs.annotationVisible != AnnotationVisible::Hidden) {
|
||||
linesWrapped += pdoc->AnnotationLines(lineNumber);
|
||||
}
|
||||
if (pcs->SetHeight(lineNumber, linesWrapped)) {
|
||||
wrapsDone++;
|
||||
}
|
||||
wrapPending.Wrapped(lineNumber);
|
||||
}
|
||||
|
||||
durationWrapOneByte.AddSample(bytesBeingWrapped, durationShortLinesThreads + durationLongLines);
|
||||
|
||||
return wrapsDone > 0;
|
||||
}
|
||||
|
||||
// Perform wrapping for a subset of the lines needing wrapping.
|
||||
// wsAll: wrap all lines which need wrapping in this single call
|
||||
// wsVisible: wrap currently visible lines
|
||||
@ -1549,16 +1681,7 @@ bool Editor::WrapLines(WrapScope ws) {
|
||||
if (surface) {
|
||||
//Platform::DebugPrintf("Wraplines: scope=%0d need=%0d..%0d perform=%0d..%0d\n", ws, wrapPending.start, wrapPending.end, lineToWrap, lineToWrapEnd);
|
||||
|
||||
const size_t bytesBeingWrapped = pdoc->LineStart(lineToWrapEnd) - pdoc->LineStart(lineToWrap);
|
||||
ElapsedPeriod epWrapping;
|
||||
while (lineToWrap < lineToWrapEnd) {
|
||||
if (WrapOneLine(surface, lineToWrap)) {
|
||||
wrapOccurred = true;
|
||||
}
|
||||
wrapPending.Wrapped(lineToWrap);
|
||||
lineToWrap++;
|
||||
}
|
||||
durationWrapOneByte.AddSample(bytesBeingWrapped, epWrapping.Duration());
|
||||
wrapOccurred = WrapBlock(surface, lineToWrap, lineToWrapEnd);
|
||||
|
||||
goodTopLine = pcs->DisplayFromDoc(lineDocTop) + std::min(
|
||||
subLineTop, static_cast<Sci::Line>(pcs->GetHeight(lineDocTop)-1));
|
||||
|
||||
@ -312,6 +312,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
Point GetVisibleOriginInMain() const override;
|
||||
PointDocument DocumentPointFromView(Point ptView) const; // Convert a point from view space to document
|
||||
Sci::Line TopLineOfMain() const noexcept final; // Return the line at Main's y coordinate 0
|
||||
virtual Point ClientSize() const;
|
||||
virtual PRectangle GetClientRectangle() const;
|
||||
virtual PRectangle GetClientDrawingRectangle();
|
||||
PRectangle GetTextRectangle() const;
|
||||
@ -403,6 +404,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
bool Wrapping() const noexcept;
|
||||
void NeedWrapping(Sci::Line docLineStart=0, Sci::Line docLineEnd=WrapPending::lineLarge);
|
||||
bool WrapOneLine(Surface *surface, Sci::Line lineToWrap);
|
||||
bool WrapBlock(Surface *surface, Sci::Line lineToWrap, Sci::Line lineToWrapEnd);
|
||||
enum class WrapScope {wsAll, wsVisible, wsIdle};
|
||||
bool WrapLines(WrapScope ws);
|
||||
void LinesJoin();
|
||||
|
||||
@ -102,6 +102,13 @@ void LineLayout::Resize(int maxLineLength_) {
|
||||
}
|
||||
}
|
||||
|
||||
void LineLayout::ReSet(Sci::Line lineNumber_, Sci::Position maxLineLength_) {
|
||||
lineNumber = lineNumber_;
|
||||
Resize(static_cast<int>(maxLineLength_));
|
||||
lines = 0;
|
||||
Invalidate(ValidLevel::invalid);
|
||||
}
|
||||
|
||||
void LineLayout::EnsureBidiData() {
|
||||
if (!bidiData) {
|
||||
bidiData = std::make_unique<BidiData>();
|
||||
@ -114,6 +121,7 @@ void LineLayout::Free() noexcept {
|
||||
styles.reset();
|
||||
positions.reset();
|
||||
lineStarts.reset();
|
||||
lenLineStarts = 0;
|
||||
bidiData.reset();
|
||||
}
|
||||
|
||||
@ -446,6 +454,21 @@ XYPOSITION ScreenLine::TabPositionAfter(XYPOSITION xPosition) const noexcept {
|
||||
return (std::floor((xPosition + TabWidthMinimumPixels()) / TabWidth()) + 1) * TabWidth();
|
||||
}
|
||||
|
||||
bool SignificantLines::LineMayCache(Sci::Line line) const noexcept {
|
||||
switch (level) {
|
||||
case LineCache::None:
|
||||
return false;
|
||||
case LineCache::Caret:
|
||||
return line == lineCaret;
|
||||
case LineCache::Page:
|
||||
return (abs(line - lineCaret) < linesOnScreen) ||
|
||||
((line >= lineTop) && (line <= (lineTop + linesOnScreen)));
|
||||
case LineCache::Document:
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
LineLayoutCache::LineLayoutCache() :
|
||||
level(LineCache::None),
|
||||
allInvalidated(false), styleClock(-1) {
|
||||
|
||||
@ -83,6 +83,7 @@ public:
|
||||
void operator=(LineLayout &&) = delete;
|
||||
virtual ~LineLayout();
|
||||
void Resize(int maxLineLength_);
|
||||
void ReSet(Sci::Line lineNumber_, Sci::Position maxLineLength_);
|
||||
void EnsureBidiData();
|
||||
void Free() noexcept;
|
||||
void ClearPositions();
|
||||
@ -140,6 +141,14 @@ struct ScreenLine : public IScreenLine {
|
||||
XYPOSITION TabPositionAfter(XYPOSITION xPosition) const noexcept override;
|
||||
};
|
||||
|
||||
struct SignificantLines {
|
||||
Sci::Line lineCaret;
|
||||
Sci::Line lineTop;
|
||||
Sci::Line linesOnScreen;
|
||||
Scintilla::LineCache level;
|
||||
bool LineMayCache(Sci::Line line) const noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
*/
|
||||
class LineLayoutCache {
|
||||
|
||||
@ -1 +1 @@
|
||||
533
|
||||
534
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define VERSION_SCINTILLA "5.3.3"
|
||||
#define VERSION_WORDS 5, 3, 3, 0
|
||||
#define VERSION_SCINTILLA "5.3.4"
|
||||
#define VERSION_WORDS 5, 3, 4, 0
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_WORDS
|
||||
|
||||
Loading…
Reference in New Issue
Block a user