+upd: Scintilla v5.3.3

This commit is contained in:
METANEOCORTEX\Kotti 2023-02-24 18:15:03 +01:00
parent d0a8ba9f2f
commit 2ea0adb0c3
32 changed files with 940 additions and 802 deletions

View File

@ -231,7 +231,7 @@ Position ScintillaCall::GetStyledText(void *tr) {
return CallPointer(Message::GetStyledText, 0, tr);
}
Position ScintillaCall::GetStyledTextFull(void *tr) {
Position ScintillaCall::GetStyledTextFull(TextRangeFull *tr) {
return CallPointer(Message::GetStyledTextFull, 0, tr);
}
@ -1175,7 +1175,7 @@ Position ScintillaCall::FindText(Scintilla::FindOption searchFlags, void *ft) {
return CallPointer(Message::FindText, static_cast<uintptr_t>(searchFlags), ft);
}
Position ScintillaCall::FindTextFull(Scintilla::FindOption searchFlags, void *ft) {
Position ScintillaCall::FindTextFull(Scintilla::FindOption searchFlags, TextToFindFull *ft) {
return CallPointer(Message::FindTextFull, static_cast<uintptr_t>(searchFlags), ft);
}
@ -1183,7 +1183,7 @@ Position ScintillaCall::FormatRange(bool draw, void *fr) {
return CallPointer(Message::FormatRange, draw, fr);
}
Position ScintillaCall::FormatRangeFull(bool draw, void *fr) {
Position ScintillaCall::FormatRangeFull(bool draw, RangeToFormatFull *fr) {
return CallPointer(Message::FormatRangeFull, draw, fr);
}
@ -1251,7 +1251,7 @@ Position ScintillaCall::GetTextRange(void *tr) {
return CallPointer(Message::GetTextRange, 0, tr);
}
Position ScintillaCall::GetTextRangeFull(void *tr) {
Position ScintillaCall::GetTextRangeFull(TextRangeFull *tr) {
return CallPointer(Message::GetTextRangeFull, 0, tr);
}

View File

@ -46,6 +46,10 @@ constVariable:scintilla/gtk/ScintillaGTKAccessible.cxx
cstyleCast:scintilla/qt/ScintillaEdit/ScintillaEdit.cpp
shadowFunction:scintilla/qt/ScintillaEdit/ScintillaEdit.cpp
// cppcheck fails emit from Qt
shadowFunction:scintilla/qt/ScintillaEditBase/ScintillaQt.cpp
shadowFunction:scintilla/qt/ScintillaEditBase/ScintillaEditBase.cpp
// moc_ files show #error as they are not built with standard context
preprocessorErrorDirective:scintilla/qt/*.cpp
@ -58,3 +62,10 @@ passedByValue
// Suppress everything in catch.hpp as won't be changing
*:scintilla/test/unit/catch.hpp
// Checks for moves move to variables that are not read but the moved from is checked
unreadVariable:scintilla/test/unit/*.cxx
accessMoved:scintilla/test/unit/*.cxx
// cppcheck fails REQUIRE from Catch
comparisonOfFuncReturningBoolError:scintilla/test/unit/*.cxx

View File

@ -129,7 +129,7 @@
<h1>Scintilla Documentation</h1>
<p>Last edited 15 November 2022 NH</p>
<p>Last edited 14 January 2023 NH</p>
<p style="background:#90F0C0">Scintilla 5 has moved the lexers from Scintilla into a new
<a href="Lexilla.html">Lexilla</a> project.<br />
@ -6891,8 +6891,9 @@ struct Sci_TextToFindFull {
<p><code>SCI_FORMATRANGE</code> can be used to draw the text onto a display surface
which can include a printer display surface. Printed output shows text styling as on the
screen, but it hides all margins except a line number margin. All special marker effects are
removed and the selection and caret are hidden.</p>
screen, but it hides all margins except a line number margin.
Markers do not appear in a margin but will change line background colour.
The selection and caret are hidden.</p>
<p>Different platforms use different display surface ID types to print on. On Windows, these are
<code>HDC</code>s., on GTK 3.x <code>cairo_t *</code>,

View File

@ -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/scintilla532.zip">
<font size="4"> <a href="https://www.scintilla.org/scintilla533.zip">
Windows</a>&nbsp;&nbsp;
<a href="https://www.scintilla.org/scintilla532.tgz">
<a href="https://www.scintilla.org/scintilla533.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.3.2
Release 5.3.3
</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/scintilla532.zip">zip format</a> (1.4M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/scintilla532.tgz">tgz format</a> (1.3M) commonly used on Linux and compatible operating systems</li>
<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>
</ul>
Instructions for building on both Windows and Linux are included in the readme file.
<h4>

View File

@ -575,9 +575,80 @@
<td>Reinhard Nißl</td>
<td>Ferdinand Oeinck</td>
<td>Michael Heath</td>
<td>Enrico Tröger</td>
</tr>
</table>
<h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/scintilla534.zip">Release 5.3.4</a>
</h3>
<ul>
<li>
Released 8 February 2023.
</li>
<li>
More typesafe bindings of *Full APIs in ScintillaCall.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1477/">Feature #1477</a>.
</li>
<li>
Fix overlapping of text with line end wrap marker.
<a href="https://sourceforge.net/p/scintilla/bugs/2378/">Bug #2378</a>.
</li>
<li>
Fix clipping of line end wrap symbol for SC_WRAPVISUALFLAGLOC_END_BY_TEXT.
</li>
<li>
Where a multi-byte character contains multiple styles, display each byte as a representation.
This makes it easier to see and fix lexers that change styles mid-character, commonly because
they use fixed size buffers.
</li>
<li>
Fix a potential crash with autocompletion list fill-ups where a SCN_CHARADDED
handler retriggered an autocompletion list, but with no items that match the typed character.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla533.zip">Release 5.3.3</a>
</h3>
<ul>
<li>
Released 8 February 2023.
</li>
<li>
Fix SCI_LINESJOIN bug where carriage returns were incorrectly retained.
<a href="https://sourceforge.net/p/scintilla/bugs/2372/">Bug #2372</a>.
</li>
<li>
Fix SCI_VERTICALCENTRECARET to update the vertical scroll position.
</li>
<li>
When an autocompletion list is shown in response to SCN_CHARADDED, do not process character as fill-up or stop.
This avoids closing immediately when a character may both trigger and finish autocompletion.
</li>
<li>
On Cocoa fix character input bug where dotless 'i' and some other extended
Latin characters could not be entered.
The change also stops SCI_ASSIGNCMDKEY from working with these characters
on Cocoa.
<a href="https://sourceforge.net/p/scintilla/bugs/2374/">Bug #2374</a>.
</li>
<li>
On GTK, support IME context.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1476/">Feature #1476</a>.
</li>
<li>
On GTK on Win32, fix scrolling speed to not be too fast.
<a href="https://sourceforge.net/p/scintilla/bugs/2375/">Bug #2375</a>.
</li>
<li>
On Qt, fix indicator drawing past left of text pane over margin.
<a href="https://sourceforge.net/p/scintilla/bugs/2373/">Bug #2373</a>,
<a href="https://sourceforge.net/p/scintilla/bugs/1956/">Bug #1956</a>.
</li>
<li>
On Qt, allow scrolling with mouse wheel when scroll bar hidden.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla532.zip">Release 5.3.2</a>
</h3>

View File

@ -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="20221206" />
<meta name="Date.Modified" content="20230208" />
<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.2<br />
Site last modified December 6 2022</font>
<font color="#FFCC99" size="3"> Release version 5.3.3<br />
Site last modified February 8 2023</font>
</td>
<td width="20%">
&nbsp;
@ -72,12 +72,12 @@
</tr>
</table>
<ul id="versionlist">
<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>
<li>Version 5.2.2 on GTK, scroll horizontally with Shift + Scroll Wheel.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -15,6 +15,11 @@ namespace Scintilla {
enum class Message; // Declare in case ScintillaMessages.h not included
// Declare in case ScintillaStructures.h not included
struct TextRangeFull;
struct TextToFindFull;
struct RangeToFormatFull;
using FunctionDirect = intptr_t(*)(intptr_t ptr, unsigned int iMessage, uintptr_t wParam, intptr_t lParam, int *pStatus);
struct Failure {
@ -96,7 +101,7 @@ public:
void SelectAll();
void SetSavePoint();
Position GetStyledText(void *tr);
Position GetStyledTextFull(void *tr);
Position GetStyledTextFull(TextRangeFull *tr);
bool CanRedo();
Line MarkerLineFromHandle(int markerHandle);
void MarkerDeleteHandle(int markerHandle);
@ -332,9 +337,9 @@ public:
void SetPrintColourMode(Scintilla::PrintOption mode);
Scintilla::PrintOption PrintColourMode();
Position FindText(Scintilla::FindOption searchFlags, void *ft);
Position FindTextFull(Scintilla::FindOption searchFlags, void *ft);
Position FindTextFull(Scintilla::FindOption searchFlags, TextToFindFull *ft);
Position FormatRange(bool draw, void *fr);
Position FormatRangeFull(bool draw, void *fr);
Position FormatRangeFull(bool draw, RangeToFormatFull *fr);
void SetChangeHistory(Scintilla::ChangeHistoryOption changeHistory);
Scintilla::ChangeHistoryOption ChangeHistory();
Line FirstVisibleLine();
@ -351,7 +356,7 @@ public:
Position GetSelText(char *text);
std::string GetSelText();
Position GetTextRange(void *tr);
Position GetTextRangeFull(void *tr);
Position GetTextRangeFull(TextRangeFull *tr);
void HideSelection(bool hide);
bool SelectionHidden();
int PointXFromPosition(Position pos);

View File

@ -23,9 +23,9 @@ typeAliases = {
"colour": "Colour",
"colouralpha": "ColourAlpha",
"findtext": "void *",
"findtextfull": "void *",
"findtextfull": "TextToFindFull *",
"formatrange": "void *",
"formatrangefull": "void *",
"formatrangefull": "RangeToFormatFull *",
"int": "int",
"keymod": "int",
"line": "Line",
@ -34,7 +34,7 @@ typeAliases = {
"string": "const char *",
"stringresult": "char *",
"textrange": "void *",
"textrangefull": "void *",
"textrangefull": "TextRangeFull *",
}
basicTypes = [

View File

@ -225,27 +225,27 @@ void Document::RemoveLine(Sci::Line line) {
}
LineMarkers *Document::Markers() const noexcept {
return dynamic_cast<LineMarkers *>(perLineData[ldMarkers].get());
return static_cast<LineMarkers *>(perLineData[ldMarkers].get());
}
LineLevels *Document::Levels() const noexcept {
return dynamic_cast<LineLevels *>(perLineData[ldLevels].get());
return static_cast<LineLevels *>(perLineData[ldLevels].get());
}
LineState *Document::States() const noexcept {
return dynamic_cast<LineState *>(perLineData[ldState].get());
return static_cast<LineState *>(perLineData[ldState].get());
}
LineAnnotation *Document::Margins() const noexcept {
return dynamic_cast<LineAnnotation *>(perLineData[ldMargin].get());
return static_cast<LineAnnotation *>(perLineData[ldMargin].get());
}
LineAnnotation *Document::Annotations() const noexcept {
return dynamic_cast<LineAnnotation *>(perLineData[ldAnnotation].get());
return static_cast<LineAnnotation *>(perLineData[ldAnnotation].get());
}
LineAnnotation *Document::EOLAnnotations() const noexcept {
return dynamic_cast<LineAnnotation *>(perLineData[ldEOLAnnotation].get());
return static_cast<LineAnnotation *>(perLineData[ldEOLAnnotation].get());
}
LineEndType Document::LineEndTypesSupported() const {
@ -512,7 +512,7 @@ Sci::Position Document::VCHomePosition(Sci::Position position) const {
const Sci::Position startPosition = LineStart(line);
const Sci::Position endLine = LineEnd(line);
Sci::Position startText = startPosition;
while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t'))
while (startText < endLine && IsSpaceOrTab(cb.CharAt(startText)))
startText++;
if (position == startText)
return startPosition;
@ -558,8 +558,8 @@ int SCI_METHOD Document::GetLevel(Sci_Position line) const noexcept {
return Levels()->GetLevel(line);
}
FoldLevel Document::GetFoldLevel(Sci_Position line) const {
return static_cast<FoldLevel>(Levels()->GetLevel(line));
FoldLevel Document::GetFoldLevel(Sci_Position line) const noexcept {
return Levels()->GetFoldLevel(line);
}
void Document::ClearLevels() {
@ -597,21 +597,8 @@ Sci::Line Document::GetLastChild(Sci::Line lineParent, std::optional<FoldLevel>
return lineMaxSubord;
}
Sci::Line Document::GetFoldParent(Sci::Line line) const {
const FoldLevel level = LevelNumberPart(GetFoldLevel(line));
Sci::Line lineLook = line - 1;
while ((lineLook > 0) && (
(!LevelIsHeader(GetFoldLevel(lineLook))) ||
(LevelNumberPart(GetFoldLevel(lineLook)) >= level))
) {
lineLook--;
}
if (LevelIsHeader(GetFoldLevel(lineLook)) &&
(LevelNumberPart(GetFoldLevel(lineLook)) < level)) {
return lineLook;
} else {
return -1;
}
Sci::Line Document::GetFoldParent(Sci::Line line) const noexcept {
return Levels()->GetFoldParent(line);
}
void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sci::Line line, Sci::Line lastLine) {
@ -1576,13 +1563,12 @@ Sci::Position Document::SetLineIndentation(Sci::Line line, Sci::Position indent)
if (indent < 0)
indent = 0;
if (indent != indentOfLine) {
std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs);
const std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs);
const Sci::Position thisLineStart = LineStart(line);
const Sci::Position indentPos = GetLineIndentPosition(line);
UndoGroup ug(this);
DeleteChars(thisLineStart, indentPos - thisLineStart);
return thisLineStart + InsertString(thisLineStart, linebuf.c_str(),
linebuf.length());
return thisLineStart + InsertString(thisLineStart, linebuf);
} else {
return GetLineIndentPosition(line);
}
@ -1719,7 +1705,8 @@ void Document::ConvertLineEnds(EndOfLine eolModeSet) {
UndoGroup ug(this);
for (Sci::Position pos = 0; pos < Length(); pos++) {
if (cb.CharAt(pos) == '\r') {
const char ch = cb.CharAt(pos);
if (ch == '\r') {
if (cb.CharAt(pos + 1) == '\n') {
// CRLF
if (eolModeSet == EndOfLine::Cr) {
@ -1739,7 +1726,7 @@ void Document::ConvertLineEnds(EndOfLine eolModeSet) {
pos--;
}
}
} else if (cb.CharAt(pos) == '\n') {
} else if (ch == '\n') {
// LF
if (eolModeSet == EndOfLine::CrLf) {
pos += InsertString(pos, "\r", 1); // Insert CR
@ -1753,6 +1740,16 @@ void Document::ConvertLineEnds(EndOfLine eolModeSet) {
}
std::string_view Document::EOLString() const noexcept {
if (eolMode == EndOfLine::CrLf) {
return "\r\n";
} else if (eolMode == EndOfLine::Cr) {
return "\r";
} else {
return "\n";
}
}
DocumentOption Document::Options() const noexcept {
return (IsLarge() ? DocumentOption::TextLarge : DocumentOption::Default) |
(cb.HasStyles() ? DocumentOption::Default : DocumentOption::StylesNone);

View File

@ -424,6 +424,7 @@ public:
void Indent(bool forwards, Sci::Line lineBottom, Sci::Line lineTop);
static std::string TransformLineEnds(const char *s, size_t len, Scintilla::EndOfLine eolModeWanted);
void ConvertLineEnds(Scintilla::EndOfLine eolModeSet);
std::string_view EOLString() const noexcept;
void SetReadOnly(bool set) { cb.SetReadOnly(set); }
bool IsReadOnly() const noexcept { return cb.IsReadOnly(); }
bool IsLarge() const noexcept { return cb.IsLarge(); }
@ -465,10 +466,10 @@ public:
int SCI_METHOD SetLevel(Sci_Position line, int level) override;
int SCI_METHOD GetLevel(Sci_Position line) const noexcept override;
Scintilla::FoldLevel GetFoldLevel(Sci_Position line) const;
Scintilla::FoldLevel GetFoldLevel(Sci_Position line) const noexcept;
void ClearLevels();
Sci::Line GetLastChild(Sci::Line lineParent, std::optional<Scintilla::FoldLevel> level = {}, Sci::Line lastLine = -1);
Sci::Line GetFoldParent(Sci::Line line) const;
Sci::Line GetFoldParent(Sci::Line line) const noexcept;
void GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, Sci::Line line, Sci::Line lastLine);
Sci::Position ExtendWordSelect(Sci::Position pos, int delta, bool onlyWordCharacters=false) const;

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,6 @@ void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XY
std::string_view text, DrawPhase phase);
void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRectangle rcText,
const StyledText &st, size_t start, size_t length, DrawPhase phase);
void Hexits(char *hexits, int ch) noexcept;
typedef void (*DrawTabArrowFn)(Surface *surface, PRectangle rcTab, int ymid,
const ViewStyle &vsDraw, Stroke stroke);
@ -133,32 +132,29 @@ public:
Sci::Line DisplayFromPosition(Surface *surface, const EditModel &model, Sci::Position pos, const ViewStyle &vs);
Sci::Position StartEndDisplayLine(Surface *surface, const EditModel &model, Sci::Position pos, bool start, const ViewStyle &vs);
void DrawIndentGuide(Surface *surface, Sci::Line lineVisible, int lineHeight, XYPOSITION start, PRectangle rcSegment, bool highlight);
void DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine,
Sci::Line line, Sci::Position lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart,
ColourOptional background);
private:
void DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Position lineEnd, XYPOSITION subLineStart, ColourOptional background);
void DrawFoldDisplayText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase);
Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYPOSITION subLineStart, DrawPhase phase);
void DrawEOLAnnotationText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase);
Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYPOSITION subLineStart, DrawPhase phase);
void DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase);
void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line lineDoc,
int xStart, PRectangle rcLine, int subLine) const;
void DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine,
Range lineRange, Sci::Position posLineStart, int xStart,
int subLine, ColourOptional background) const;
void DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line lineVisible,
PRectangle rcLine, Range lineRange, Sci::Position posLineStart, int xStart,
int subLine, ColourOptional background);
void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line lineDoc, int xStart, PRectangle rcLine, int subLine) const;
void DrawIndentGuide(Surface *surface, XYPOSITION start, PRectangle rcSegment, bool highlight, bool offset);
void DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible, Range lineRange, Sci::Position posLineStart,
ColourOptional background);
void DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, Sci::Line lineVisible, PRectangle rcLine, int xStart, int subLine);
void DrawLine(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line,
Sci::Line lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase);
void PaintText(Surface *surfaceWindow, const EditModel &model, PRectangle rcArea, PRectangle rcClient,
const ViewStyle &vsDraw);
void FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, PRectangle rcArea, int subLine) const;
Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible);
void DrawLine(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
Sci::Line line, Sci::Line lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase);
public:
void PaintText(Surface *surfaceWindow, const EditModel &model, const ViewStyle &vsDraw,
PRectangle rcArea, PRectangle rcClient);
Sci::Position FormatRange(bool draw, CharacterRangeFull chrg, Rectangle rc, Surface *surface, Surface *surfaceMeasure,
const EditModel &model, const ViewStyle &vs);
};

View File

@ -212,50 +212,7 @@ void Editor::Finalise() {
}
void Editor::SetRepresentations() {
reprs.Clear();
// C0 control set
const char *const reps[] = {
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
};
for (size_t j=0; j < std::size(reps); j++) {
const char c[2] = { static_cast<char>(j), 0 };
reprs.SetRepresentation(std::string_view(c, 1), reps[j]);
}
reprs.SetRepresentation("\x7f", "DEL");
const int dbcsCodePage = pdoc->dbcsCodePage;
// C1 control set
// As well as Unicode mode, ISO-8859-1 should use these
if (CpUtf8 == dbcsCodePage) {
const char *const repsC1[] = {
"PAD", "HOP", "BPH", "NBH", "IND", "NEL", "SSA", "ESA",
"HTS", "HTJ", "VTS", "PLD", "PLU", "RI", "SS2", "SS3",
"DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA",
"SOS", "SGCI", "SCI", "CSI", "ST", "OSC", "PM", "APC"
};
for (size_t j=0; j < std::size(repsC1); j++) {
const char c1[3] = { '\xc2', static_cast<char>(0x80+j), 0 };
reprs.SetRepresentation(c1, repsC1[j]);
}
reprs.SetRepresentation("\xe2\x80\xa8", "LS");
reprs.SetRepresentation("\xe2\x80\xa9", "PS");
}
// Invalid as single bytes in multi-byte encodings
if (dbcsCodePage) {
for (int k = 0x80; k < 0x100; k++) {
if ((CpUtf8 == dbcsCodePage) || !IsDBCSValidSingleByte(dbcsCodePage, k)) {
const char hiByte[2] = { static_cast<char>(k), 0 };
char hexits[4];
Hexits(hexits, k);
reprs.SetRepresentation(hiByte, hexits);
}
}
}
reprs.SetDefaultRepresentations(pdoc->dbcsCodePage);
}
void Editor::DropGraphics() noexcept {
@ -801,9 +758,7 @@ void Editor::MultipleSelectAdd(AddNumber addNumber) {
bool Editor::RangeContainsProtected(Sci::Position start, Sci::Position end) const noexcept {
if (vs.ProtectionActive()) {
if (start > end) {
const Sci::Position t = start;
start = end;
end = t;
std::swap(start, end);
}
for (Sci::Position pos = start; pos < end; pos++) {
if (vs.styles[pdoc->StyleIndexAt(pos)].IsProtected())
@ -1012,6 +967,7 @@ void Editor::VerticalCentreCaret() {
const Sci::Line newTop = lineDisplay - (LinesOnScreen() / 2);
if (topLine != newTop) {
SetTopLine(newTop > 0 ? newTop : 0);
SetVerticalScrollPos();
RedrawRect(GetClientRectangle());
}
}
@ -1067,14 +1023,14 @@ void Editor::MoveSelectedLines(int lineDelta) {
SetSelection(pdoc->MovePositionOutsideChar(selectionStart - 1, -1), selectionEnd);
ClearSelection();
const char *eol = StringFromEOLMode(pdoc->eolMode);
const std::string_view eol = pdoc->EOLString();
if (currentLine + lineDelta >= pdoc->LinesTotal())
pdoc->InsertString(pdoc->Length(), eol, strlen(eol));
pdoc->InsertString(pdoc->Length(), eol);
GoToLine(currentLine + lineDelta);
Sci::Position selectionLength = pdoc->InsertString(CurrentPosition(), selectedText);
if (appendEol) {
const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition() + selectionLength, eol, strlen(eol));
const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition() + selectionLength, eol);
selectionLength += lengthInserted;
}
SetSelection(CurrentPosition(), CurrentPosition() + selectionLength);
@ -1183,9 +1139,11 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran
// It should be possible to scroll the window to show the caret,
// but this fails to remove the caret on GTK+
if (bSlop) { // A margin is defined
Sci::Line yMoveT, yMoveB;
Sci::Line yMoveT = 0;
Sci::Line yMoveB = 0;
if (bStrict) {
Sci::Line yMarginT, yMarginB;
Sci::Line yMarginT = 0;
Sci::Line yMarginB = 0;
if (!FlagSet(options, XYScrollOptions::useMargin)) {
// In drag mode, avoid moves
// otherwise, a double click will select several lines.
@ -1280,9 +1238,11 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &ran
const bool bEven = FlagSet(policies.x.policy, CaretPolicy::Even);
if (bSlop) { // A margin is defined
int xMoveL, xMoveR;
int xMoveL = 0;
int xMoveR = 0;
if (bStrict) {
int xMarginL, xMarginR;
int xMarginL = 0;
int xMarginR = 0;
if (!FlagSet(options, XYScrollOptions::useMargin)) {
// In drag mode, avoid moves unless very near of the margin
// otherwise, a simple click will select text.
@ -1623,33 +1583,21 @@ bool Editor::WrapLines(WrapScope ws) {
void Editor::LinesJoin() {
if (!RangeContainsProtected(targetRange.start.Position(), targetRange.end.Position())) {
UndoGroup ug(pdoc);
bool prevNonWS = true;
for (Sci::Position pos = targetRange.start.Position(); pos < targetRange.end.Position(); pos++) {
if (pdoc->IsPositionInLineEnd(pos)) {
targetRange.end.Add(-pdoc->LenChar(pos));
pdoc->DelChar(pos);
if (prevNonWS) {
// Ensure at least one space separating previous lines
const Sci::Position lengthInserted = pdoc->InsertString(pos, " ", 1);
targetRange.end.Add(lengthInserted);
}
} else {
prevNonWS = pdoc->CharAt(pos) != ' ';
const Sci::Line line = pdoc->SciLineFromPosition(targetRange.start.Position());
for (Sci::Position pos = pdoc->LineEnd(line); pos < targetRange.end.Position(); pos = pdoc->LineEnd(line)) {
const char chPrev = pdoc->CharAt(pos - 1);
const Sci::Position widthChar = pdoc->LenChar(pos);
targetRange.end.Add(-widthChar);
pdoc->DeleteChars(pos, widthChar);
if (chPrev != ' ') {
// Ensure at least one space separating previous lines
const Sci::Position lengthInserted = pdoc->InsertString(pos, " ", 1);
targetRange.end.Add(lengthInserted);
}
}
}
}
const char *Editor::StringFromEOLMode(EndOfLine eolMode) noexcept {
if (eolMode == EndOfLine::CrLf) {
return "\r\n";
} else if (eolMode == EndOfLine::Cr) {
return "\r";
} else {
return "\n";
}
}
void Editor::LinesSplit(int pixelWidth) {
if (!RangeContainsProtected(targetRange.start.Position(), targetRange.end.Position())) {
if (pixelWidth == 0) {
@ -1658,7 +1606,7 @@ void Editor::LinesSplit(int pixelWidth) {
}
const Sci::Line lineStart = pdoc->SciLineFromPosition(targetRange.start.Position());
Sci::Line lineEnd = pdoc->SciLineFromPosition(targetRange.end.Position());
const char *eol = StringFromEOLMode(pdoc->eolMode);
const std::string_view eol = pdoc->EOLString();
UndoGroup ug(pdoc);
for (Sci::Line line = lineStart; line <= lineEnd; line++) {
AutoSurface surface(this);
@ -1669,8 +1617,7 @@ void Editor::LinesSplit(int pixelWidth) {
Sci::Position lengthInsertedTotal = 0;
for (int subLine = 1; subLine < ll->lines; subLine++) {
const Sci::Position lengthInserted = pdoc->InsertString(
posLineStart + lengthInsertedTotal + ll->LineStart(subLine),
eol, strlen(eol));
posLineStart + lengthInsertedTotal + ll->LineStart(subLine), eol);
targetRange.end.Add(lengthInserted);
lengthInsertedTotal += lengthInserted;
}
@ -1819,7 +1766,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
return;
}
view.PaintText(surfaceWindow, *this, rcArea, rcClient, vs);
view.PaintText(surfaceWindow, *this, vs, rcArea, rcClient);
if (horizontalScrollBarVisible && trackLineWidth && (view.lineWidthMaxSeen > scrollWidth)) {
scrollWidth = view.lineWidthMaxSeen;
@ -1928,8 +1875,8 @@ Sci::Position Editor::RealizeVirtualSpace(Sci::Position position, Sci::Position
if (indent == position) {
return pdoc->SetLineIndentation(line, pdoc->GetLineIndentation(line) + virtualSpace);
} else {
std::string spaceText(virtualSpace, ' ');
const Sci::Position lengthInserted = pdoc->InsertString(position, spaceText.c_str(), virtualSpace);
const std::string spaceText(virtualSpace, ' ');
const Sci::Position lengthInserted = pdoc->InsertString(position, spaceText);
position += lengthInserted;
}
}
@ -1996,7 +1943,7 @@ void Editor::InsertCharacter(std::string_view sv, CharacterSource charSource) {
}
}
positionInsert = RealizeVirtualSpace(positionInsert, currentSel->caret.VirtualSpace());
const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, sv.data(), sv.length());
const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, sv);
if (lengthInserted > 0) {
currentSel->caret.SetPosition(positionInsert + lengthInserted);
currentSel->anchor.SetPosition(positionInsert + lengthInserted);
@ -2130,9 +2077,8 @@ void Editor::InsertPasteShape(const char *text, Sci::Position len, PasteShape sh
Sci::Position lengthInserted = pdoc->InsertString(insertPos, text, len);
// add the newline if necessary
if ((len > 0) && (text[len - 1] != '\n' && text[len - 1] != '\r')) {
const char *endline = StringFromEOLMode(pdoc->eolMode);
const Sci::Position length = strlen(endline);
lengthInserted += pdoc->InsertString(insertPos + lengthInserted, endline, length);
const std::string_view endline = pdoc->EOLString();
lengthInserted += pdoc->InsertString(insertPos + lengthInserted, endline);
}
if (sel.MainCaret() == insertPos) {
SetEmptySelection(sel.MainCaret() + lengthInserted);
@ -2226,10 +2172,8 @@ void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Posit
if ((ptr[i] == '\r') || (!prevCr))
line++;
if (line >= pdoc->LinesTotal()) {
if (pdoc->eolMode != EndOfLine::Lf)
pdoc->InsertString(pdoc->Length(), "\r", 1);
if (pdoc->eolMode != EndOfLine::Cr)
pdoc->InsertString(pdoc->Length(), "\n", 1);
const std::string_view eol = pdoc->EOLString();
pdoc->InsertString(pdoc->LengthNoExcept(), eol);
}
// Pad the end of lines with spaces if required
sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert));
@ -3031,10 +2975,8 @@ void Editor::LineTranspose() {
pdoc->DeleteChars(startPrevious, linePrevious.length());
startCurrent -= linePrevious.length();
startCurrent += pdoc->InsertString(startPrevious, lineCurrent.c_str(),
lineCurrent.length());
pdoc->InsertString(startCurrent, linePrevious.c_str(),
linePrevious.length());
startCurrent += pdoc->InsertString(startPrevious, lineCurrent);
pdoc->InsertString(startCurrent, linePrevious);
// Move caret to start of current line
MovePositionTo(SelectionPosition(startCurrent));
}
@ -3061,8 +3003,8 @@ void Editor::LineReverse() {
pdoc->DeleteChars(lineStart2, lineLen2);
pdoc->DeleteChars(lineStart1, lineLen1);
lineStart2 -= lineLen1;
pdoc->InsertString(lineStart2, line1.c_str(), lineLen1);
pdoc->InsertString(lineStart1, line2.c_str(), lineLen2);
pdoc->InsertString(lineStart2, line1);
pdoc->InsertString(lineStart1, line2);
}
// Wholly select all affected lines
sel.RangeMain() = SelectionRange(pdoc->LineStart(lineStart),
@ -3074,11 +3016,9 @@ void Editor::Duplicate(bool forLine) {
forLine = true;
}
UndoGroup ug(pdoc);
const char *eol = "";
Sci::Position eolLen = 0;
std::string_view eol;
if (forLine) {
eol = StringFromEOLMode(pdoc->eolMode);
eolLen = strlen(eol);
eol = pdoc->EOLString();
}
for (size_t r=0; r<sel.Count(); r++) {
SelectionPosition start = sel.Range(r).Start();
@ -3089,10 +3029,10 @@ void Editor::Duplicate(bool forLine) {
end = SelectionPosition(pdoc->LineEnd(line));
}
std::string text = RangeText(start.Position(), end.Position());
Sci::Position lengthInserted = eolLen;
Sci::Position lengthInserted = 0;
if (forLine)
lengthInserted = pdoc->InsertString(end.Position(), eol, eolLen);
pdoc->InsertString(end.Position() + lengthInserted, text.c_str(), text.length());
lengthInserted = pdoc->InsertString(end.Position(), eol);
pdoc->InsertString(end.Position() + lengthInserted, text);
}
if (sel.Count() && sel.IsRectangular()) {
SelectionPosition last = sel.Last();
@ -3129,11 +3069,11 @@ void Editor::NewLine() {
// Insert each line end
size_t countInsertions = 0;
const std::string_view eol = pdoc->EOLString();
for (size_t r = 0; r < sel.Count(); r++) {
sel.Range(r).ClearVirtualSpace();
const char *eol = StringFromEOLMode(pdoc->eolMode);
const Sci::Position positionInsert = sel.Range(r).caret.Position();
const Sci::Position insertLength = pdoc->InsertString(positionInsert, eol, strlen(eol));
const Sci::Position insertLength = pdoc->InsertString(positionInsert, eol);
if (insertLength > 0) {
sel.Range(r) = SelectionRange(positionInsert + insertLength);
countInsertions++;
@ -3143,16 +3083,12 @@ void Editor::NewLine() {
// Perform notifications after all the changes as the application may change the
// selections in response to the characters.
for (size_t i = 0; i < countInsertions; i++) {
const char *eol = StringFromEOLMode(pdoc->eolMode);
while (*eol) {
NotifyChar(*eol, CharacterSource::DirectInput);
for (const char ch : eol) {
NotifyChar(ch, CharacterSource::DirectInput);
if (recordingMacro) {
char txt[2];
txt[0] = *eol;
txt[1] = '\0';
const char txt[2] = { ch, '\0' };
NotifyMacroRecord(Message::ReplaceSel, 0, reinterpret_cast<sptr_t>(txt));
}
eol++;
}
}
@ -4043,8 +3979,7 @@ void Editor::Indent(bool forwards) {
if (numSpaces < 1)
numSpaces = pdoc->tabInChars;
const std::string spaceText(numSpaces, ' ');
const Sci::Position lengthInserted = pdoc->InsertString(caretPosition, spaceText.c_str(),
spaceText.length());
const Sci::Position lengthInserted = pdoc->InsertString(caretPosition, spaceText);
sel.Range(r) = SelectionRange(caretPosition + lengthInserted);
}
}
@ -4148,14 +4083,14 @@ Sci::Position Editor::FindTextFull(
pdoc->SetCaseFolder(CaseFolderForEncoding());
try {
const Sci::Position pos = pdoc->FindText(
static_cast<Sci::Position>(ft->chrg.cpMin),
static_cast<Sci::Position>(ft->chrg.cpMax),
ft->chrg.cpMin,
ft->chrg.cpMax,
ft->lpstrText,
static_cast<FindOption>(wParam),
&lengthFound);
if (pos != -1) {
ft->chrgText.cpMin = static_cast<Sci_PositionCR>(pos);
ft->chrgText.cpMax = static_cast<Sci_PositionCR>(pos + lengthFound);
ft->chrgText.cpMin = pos;
ft->chrgText.cpMax = pos + lengthFound;
}
return pos;
} catch (RegexError &) {
@ -4432,7 +4367,7 @@ void Editor::DropAt(SelectionPosition position, const char *value, size_t length
position = MovePositionOutsideChar(position, sel.MainCaret() - position.Position());
position = RealizeVirtualSpace(position);
const Sci::Position lengthInserted = pdoc->InsertString(
position.Position(), convertedText.c_str(), convertedText.length());
position.Position(), convertedText);
if (lengthInserted > 0) {
SelectionPosition posAfterInsertion = position;
posAfterInsertion.Add(lengthInserted);
@ -5805,12 +5740,11 @@ void Editor::AddStyledText(const char *buffer, Sci::Position appendLength) {
// The buffer consists of alternating character bytes and style bytes
const Sci::Position textLength = appendLength / 2;
std::string text(textLength, '\0');
Sci::Position i;
for (i = 0; i < textLength; i++) {
for (Sci::Position i = 0; i < textLength; i++) {
text[i] = buffer[i*2];
}
const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition(), text.c_str(), textLength);
for (i = 0; i < textLength; i++) {
const Sci::Position lengthInserted = pdoc->InsertString(CurrentPosition(), text);
for (Sci::Position i = 0; i < textLength; i++) {
text[i] = buffer[i*2+1];
}
pdoc->StartStyling(CurrentPosition());
@ -5900,8 +5834,8 @@ void Editor::StyleSetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {
const int classified = UTF8Classify(utf8);
if (!(classified & UTF8MaskInvalid)) {
// valid UTF-8
int len = classified & UTF8MaskWidth;
for (int i=0; i<len && i<4; i++)
const int len = classified & UTF8MaskWidth;
for (int i=0; i<len && i<UTF8MaxBytes; i++)
*rep++ = *utf8++;
}
*rep = 0;

View File

@ -614,8 +614,6 @@ protected: // ScintillaBase subclass needs access to much of Editor
Scintilla::sptr_t StyleGetMessage(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
void SetSelectionNMessage(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
static const char *StringFromEOLMode(Scintilla::EndOfLine eolMode) noexcept;
// Coercion functions for transforming WndProc parameters into pointers
static void *PtrFromSPtr(Scintilla::sptr_t lParam) noexcept {
return reinterpret_cast<void *>(lParam);

View File

@ -66,6 +66,9 @@ public:
constexpr bool Intersects(Interval other) const noexcept {
return (right > other.left) && (left < other.right);
}
constexpr Interval Offset(XYPOSITION offset) const noexcept {
return {left + offset, right + offset};
}
};
/**
@ -112,6 +115,10 @@ public:
return (right > other.left) && (left < other.right) &&
(bottom > other.top) && (top < other.bottom);
}
constexpr bool Intersects(Interval horizontalBounds) const noexcept {
return (right > horizontalBounds.left) && (left < horizontalBounds.right);
}
void Move(XYPOSITION xDelta, XYPOSITION yDelta) noexcept {
left += xDelta;
top += yDelta;
@ -119,6 +126,10 @@ public:
bottom += yDelta;
}
PRectangle WithHorizontalBounds(Interval horizontal) const noexcept {
return PRectangle(horizontal.left, top, horizontal.right, bottom);
}
constexpr PRectangle Inset(XYPOSITION delta) const noexcept {
return PRectangle(left + delta, top + delta, right - delta, bottom - delta);
}
@ -200,16 +211,18 @@ public:
// Red, green and blue values as bytes 0..255
constexpr unsigned char GetRed() const noexcept {
return co & 0xff;
return co & 0xffU;
}
constexpr unsigned char GetGreen() const noexcept {
return (co >> 8) & 0xff;
return (co >> 8) & 0xffU;
}
constexpr unsigned char GetBlue() const noexcept {
return (co >> 16) & 0xff;
return (co >> 16) & 0xffU;
}
constexpr unsigned char GetAlpha() const noexcept {
return (co >> 24) & 0xff;
// Use a temporary here to prevent a 'Wconversion' warning from GCC
const int shifted = co >> 24;
return shifted & 0xffU;
}
// Red, green, blue, and alpha values as float 0..1.0

View File

@ -376,15 +376,15 @@ void MarginView::PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOn
char number[100] = "";
if (FlagSet(model.foldFlags, FoldFlag::LevelNumbers)) {
const FoldLevel lev = model.pdoc->GetFoldLevel(lineDoc);
sprintf(number, "%c%c %03X %03X",
snprintf(number,std::size(number), "%c%c %03X %03X",
LevelIsHeader(lev) ? 'H' : '_',
LevelIsWhitespace(lev) ? 'W' : '_',
LevelNumber(lev),
static_cast<int>(lev) >> 16
static_cast<unsigned int>(lev) >> 16
);
} else {
const int state = model.pdoc->GetLineState(lineDoc);
sprintf(number, "%0X", state);
snprintf(number, std::size(number), "%0X", state);
}
sNumber = number;
}

View File

@ -263,11 +263,28 @@ int LineLevels::SetLevel(Sci::Line line, int level, Sci::Line lines) {
}
int LineLevels::GetLevel(Sci::Line line) const noexcept {
if (levels.Length() && (line >= 0) && (line < levels.Length())) {
if ((line >= 0) && (line < levels.Length())) {
return levels[line];
} else {
return static_cast<int>(Scintilla::FoldLevel::Base);
}
return static_cast<int>(Scintilla::FoldLevel::Base);
}
Scintilla::FoldLevel LineLevels::GetFoldLevel(Sci::Line line) const noexcept {
if ((line >= 0) && (line < levels.Length())) {
return static_cast<FoldLevel>(levels[line]);
}
return Scintilla::FoldLevel::Base;
}
Sci::Line LineLevels::GetFoldParent(Sci::Line line) const noexcept {
const FoldLevel level = LevelNumberPart(GetFoldLevel(line));
for (Sci::Line lineLook = line - 1; lineLook >= 0; lineLook--) {
const FoldLevel levelTry = GetFoldLevel(lineLook);
if (LevelIsHeader(levelTry) && LevelNumberPart(levelTry) < level) {
return lineLook;
}
}
return -1;
}
void LineState::Init() {

View File

@ -75,6 +75,8 @@ public:
void ClearLevels();
int SetLevel(Sci::Line line, int level, Sci::Line lines);
int GetLevel(Sci::Line line) const noexcept;
FoldLevel GetFoldLevel(Sci::Line line) const noexcept;
Sci::Line GetFoldParent(Sci::Line line) const noexcept;
};
class LineState : public PerLine {

View File

@ -51,6 +51,7 @@
#include "CaseFolder.h"
#include "Document.h"
#include "UniConversion.h"
#include "DBCS.h"
#include "Selection.h"
#include "PositionCache.h"
@ -314,10 +315,76 @@ XYPOSITION LineLayout::XInLine(Sci::Position index) const noexcept {
return positions[numCharsInLine] + 1.0;
}
Interval LineLayout::Span(int start, int end) const noexcept {
return { positions[start], positions[end] };
}
Interval LineLayout::SpanByte(int index) const noexcept {
return Span(index, index+1);
}
int LineLayout::EndLineStyle() const noexcept {
return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0];
}
void LineLayout::WrapLine(const Document *pdoc, Sci::Position posLineStart, Wrap wrapState, XYPOSITION wrapWidth) {
// Document wants document positions but simpler to work in line positions
// so take care of adding and subtracting line start in a lambda.
auto CharacterBoundary = [=](Sci::Position i, Sci::Position moveDir) noexcept -> Sci::Position {
return pdoc->MovePositionOutsideChar(i + posLineStart, moveDir) - posLineStart;
};
lines = 0;
// Calculate line start positions based upon width.
Sci::Position lastLineStart = 0;
XYPOSITION startOffset = wrapWidth;
Sci::Position p = 0;
while (p < numCharsInLine) {
while (p < numCharsInLine && positions[p + 1] < startOffset) {
p++;
}
if (p < numCharsInLine) {
// backtrack to find lastGoodBreak
Sci::Position lastGoodBreak = p;
if (p > 0) {
lastGoodBreak = CharacterBoundary(p, -1);
}
if (wrapState != Wrap::Char) {
Sci::Position pos = lastGoodBreak;
while (pos > lastLineStart) {
// style boundary and space
if (wrapState != Wrap::WhiteSpace && (styles[pos - 1] != styles[pos])) {
break;
}
if (IsBreakSpace(chars[pos - 1]) && !IsBreakSpace(chars[pos])) {
break;
}
pos = CharacterBoundary(pos - 1, -1);
}
if (pos > lastLineStart) {
lastGoodBreak = pos;
}
}
if (lastGoodBreak == lastLineStart) {
// Try moving to start of last character
if (p > 0) {
lastGoodBreak = CharacterBoundary(p, -1);
}
if (lastGoodBreak == lastLineStart) {
// Ensure at least one character on line.
lastGoodBreak = CharacterBoundary(lastGoodBreak + 1, 1);
}
}
lastLineStart = lastGoodBreak;
AddLineStart(lastLineStart);
startOffset = positions[lastLineStart];
// take into account the space for start wrap mark and indent
startOffset += wrapWidth - wrapIndent;
p = lastLineStart + 1;
}
}
lines++;
}
ScreenLine::ScreenLine(
const LineLayout *ll_,
int subLine,
@ -508,21 +575,21 @@ std::shared_ptr<LineLayout> LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci:
size_t pos = 0;
if (level == LineCache::Page) {
// If first entry is this line then just reuse it.
if (!(cache[0] && (cache[0]->lineNumber == lineNumber))) {
if (!(cache[0] && (cache[0]->LineNumber() == lineNumber))) {
const size_t posForLine = EntryForLine(lineNumber);
if (lineNumber == lineCaret) {
// Use position 0 for caret line.
if (cache[0]) {
// Another line is currently in [0] so move it out to its normal position.
// Since it was recently the caret line its likely to be needed soon.
const size_t posNewForEntry0 = EntryForLine(cache[0]->lineNumber);
const size_t posNewForEntry0 = EntryForLine(cache[0]->LineNumber());
if (posForLine == posNewForEntry0) {
std::swap(cache[0], cache[posNewForEntry0]);
} else {
cache[posNewForEntry0] = std::move(cache[0]);
}
}
if (cache[posForLine] && (cache[posForLine]->lineNumber == lineNumber)) {
if (cache[posForLine] && (cache[posForLine]->LineNumber() == lineNumber)) {
// Caret line is currently somewhere else so move it to [0].
cache[0] = std::move(cache[posForLine]);
}
@ -572,6 +639,40 @@ constexpr unsigned int KeyFromString(std::string_view charBytes) noexcept {
constexpr unsigned int representationKeyCrLf = KeyFromString("\r\n");
const char *const repsC0[] = {
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
};
const char *const repsC1[] = {
"PAD", "HOP", "BPH", "NBH", "IND", "NEL", "SSA", "ESA",
"HTS", "HTJ", "VTS", "PLD", "PLU", "RI", "SS2", "SS3",
"DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA",
"SOS", "SGCI", "SCI", "CSI", "ST", "OSC", "PM", "APC"
};
}
namespace Scintilla::Internal {
const char *ControlCharacterString(unsigned char ch) noexcept {
if (ch < std::size(repsC0)) {
return repsC0[ch];
} else {
return "BAD";
}
}
void Hexits(char *hexits, int ch) noexcept {
hexits[0] = 'x';
hexits[1] = "0123456789ABCDEF"[ch / 0x10];
hexits[2] = "0123456789ABCDEF"[ch % 0x10];
hexits[3] = 0;
}
}
void SpecialRepresentations::SetRepresentation(std::string_view charBytes, std::string_view value) {
@ -665,6 +766,40 @@ void SpecialRepresentations::Clear() {
crlf = false;
}
void SpecialRepresentations::SetDefaultRepresentations(int dbcsCodePage) {
Clear();
// C0 control set
for (size_t j = 0; j < std::size(repsC0); j++) {
const char c[2] = { static_cast<char>(j), 0 };
SetRepresentation(std::string_view(c, 1), repsC0[j]);
}
SetRepresentation("\x7f", "DEL");
// C1 control set
// As well as Unicode mode, ISO-8859-1 should use these
if (CpUtf8 == dbcsCodePage) {
for (size_t j = 0; j < std::size(repsC1); j++) {
const char c1[3] = { '\xc2', static_cast<char>(0x80 + j), 0 };
SetRepresentation(c1, repsC1[j]);
}
SetRepresentation("\xe2\x80\xa8", "LS");
SetRepresentation("\xe2\x80\xa9", "PS");
}
// Invalid as single bytes in multi-byte encodings
if (dbcsCodePage) {
for (int k = 0x80; k < 0x100; k++) {
if ((CpUtf8 == dbcsCodePage) || !IsDBCSValidSingleByte(dbcsCodePage, k)) {
const char hiByte[2] = { static_cast<char>(k), 0 };
char hexits[4];
Hexits(hexits, k);
SetRepresentation(hiByte, hexits);
}
}
}
}
void BreakFinder::Insert(Sci::Position val) {
const int posInLine = static_cast<int>(val);
if (posInLine > nextBreak) {
@ -753,12 +888,28 @@ TextSegment BreakFinder::Next() {
int charWidth = 1;
const char * const chars = &ll->chars[nextBreak];
const unsigned char ch = chars[0];
bool characterStyleConsistent = true; // All bytes of character in same style?
if (!UTF8IsAscii(ch) && encodingFamily != EncodingFamily::eightBit) {
if (encodingFamily == EncodingFamily::unicode) {
charWidth = UTF8DrawBytes(chars, lineRange.end - nextBreak);
} else {
charWidth = pdoc->DBCSDrawBytes(std::string_view(chars, lineRange.end - nextBreak));
}
for (int trail = 1; trail < charWidth; trail++) {
if (ll->styles[nextBreak] != ll->styles[nextBreak + trail]) {
characterStyleConsistent = false;
}
}
}
if (!characterStyleConsistent) {
if (nextBreak == prev) {
// Show first character representation bytes since it has inconsistent styles.
charWidth = 1;
} else {
// Return segment before nextBreak but allow to be split up if too long
// If not split up, next call will hit the above 'charWidth = 1;' and display bytes.
break;
}
}
repr = nullptr;
if (preprs->MayContain(ch)) {
@ -818,6 +969,7 @@ class PositionCacheEntry {
uint16_t styleNumber;
uint16_t len;
uint16_t clock;
bool unicode;
std::unique_ptr<XYPOSITION[]> positions;
public:
PositionCacheEntry() noexcept;
@ -828,10 +980,10 @@ public:
void operator=(const PositionCacheEntry &) = delete;
void operator=(PositionCacheEntry &&) = delete;
~PositionCacheEntry();
void Set(unsigned int styleNumber_, std::string_view sv, const XYPOSITION *positions_, uint16_t clock_);
void Set(unsigned int styleNumber_, bool unicode_, std::string_view sv, const XYPOSITION *positions_, uint16_t clock_);
void Clear() noexcept;
bool Retrieve(unsigned int styleNumber_, std::string_view sv, XYPOSITION *positions_) const noexcept;
static size_t Hash(unsigned int styleNumber_, std::string_view sv) noexcept;
bool Retrieve(unsigned int styleNumber_, bool unicode_, std::string_view sv, XYPOSITION *positions_) const noexcept;
static size_t Hash(unsigned int styleNumber_, bool unicode_, std::string_view sv) noexcept;
bool NewerThan(const PositionCacheEntry &other) const noexcept;
void ResetClock() noexcept;
};
@ -854,16 +1006,16 @@ public:
void SetSize(size_t size_) override;
size_t GetSize() const noexcept override;
void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
std::string_view sv, XYPOSITION *positions, bool needsLocking) override;
bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) override;
};
PositionCacheEntry::PositionCacheEntry() noexcept :
styleNumber(0), len(0), clock(0) {
styleNumber(0), len(0), clock(0), unicode(false) {
}
// Copy constructor not currently used, but needed for being element in std::vector.
PositionCacheEntry::PositionCacheEntry(const PositionCacheEntry &other) :
styleNumber(other.styleNumber), len(other.len), clock(other.clock) {
styleNumber(other.styleNumber), len(other.len), clock(other.clock), unicode(other.unicode) {
if (other.positions) {
const size_t lenData = len + (len / sizeof(XYPOSITION)) + 1;
positions = std::make_unique<XYPOSITION[]>(lenData);
@ -871,12 +1023,13 @@ PositionCacheEntry::PositionCacheEntry(const PositionCacheEntry &other) :
}
}
void PositionCacheEntry::Set(unsigned int styleNumber_, std::string_view sv,
void PositionCacheEntry::Set(unsigned int styleNumber_, bool unicode_, std::string_view sv,
const XYPOSITION *positions_, uint16_t clock_) {
Clear();
styleNumber = static_cast<uint16_t>(styleNumber_);
len = static_cast<uint16_t>(sv.length());
clock = clock_;
unicode = unicode_;
if (sv.data() && positions_) {
positions = std::make_unique<XYPOSITION[]>(len + (len / sizeof(XYPOSITION)) + 1);
for (unsigned int i=0; i<len; i++) {
@ -897,8 +1050,8 @@ void PositionCacheEntry::Clear() noexcept {
clock = 0;
}
bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, std::string_view sv, XYPOSITION *positions_) const noexcept {
if ((styleNumber == styleNumber_) && (len == sv.length()) &&
bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, bool unicode_, std::string_view sv, XYPOSITION *positions_) const noexcept {
if ((styleNumber == styleNumber_) && (unicode == unicode_) && (len == sv.length()) &&
(memcmp(&positions[len], sv.data(), sv.length())== 0)) {
for (unsigned int i=0; i<len; i++) {
positions_[i] = positions[i];
@ -909,10 +1062,10 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, std::string_view sv
}
}
size_t PositionCacheEntry::Hash(unsigned int styleNumber_, std::string_view sv) noexcept {
size_t PositionCacheEntry::Hash(unsigned int styleNumber_, bool unicode_, std::string_view sv) noexcept {
const size_t h1 = std::hash<std::string_view>{}(sv);
const size_t h2 = std::hash<unsigned int>{}(styleNumber_);
return h1 ^ (h2 << 1);
return h1 ^ (h2 << 1) ^ static_cast<size_t>(unicode_);
}
bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const noexcept {
@ -951,7 +1104,7 @@ size_t PositionCache::GetSize() const noexcept {
}
void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
std::string_view sv, XYPOSITION *positions, bool needsLocking) {
bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) {
const Style &style = vstyle.styles[styleNumber];
if (style.monospaceASCII) {
if (AllGraphicASCII(sv)) {
@ -969,17 +1122,17 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns
// long comments with only a single comment.
// Two way associative: try two probe positions.
const size_t hashValue = PositionCacheEntry::Hash(styleNumber, sv);
const size_t hashValue = PositionCacheEntry::Hash(styleNumber, unicode, sv);
probe = hashValue % pces.size();
std::unique_lock<std::mutex> guard(mutex, std::defer_lock);
if (needsLocking) {
guard.lock();
}
if (pces[probe].Retrieve(styleNumber, sv, positions)) {
if (pces[probe].Retrieve(styleNumber, unicode, sv, positions)) {
return;
}
const size_t probe2 = (hashValue * 37) % pces.size();
if (pces[probe2].Retrieve(styleNumber, sv, positions)) {
if (pces[probe2].Retrieve(styleNumber, unicode, sv, positions)) {
return;
}
// Not found. Choose the oldest of the two slots to replace
@ -989,7 +1142,11 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns
}
const Font *fontStyle = style.font.get();
surface->MeasureWidths(fontStyle, sv, positions);
if (unicode) {
surface->MeasureWidthsUTF8(fontStyle, sv, positions);
} else {
surface->MeasureWidths(fontStyle, sv, positions);
}
if (probe < pces.size()) {
// Store into cache
std::unique_lock<std::mutex> guard(mutex, std::defer_lock);
@ -1006,7 +1163,7 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns
clock = 2;
}
allClear = false;
pces[probe].Set(styleNumber, sv, positions, clock);
pces[probe].Set(styleNumber, unicode, sv, positions, clock);
}
}

View File

@ -48,7 +48,6 @@ public:
*/
class LineLayout {
private:
friend class LineLayoutCache;
std::unique_ptr<int []>lineStarts;
int lenLineStarts;
/// Drawing is only performed for @a maxLineLength characters on each line.
@ -105,7 +104,10 @@ public:
int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const noexcept;
Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept;
XYPOSITION XInLine(Sci::Position index) const noexcept;
Interval Span(int start, int end) const noexcept;
Interval SpanByte(int index) const noexcept;
int EndLineStyle() const noexcept;
void WrapLine(const Document *pdoc, Sci::Position posLineStart, Wrap wrapState, XYPOSITION wrapWidth);
};
struct ScreenLine : public IScreenLine {
@ -179,6 +181,9 @@ public:
typedef std::map<unsigned int, Representation> MapRepresentation;
const char *ControlCharacterString(unsigned char ch) noexcept;
void Hexits(char *hexits, int ch) noexcept;
class SpecialRepresentations {
MapRepresentation mapReprs;
unsigned short startByteHasReprs[0x100] {};
@ -198,6 +203,7 @@ public:
return startByteHasReprs[ch] != 0;
}
void Clear();
void SetDefaultRepresentations(int dbcsCodePage);
};
struct TextSegment {
@ -256,7 +262,7 @@ public:
virtual void SetSize(size_t size_) = 0;
virtual size_t GetSize() const noexcept = 0;
virtual void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber,
std::string_view sv, XYPOSITION *positions, bool needsLocking) = 0;
bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) = 0;
};
std::unique_ptr<IPositionCache> CreatePositionCache();

View File

@ -78,11 +78,12 @@ void ScintillaBase::Finalise() {
}
void ScintillaBase::InsertCharacter(std::string_view sv, CharacterSource charSource) {
const bool isFillUp = ac.Active() && ac.IsFillUpChar(sv[0]);
const bool acActive = ac.Active();
const bool isFillUp = acActive && ac.IsFillUpChar(sv[0]);
if (!isFillUp) {
Editor::InsertCharacter(sv, charSource);
}
if (ac.Active()) {
if (acActive && ac.Active()) { // if it was and still is active
AutoCompleteCharacterAdded(sv[0]);
// For fill ups add the character after the autocompletion has
// triggered so containers see the key so can display a calltip.
@ -590,7 +591,6 @@ public:
void PropSet(const char *key, const char *val);
const char *PropGet(const char *key) const;
int PropGetInt(const char *key, int defaultValue=0) const;
size_t PropGetExpanded(const char *key, char *result) const;
LineEndType LineEndTypesSupported() override;
int AllocateSubStyles(int styleBase, int numberStyles);
@ -710,20 +710,6 @@ int LexState::PropGetInt(const char *key, int defaultValue) const {
return defaultValue;
}
size_t LexState::PropGetExpanded(const char *key, char *result) const {
if (instance) {
const char *value = instance->PropertyGet(key);
if (value) {
size_t const len = strlen(value);
if (result) {
strcpy_s(result, len, value);
}
return len;
}
}
return 0;
}
LineEndType LexState::LineEndTypesSupported() {
if (instance) {
return static_cast<LineEndType>(instance->LineEndTypesSupported());
@ -1065,8 +1051,7 @@ sptr_t ScintillaBase::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
return StringResult(lParam, DocumentLexState()->PropGet(ConstCharPtrFromUPtr(wParam)));
case Message::GetPropertyExpanded:
return DocumentLexState()->PropGetExpanded(ConstCharPtrFromUPtr(wParam),
CharPtrFromSPtr(lParam));
return StringResult(lParam, DocumentLexState()->PropGet(ConstCharPtrFromUPtr(wParam)));
case Message::GetPropertyInt:
return DocumentLexState()->PropGetInt(ConstCharPtrFromUPtr(wParam), static_cast<int>(lParam));

View File

@ -81,6 +81,12 @@ struct SelectionSegment {
if (end < p)
end = p;
}
SelectionSegment Subtract(Sci::Position increment) const noexcept {
SelectionSegment ret(start, end);
ret.start.Add(-increment);
ret.end.Add(-increment);
return ret;
}
};
struct SelectionRange {

View File

@ -239,6 +239,14 @@ RGBAImage::RGBAImage(const XPM &xpm) {
}
}
float RGBAImage::GetScaledHeight() const noexcept {
return static_cast<float>(height) / scale;
}
float RGBAImage::GetScaledWidth() const noexcept {
return static_cast<float>(width) / scale;
}
int RGBAImage::CountBytes() const noexcept {
return width * height * 4;
}
@ -256,15 +264,23 @@ void RGBAImage::SetPixel(int x, int y, ColourRGBA colour) noexcept {
pixel[3] = colour.GetAlpha();
}
namespace {
unsigned char AlphaMultiplied(unsigned char value, unsigned char alpha) {
return (value * alpha / UCHAR_MAX) & 0xffU;
}
}
// Transform a block of pixels from RGBA to BGRA with premultiplied alpha.
// Used for DrawRGBAImage on some platforms.
void RGBAImage::BGRAFromRGBA(unsigned char *pixelsBGRA, const unsigned char *pixelsRGBA, size_t count) noexcept {
for (size_t i = 0; i < count; i++) {
const unsigned char alpha = pixelsRGBA[3];
// Input is RGBA, output is BGRA with premultiplied alpha
pixelsBGRA[2] = pixelsRGBA[0] * alpha / UCHAR_MAX;
pixelsBGRA[1] = pixelsRGBA[1] * alpha / UCHAR_MAX;
pixelsBGRA[0] = pixelsRGBA[2] * alpha / UCHAR_MAX;
pixelsBGRA[2] = AlphaMultiplied(pixelsRGBA[0], alpha);
pixelsBGRA[1] = AlphaMultiplied(pixelsRGBA[1], alpha);
pixelsBGRA[0] = AlphaMultiplied(pixelsRGBA[2], alpha);
pixelsBGRA[3] = alpha;
pixelsRGBA += bytesPerPixel;
pixelsBGRA += bytesPerPixel;

View File

@ -51,8 +51,8 @@ public:
int GetHeight() const noexcept { return height; }
int GetWidth() const noexcept { return width; }
float GetScale() const noexcept { return scale; }
float GetScaledHeight() const noexcept { return height / scale; }
float GetScaledWidth() const noexcept { return width / scale; }
float GetScaledHeight() const noexcept;
float GetScaledWidth() const noexcept;
int CountBytes() const noexcept;
const unsigned char *Pixels() const noexcept;
void SetPixel(int x, int y, ColourRGBA colour) noexcept;

View File

@ -1 +1 @@
532
533

View File

@ -4084,7 +4084,7 @@ void Platform::DebugPrintf(const char *format, ...) noexcept {
char buffer[2000];
va_list pArguments;
va_start(pArguments, format);
vsprintf_s(buffer,format,pArguments);
vsnprintf(buffer, std::size(buffer), format, pArguments);
va_end(pArguments);
Platform::DebugDisplay(buffer);
}
@ -4103,7 +4103,7 @@ bool Platform::ShowAssertionPopUps(bool assertionPopUps_) noexcept {
void Platform::Assert(const char *c, const char *file, int line) noexcept {
char buffer[2000] {};
sprintf(buffer, "Assertion [%s] failed at %s %d%s", c, file, line, assertionPopUps ? "" : "\r\n");
snprintf(buffer, std::size(buffer), "Assertion [%s] failed at %s %d%s", c, file, line, assertionPopUps ? "" : "\r\n");
if (assertionPopUps) {
const int idButton = ::MessageBoxA(0, buffer, "Assertion failure",
MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);

View File

@ -6,8 +6,8 @@
#include <windows.h>
#define VERSION_SCINTILLA "5.3.2"
#define VERSION_WORDS 5, 3, 2, 0
#define VERSION_SCINTILLA "5.3.3"
#define VERSION_WORDS 5, 3, 3, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_WORDS

View File

@ -373,6 +373,7 @@ $(DIR_O)/PositionCache.o: \
../src/CaseFolder.h \
../src/Document.h \
../src/UniConversion.h \
../src/DBCS.h \
../src/Selection.h \
../src/PositionCache.h
$(DIR_O)/RESearch.o: \

View File

@ -19,7 +19,6 @@ WARNINGS = -Wpedantic -Wall -Wextra
ifdef CLANG
CXX = clang++
DEFINES += -D_CRT_SECURE_NO_DEPRECATE
else
# MinGW GCC
LIBSMINGW = -lstdc++

View File

@ -373,6 +373,7 @@ $(DIR_O)/PositionCache.obj: \
../src/CaseFolder.h \
../src/Document.h \
../src/UniConversion.h \
../src/DBCS.h \
../src/Selection.h \
../src/PositionCache.h
$(DIR_O)/RESearch.obj: \

View File

@ -35,7 +35,7 @@ SUBSYSTEM=-SUBSYSTEM:WINDOWS,10.00
!ENDIF
!ENDIF
CRTFLAGS=-D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 -D_CRT_SECURE_NO_DEPRECATE=1 -D_SCL_SECURE_NO_WARNINGS=1 $(ADD_DEFINE)
CRTFLAGS=$(ADD_DEFINE)
CXXFLAGS=-Zi -TP -MP -W4 -EHsc -std:c++17 $(CRTFLAGS)
CXXDEBUG=-Od -MTd -DDEBUG
CXXNDEBUG=-O2 -MT -DNDEBUG -GL

View File

@ -1,4 +1,6 @@
cd ..
del/q scintilla.zip
zip scintilla.zip scintilla\*.* scintilla\*\*.* scintilla\*\*\*.* scintilla\*\*\*\*.* scintilla\*\*\*\*\*.* -x *.o -x *.obj -x *.dll -x *.lib -x *.res -x *.exp
zip scintilla.zip scintilla\*.* scintilla\*\*.* scintilla\*\*\*.* scintilla\*\*\*\*.* scintilla\*\*\*\*\*.* ^
-x *.o *.obj *.dll *.lib *.res *.exp *.bak *.tgz ^
**/__pycache__/* **/Debug/* **/Release/* **/x64/* **/ARM64/* **/cov-int/* */.hg/* @
cd scintilla