mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-14 21:09:05 +08:00
Merge pull request #4650 from RaiKoHoff/Dev_Master
Update: Scintilla v5.3.4. Lexilla v5.2.4
This commit is contained in:
commit
a11b041c3e
@ -61,7 +61,6 @@ unreadVariable:lexilla/lexers/LexJulia.cxx
|
||||
variableScope:lexilla/lexers/LexJulia.cxx
|
||||
variableScope:lexilla/lexers/LexLaTeX.cxx
|
||||
constParameter:lexilla/lexers/LexLaTeX.cxx
|
||||
constParameter:lexilla/lexers/LexLisp.cxx
|
||||
constParameter:lexilla/lexers/LexMagik.cxx
|
||||
constParameter:lexilla/lexers/LexMatlab.cxx
|
||||
unreadVariable:lexilla/lexers/LexMatlab.cxx
|
||||
@ -91,7 +90,6 @@ redundantInitialization:lexilla/lexers/LexRegistry.cxx
|
||||
constParameter:lexilla/lexers/LexRuby.cxx
|
||||
knownConditionTrueFalse:lexilla/lexers/LexRuby.cxx
|
||||
constParameter:lexilla/lexers/LexRust.cxx
|
||||
constParameter:lexilla/lexers/LexScriptol.cxx
|
||||
knownConditionTrueFalse:lexilla/lexers/LexScriptol.cxx
|
||||
variableScope:lexilla/lexers/LexSpecman.cxx
|
||||
unreadVariable:lexilla/lexers/LexSpice.cxx
|
||||
@ -128,29 +126,12 @@ constParameterCallback:lexilla/lexers/LexPython.cxx
|
||||
constParameterCallback:lexilla/lexers/LexScriptol.cxx
|
||||
constParameterCallback:lexilla/lexers/LexVB.cxx
|
||||
|
||||
constVariable:lexilla/lexers/LexA68k.cxx
|
||||
constVariable:lexilla/lexers/LexAsn1.cxx
|
||||
constVariable:lexilla/lexers/LexCLW.cxx
|
||||
constVariable:lexilla/lexers/LexCOBOL.cxx
|
||||
constVariable:lexilla/lexers/LexCSS.cxx
|
||||
constVariable:lexilla/lexers/LexCrontab.cxx
|
||||
constVariable:lexilla/lexers/LexEScript.cxx
|
||||
constVariable:lexilla/lexers/LexEiffel.cxx
|
||||
constVariable:lexilla/lexers/LexForth.cxx
|
||||
constVariable:lexilla/lexers/LexGui4Cli.cxx
|
||||
constVariable:lexilla/lexers/LexKix.cxx
|
||||
constVariable:lexilla/lexers/LexLout.cxx
|
||||
constVariable:lexilla/lexers/LexMetapost.cxx
|
||||
constVariable:lexilla/lexers/LexModula.cxx
|
||||
constVariable:lexilla/lexers/LexOpal.cxx
|
||||
constVariable:lexilla/lexers/LexPS.cxx
|
||||
constVariable:lexilla/lexers/LexPascal.cxx
|
||||
constVariable:lexilla/lexers/LexRebol.cxx
|
||||
constVariable:lexilla/lexers/LexSorcus.cxx
|
||||
constVariable:lexilla/lexers/LexStata.cxx
|
||||
constVariable:lexilla/lexers/LexTACL.cxx
|
||||
constVariable:lexilla/lexers/LexTADS3.cxx
|
||||
constVariable:lexilla/lexers/LexTAL.cxx
|
||||
|
||||
// cppcheck appears wrong as atKeyPath must be remembered between loops
|
||||
variableScope:lexilla/lexers/LexRegistry.cxx
|
||||
|
||||
@ -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="20230313" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
.logo {
|
||||
@ -61,8 +61,8 @@
|
||||
<font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
|
||||
</td>
|
||||
<td width="40%" align="right">
|
||||
<font color="#FFCC99" size="3">Release version 5.2.2<br />
|
||||
Site last modified February 8 2023</font>
|
||||
<font color="#FFCC99" size="3">Release version 5.2.4<br />
|
||||
Site last modified March 13 2023</font>
|
||||
</td>
|
||||
<td width="20%">
|
||||
|
||||
@ -77,13 +77,13 @@
|
||||
</tr>
|
||||
</table>
|
||||
<ul id="versionlist">
|
||||
<li>Version 5.2.4 improves C++ and GDScript.</li>
|
||||
<li>Version 5.2.3 improves Makefile, Ruby, and YAML.</li>
|
||||
<li>Version 5.2.2 improves C++, Matlab, Modula-3, Python, and X12.</li>
|
||||
<li>Version 5.2.1 improves Batch, F#, Markdown, and PowerShell.</li>
|
||||
<li>Version 5.2.0 improves PowerShell and R.</li>
|
||||
<li>Version 5.1.9 improves Julia and Properties.</li>
|
||||
<li>Version 5.1.8 improves F#, MS SQL, PowerShell, and Visual Prolog.</li>
|
||||
<li>Version 5.1.7 improves CMake, HTML, Matlab, Raku, Ruby, and VHDL.</li>
|
||||
<li>Version 5.1.6 improves Markdown and Ruby.</li>
|
||||
</ul>
|
||||
<ul id="menu">
|
||||
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
|
||||
|
||||
@ -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/lexilla522.zip">
|
||||
<font size="4"> <a href="https://www.scintilla.org/lexilla524.zip">
|
||||
Windows</a>
|
||||
<a href="https://www.scintilla.org/lexilla522.tgz">
|
||||
<a href="https://www.scintilla.org/lexilla524.tgz">
|
||||
GTK/Linux</a>
|
||||
</font>
|
||||
</td>
|
||||
@ -42,7 +42,7 @@
|
||||
containing very few restrictions.
|
||||
</p>
|
||||
<h3>
|
||||
Release 5.2.2
|
||||
Release 5.2.4
|
||||
</h3>
|
||||
<h4>
|
||||
Source Code
|
||||
@ -50,8 +50,8 @@
|
||||
The source code package contains all of the source code for Lexilla but no binary
|
||||
executable code and is available in
|
||||
<ul>
|
||||
<li><a href="https://www.scintilla.org/lexilla522.zip">zip format</a> (1.2M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla522.tgz">tgz format</a> (0.9M) commonly used on Linux and compatible operating systems</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla524.zip">zip format</a> (1.2M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla524.tgz">tgz format</a> (0.9M) 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>
|
||||
|
||||
@ -585,12 +585,29 @@
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Releases</h2>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/lexilla524.zip">Release 5.2.4</a>
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Released 13 March 2023.
|
||||
</li>
|
||||
<li>
|
||||
C++: Fix failure to recognize keywords containing upper case.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/issues/149">Issue #149</a>.
|
||||
</li>
|
||||
<li>
|
||||
GDScript: Support % and $ node paths.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/issues/145">Issue #145</a>,
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/146">Pull request #146</a>.
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/lexilla523.zip">Release 5.2.3</a>
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Released 8 February 2023.
|
||||
Released 8 March 2023.
|
||||
</li>
|
||||
<li>
|
||||
Add scripts/PromoteNew.bat script to promote .new files after checking.
|
||||
|
||||
@ -2306,3 +2306,4 @@ val SCE_GD_COMMENTBLOCK=12
|
||||
val SCE_GD_STRINGEOL=13
|
||||
val SCE_GD_WORD2=14
|
||||
val SCE_GD_ANNOTATION=15
|
||||
val SCE_GD_NODEPATH=16
|
||||
|
||||
@ -2054,6 +2054,7 @@
|
||||
#define SCE_GD_STRINGEOL 13
|
||||
#define SCE_GD_WORD2 14
|
||||
#define SCE_GD_ANNOTATION 15
|
||||
#define SCE_GD_NODEPATH 16
|
||||
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
|
||||
|
||||
#endif
|
||||
|
||||
@ -91,6 +91,10 @@ constexpr bool IsSpaceOrTab(int ch) noexcept {
|
||||
return ch == ' ' || ch == '\t';
|
||||
}
|
||||
|
||||
constexpr bool IsOperatorOrSpace(int ch) noexcept {
|
||||
return isoperator(ch) || IsASpace(ch);
|
||||
}
|
||||
|
||||
bool OnlySpaceOrTab(const std::string &s) noexcept {
|
||||
for (const char ch : s) {
|
||||
if (!IsSpaceOrTab(ch))
|
||||
@ -138,23 +142,18 @@ BracketPair FindBracketPair(Tokens &tokens) {
|
||||
|
||||
void highlightTaskMarker(StyleContext &sc, LexAccessor &styler,
|
||||
int activity, const WordList &markerList, bool caseSensitive){
|
||||
if ((isoperator(sc.chPrev) || IsASpace(sc.chPrev)) && markerList.Length()) {
|
||||
constexpr Sci_PositionU lengthMarker = 50;
|
||||
char marker[lengthMarker+1] = "";
|
||||
const Sci_PositionU currPos = sc.currentPos;
|
||||
Sci_PositionU i = 0;
|
||||
while (i < lengthMarker) {
|
||||
const char ch = styler.SafeGetCharAt(currPos + i);
|
||||
if (IsASpace(ch) || isoperator(ch)) {
|
||||
if (IsOperatorOrSpace(sc.chPrev) && !IsOperatorOrSpace(sc.ch) && markerList.Length()) {
|
||||
std::string marker;
|
||||
for (Sci_PositionU currPos = sc.currentPos; true; currPos++) {
|
||||
const char ch = styler.SafeGetCharAt(currPos);
|
||||
if (IsOperatorOrSpace(ch)) {
|
||||
break;
|
||||
}
|
||||
if (caseSensitive)
|
||||
marker[i] = ch;
|
||||
marker.push_back(ch);
|
||||
else
|
||||
marker[i] = MakeLowerCase(ch);
|
||||
i++;
|
||||
marker.push_back(MakeLowerCase(ch));
|
||||
}
|
||||
marker[i] = '\0';
|
||||
if (markerList.InList(marker)) {
|
||||
sc.SetState(SCE_C_TASKMARKER|activity);
|
||||
}
|
||||
@ -767,6 +766,9 @@ Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
|
||||
void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
const StyleContext::Transform transform = caseSensitive ?
|
||||
StyleContext::Transform::none : StyleContext::Transform::lower;
|
||||
|
||||
const CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
|
||||
const CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
|
||||
|
||||
@ -843,6 +845,8 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
|
||||
SparseState<std::string> rawSTNew(lineCurrent);
|
||||
|
||||
std::string currentText;
|
||||
|
||||
int activitySet = preproc.ActiveState();
|
||||
|
||||
const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER);
|
||||
@ -928,31 +932,29 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
break;
|
||||
case SCE_C_IDENTIFIER:
|
||||
if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch == '.')) {
|
||||
char s[1000];
|
||||
if (caseSensitive) {
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
} else {
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
}
|
||||
if (keywords.InList(s)) {
|
||||
lastWordWasUUID = strcmp(s, "uuid") == 0;
|
||||
sc.GetCurrentString(currentText, transform);
|
||||
if (keywords.InList(currentText)) {
|
||||
lastWordWasUUID = currentText == "uuid";
|
||||
sc.ChangeState(SCE_C_WORD|activitySet);
|
||||
} else if (keywords2.InList(s)) {
|
||||
} else if (keywords2.InList(currentText)) {
|
||||
sc.ChangeState(SCE_C_WORD2|activitySet);
|
||||
} else if (keywords4.InList(s)) {
|
||||
} else if (keywords4.InList(currentText)) {
|
||||
sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);
|
||||
} else {
|
||||
const int subStyle = classifierIdentifiers.ValueFor(s);
|
||||
const int subStyle = classifierIdentifiers.ValueFor(currentText);
|
||||
if (subStyle >= 0) {
|
||||
sc.ChangeState(subStyle|activitySet);
|
||||
}
|
||||
}
|
||||
const bool literalString = sc.ch == '\"';
|
||||
if (literalString || sc.ch == '\'') {
|
||||
size_t lenS = strlen(s);
|
||||
std::string_view s = currentText;
|
||||
size_t lenS = s.length();
|
||||
const bool raw = literalString && sc.chPrev == 'R' && !setInvalidRawFirst.Contains(sc.chNext);
|
||||
if (raw)
|
||||
s[lenS--] = '\0';
|
||||
if (raw) {
|
||||
s.remove_suffix(1);
|
||||
lenS--;
|
||||
}
|
||||
const bool valid =
|
||||
(lenS == 0) ||
|
||||
((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) ||
|
||||
@ -1066,33 +1068,27 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
seenDocKeyBrace = true;
|
||||
} else if (!setDoxygen.Contains(sc.ch)
|
||||
&& !(seenDocKeyBrace && (sc.ch == ',' || sc.ch == '.'))) {
|
||||
char s[100];
|
||||
if (caseSensitive) {
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
} else {
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
}
|
||||
if (!(IsASpace(sc.ch) || (sc.ch == 0))) {
|
||||
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
|
||||
} else if (!keywords3.InList(s + 1) && !keywords3.InList(s)) {
|
||||
const int subStyleCDKW = classifierDocKeyWords.ValueFor(s+1);
|
||||
if (subStyleCDKW >= 0) {
|
||||
sc.ChangeState(subStyleCDKW|activitySet);
|
||||
} else {
|
||||
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
|
||||
} else {
|
||||
sc.GetCurrentString(currentText, transform);
|
||||
assert(!currentText.empty());
|
||||
std::string currentSuffix = currentText.substr(1);
|
||||
if (!keywords3.InList(currentSuffix) && !keywords3.InList(currentText)) {
|
||||
const int subStyleCDKW = classifierDocKeyWords.ValueFor(currentSuffix.c_str());
|
||||
if (subStyleCDKW >= 0) {
|
||||
sc.ChangeState(subStyleCDKW | activitySet);
|
||||
} else {
|
||||
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR | activitySet);
|
||||
}
|
||||
}
|
||||
}
|
||||
sc.SetState(styleBeforeDCKeyword|activitySet);
|
||||
seenDocKeyBrace = false;
|
||||
} else if (sc.ch == '>') {
|
||||
char s[100];
|
||||
if (caseSensitive) {
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
} else {
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
}
|
||||
if (!keywords3.InList(s)) {
|
||||
const int subStyleCDKW = classifierDocKeyWords.ValueFor(s + 1);
|
||||
sc.GetCurrentString(currentText, transform);
|
||||
if (!keywords3.InList(currentText)) {
|
||||
const int subStyleCDKW = classifierDocKeyWords.ValueFor(currentText.substr(1));
|
||||
if (subStyleCDKW >= 0) {
|
||||
sc.ChangeState(subStyleCDKW | activitySet);
|
||||
} else {
|
||||
@ -1222,7 +1218,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
}
|
||||
break;
|
||||
case SCE_C_TASKMARKER:
|
||||
if (isoperator(sc.ch) || IsASpace(sc.ch)) {
|
||||
if (IsOperatorOrSpace(sc.ch)) {
|
||||
sc.SetState(styleBeforeTaskMarker|activitySet);
|
||||
styleBeforeTaskMarker = SCE_C_DEFAULT;
|
||||
}
|
||||
|
||||
@ -71,3 +71,14 @@ void StyleContext::GetCurrent(char *s, Sci_PositionU len) {
|
||||
void StyleContext::GetCurrentLowered(char *s, Sci_PositionU len) {
|
||||
styler.GetRangeLowered(styler.GetStartSegment(), currentPos, s, len);
|
||||
}
|
||||
|
||||
void StyleContext::GetCurrentString(std::string &string, Transform transform) {
|
||||
const Sci_PositionU startPos = styler.GetStartSegment();
|
||||
const Sci_PositionU len = currentPos - styler.GetStartSegment();
|
||||
string.resize(len);
|
||||
if (transform == Transform::lower) {
|
||||
styler.GetRangeLowered(startPos, currentPos, string.data(), len + 1);
|
||||
} else {
|
||||
styler.GetRange(startPos, currentPos, string.data(), len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +160,6 @@ public:
|
||||
const unsigned char uch1 = ch1;
|
||||
return (ch == uch0) && (chNext == uch1);
|
||||
}
|
||||
|
||||
bool Match(const char *s) {
|
||||
const unsigned char su = *s;
|
||||
if (ch != su)
|
||||
@ -183,7 +182,8 @@ public:
|
||||
bool MatchIgnoreCase(const char *s);
|
||||
void GetCurrent(char *s, Sci_PositionU len);
|
||||
void GetCurrentLowered(char *s, Sci_PositionU len);
|
||||
|
||||
enum class Transform { none, lower };
|
||||
void GetCurrentString(std::string &string, Transform transform);
|
||||
|
||||
// >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
@ -182,6 +183,12 @@ bool WordList::InList(const char *s) const noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** convenience overload so can easily call with std::string.
|
||||
*/
|
||||
bool WordList::InList(const std::string &s) const noexcept {
|
||||
return InList(s.c_str());
|
||||
}
|
||||
|
||||
/** similar to InList, but word s can be a substring of keyword.
|
||||
* eg. the keyword define is defined as def~ine. This means the word must start
|
||||
* with def to be a keyword, but also defi, defin and define are valid.
|
||||
|
||||
@ -33,6 +33,7 @@ public:
|
||||
void Clear() noexcept;
|
||||
bool Set(const char *s);
|
||||
bool InList(const char *s) const noexcept;
|
||||
bool InList(const std::string &s) const noexcept;
|
||||
bool InListAbbreviated(const char *s, const char marker) const noexcept;
|
||||
bool InListAbridged(const char *s, const char marker) const noexcept;
|
||||
const char *WordAt(int n) const noexcept;
|
||||
|
||||
23
lexilla/scripts/PromoteNew.bat
Normal file
23
lexilla/scripts/PromoteNew.bat
Normal file
@ -0,0 +1,23 @@
|
||||
@echo off
|
||||
rem Promote new result files.
|
||||
rem Find all the *.new files under test\examples and copy them to their expected name without ".new".
|
||||
rem Run after RunTest.bat if ".new" result files are correct.
|
||||
pushd ..\test\examples
|
||||
for /R %%f in (*.new) do (call :moveFile %%f)
|
||||
popd
|
||||
goto :eof
|
||||
|
||||
:moveFile
|
||||
set pathWithNew=%1
|
||||
set directory=%~dp1
|
||||
set fileWithNew=%~nx1
|
||||
set fileNoNew=%~n1
|
||||
set pathNoNew=%pathWithNew:~0,-4%
|
||||
|
||||
if exist %pathNoNew% (
|
||||
echo Move %fileWithNew% to %fileNoNew% in %directory%
|
||||
) else (
|
||||
echo New %fileWithNew% to %fileNoNew% in %directory%
|
||||
)
|
||||
move %pathWithNew% %pathNoNew%
|
||||
goto :eof
|
||||
@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.2.2</string>
|
||||
<string>5.2.4</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
||||
@ -792,6 +792,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
@ -851,6 +852,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@ -875,7 +877,8 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5.2.2;
|
||||
CURRENT_PROJECT_VERSION = 5.2.4;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 4F446KW87E;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
@ -901,7 +904,8 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5.2.2;
|
||||
CURRENT_PROJECT_VERSION = 5.2.4;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 4F446KW87E;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define VERSION_LEXILLA "5.2.2"
|
||||
#define VERSION_WORDS 5, 2, 2, 0
|
||||
#define VERSION_LEXILLA "5.2.4"
|
||||
#define VERSION_WORDS 5, 2, 4, 0
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_WORDS
|
||||
|
||||
@ -1 +1 @@
|
||||
522
|
||||
524
|
||||
@ -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