Branch: refs/heads/master Author: Thomas Martitz thomas.martitz@mailbox.org Committer: Thomas Martitz thomas.martitz@mailbox.org Date: Mon, 15 Nov 2021 06:46:40 UTC Commit: fb7ab270d9e20b2d39f1d14b9a45c6967e691a84 https://github.com/geany/geany/commit/fb7ab270d9e20b2d39f1d14b9a45c6967e691a...
Log Message: ----------- Update to Scintilla 5.1.4 and Lexilla 5.1.3
Scintilla: - On GTK, fix primary selection paste within same instance. Bug #2287. - On GTK, fix potential crash when closing Scintilla instances due to releasing global settings object.
Lexilla: - Various Rust fixes
Modified Paths: -------------- scintilla/gtk/PlatGTK.cxx scintilla/gtk/ScintillaGTK.cxx scintilla/gtk/ScintillaGTK.h scintilla/include/Scintilla.h scintilla/include/Scintilla.iface scintilla/include/ScintillaCall.h scintilla/include/ScintillaTypes.h scintilla/lexilla/lexers/LexPython.cxx scintilla/lexilla/lexers/LexRust.cxx scintilla/lexilla/lexlib/Accessor.h scintilla/lexilla/lexlib/LexerBase.cxx scintilla/lexilla/lexlib/WordList.cxx scintilla/lexilla/version.txt scintilla/src/CellBuffer.cxx scintilla/src/CharClassify.cxx scintilla/src/CharacterType.h scintilla/src/ContractionState.cxx scintilla/src/Document.cxx scintilla/src/Document.h scintilla/src/EditView.cxx scintilla/src/Editor.cxx scintilla/src/KeyMap.cxx scintilla/src/MarginView.cxx scintilla/src/MarginView.h scintilla/src/PerLine.cxx scintilla/src/PositionCache.cxx scintilla/src/PositionCache.h scintilla/src/ViewStyle.cxx scintilla/src/ViewStyle.h scintilla/src/XPM.cxx scintilla/src/XPM.h scintilla/version.txt
Modified: scintilla/gtk/PlatGTK.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -114,7 +114,7 @@ class FontHandle : public Font { FontHandle(FontHandle &&) = delete; FontHandle &operator=(const FontHandle &) = delete; FontHandle &operator=(FontHandle &&) = delete; - ~FontHandle() { + ~FontHandle() override { if (pfd) pango_font_description_free(pfd); pfd = nullptr;
Modified: scintilla/gtk/ScintillaGTK.cxx 26 lines changed, 13 insertions(+), 13 deletions(-) =================================================================== @@ -282,9 +282,6 @@ ScintillaGTK::~ScintillaGTK() { if (settingsHandlerId) { g_signal_handler_disconnect(settings, settingsHandlerId); } - if (settings) { - g_object_unref(settings); - } }
void ScintillaGTK::RealizeThis(GtkWidget *widget) { @@ -1303,7 +1300,7 @@ struct CaseMapper { }
std::string ScintillaGTK::CaseMapString(const std::string &s, CaseMapping caseMapping) { - if ((s.size() == 0) || (caseMapping == CaseMapping::same)) + if (s.empty() || (caseMapping == CaseMapping::same)) return s;
if (IsUnicodeMode()) { @@ -1566,20 +1563,26 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio
void ScintillaGTK::InsertSelection(GtkClipboard *clipBoard, GtkSelectionData *selectionData) { const gint length = gtk_selection_data_get_length(selectionData); + const GdkAtom selection = gtk_selection_data_get_selection(selectionData); if (length >= 0) { - GdkAtom selection = gtk_selection_data_get_selection(selectionData); SelectionText selText; GetGtkSelectionText(selectionData, selText);
UndoGroup ug(pdoc); if (selection == GDK_SELECTION_CLIPBOARD) { ClearSelection(multiPasteMode == MultiPaste::Each); } + if (selection == GDK_SELECTION_PRIMARY) { + SetSelection(posPrimary, posPrimary); + }
InsertPasteShape(selText.Data(), selText.Length(), selText.rectangular ? PasteShape::rectangular : PasteShape::stream); EnsureCaretVisible(); } else { + if (selection == GDK_SELECTION_PRIMARY) { + SetSelection(posPrimary, posPrimary); + } GdkAtom target = gtk_selection_data_get_target(selectionData); if (target == atomUTF8) { // In case data is actually only stored as text/plain;charset=utf-8 not UTF8_STRING @@ -1653,7 +1656,7 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se std::unique_ptr<SelectionText> newline_normalized; { std::string tmpstr = Document::TransformLineEnds(text->Data(), text->Length(), EndOfLine::Lf); - newline_normalized.reset(new SelectionText()); + newline_normalized = std::make_unique<SelectionText>(); newline_normalized->Copy(tmpstr, CpUtf8, CharacterSet::Ansi, text->rectangular, false); text = newline_normalized.get(); } @@ -1880,12 +1883,11 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) { ButtonDownWithModifiers(pt, event->time, ModifierFlags(shift, ctrl, alt, meta)); } else if (event->button == 2) { // Grab the primary selection if it exists - const SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace()); + posPrimary = SPositionFromLocation(pt, false, false, UserVirtualSpace()); if (OwnPrimarySelection() && primary.Empty()) CopySelectionRange(&primary);
sel.Clear(); - SetSelection(pos, pos); RequestSelection(GDK_SELECTION_PRIMARY); } else if (event->button == 3) { if (!PointInSelection(pt)) @@ -2449,7 +2451,7 @@ std::vector<int> MapImeIndicators(PangoAttrList *attrs, const char *u8Str) { void ScintillaGTK::SetCandidateWindowPos() { // Composition box accompanies candidate box. const Point pt = PointMainCaret(); - GdkRectangle imeBox = {0}; // No need to set width + GdkRectangle imeBox {}; imeBox.x = static_cast<gint>(pt.x); imeBox.y = static_cast<gint>(pt.y + std::max(4, vs.lineHeight/4)); // prevent overlapping with current line @@ -3011,7 +3013,7 @@ gboolean ScintillaGTK::IdleCallback(gpointer pSci) { // Idler will be automatically stopped, if there is nothing // to do while idle. const bool ret = sciThis->Idle(); - if (ret == false) { + if (!ret) { // FIXME: This will remove the idler from GTK, we don't want to // remove it as it is removed automatically when this function // returns false (although, it should be harmless). @@ -3047,9 +3049,7 @@ void ScintillaGTK::SetDocPointer(Document *document) { sciAccessible = ScintillaGTKAccessible::FromAccessible(accessible); if (sciAccessible && pdoc) { oldDoc = pdoc; - if (oldDoc) { - oldDoc->AddRef(); - } + oldDoc->AddRef(); } }
Modified: scintilla/gtk/ScintillaGTK.h 3 lines changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -34,6 +34,7 @@ class ScintillaGTK : public ScintillaBase { int horizontalScrollBarHeight;
SelectionText primary; + SelectionPosition posPrimary;
GdkEvent *evbtn; guint buttonMouse; @@ -92,7 +93,7 @@ class ScintillaGTK : public ScintillaBase { ScintillaGTK(ScintillaGTK &&) = delete; ScintillaGTK &operator=(const ScintillaGTK &) = delete; ScintillaGTK &operator=(ScintillaGTK &&) = delete; - virtual ~ScintillaGTK(); + ~ScintillaGTK() override; static ScintillaGTK *FromWidget(GtkWidget *widget) noexcept; static void ClassInit(OBJECT_CLASS *object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class); private:
Modified: scintilla/include/Scintilla.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -907,6 +907,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define CARETSTYLE_BLOCK 2 #define CARETSTYLE_OVERSTRIKE_BAR 0 #define CARETSTYLE_OVERSTRIKE_BLOCK 0x10 +#define CARETSTYLE_CURSES 0x20 #define CARETSTYLE_INS_MASK 0xF #define CARETSTYLE_BLOCK_AFTER 0x100 #define SCI_SETCARETSTYLE 2512
Modified: scintilla/include/Scintilla.iface 3 lines changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -2489,6 +2489,7 @@ val CARETSTYLE_LINE=1 val CARETSTYLE_BLOCK=2 val CARETSTYLE_OVERSTRIKE_BAR=0 val CARETSTYLE_OVERSTRIKE_BLOCK=0x10 +val CARETSTYLE_CURSES=0x20 val CARETSTYLE_INS_MASK=0xF val CARETSTYLE_BLOCK_AFTER=0x100
@@ -3127,7 +3128,7 @@ fun int DescribeKeyWordSets=4017(, stringresult descriptions)
# Bit set of LineEndType enumertion for which line ends beyond the standard # LF, CR, and CRLF are supported by the lexer. -get int GetLineEndTypesSupported=4018(,) +get LineEndType GetLineEndTypesSupported=4018(,)
# Allocate a set of sub styles for a particular base style, returning start of range fun int AllocateSubStyles=4020(int styleBase, int numberStyles)
Modified: scintilla/include/ScintillaCall.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -854,7 +854,7 @@ class ScintillaCall { std::string DescribeProperty(const char *name); int DescribeKeyWordSets(char *descriptions); std::string DescribeKeyWordSets(); - int LineEndTypesSupported(); + Scintilla::LineEndType LineEndTypesSupported(); int AllocateSubStyles(int styleBase, int numberStyles); int SubStylesStart(int styleBase); int SubStylesLength(int styleBase);
Modified: scintilla/include/ScintillaTypes.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -439,6 +439,7 @@ enum class CaretStyle { Block = 2, OverstrikeBar = 0, OverstrikeBlock = 0x10, + Curses = 0x20, InsMask = 0xF, BlockAfter = 0x100, };
Modified: scintilla/lexilla/lexers/LexPython.cxx 21 lines changed, 11 insertions(+), 10 deletions(-) =================================================================== @@ -71,7 +71,7 @@ bool IsPyComment(Accessor &styler, Sci_Position pos, Sci_Position len) { return len > 0 && styler[pos] == '#'; }
-bool IsPyStringTypeChar(int ch, literalsAllowed allowed) noexcept { +constexpr bool IsPyStringTypeChar(int ch, literalsAllowed allowed) noexcept { return ((allowed & litB) && (ch == 'b' || ch == 'B')) || ((allowed & litU) && (ch == 'u' || ch == 'U')) || @@ -93,17 +93,17 @@ bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) n return false; }
-bool IsPyFStringState(int st) noexcept { +constexpr bool IsPyFStringState(int st) noexcept { return ((st == SCE_P_FCHARACTER) || (st == SCE_P_FSTRING) || (st == SCE_P_FTRIPLE) || (st == SCE_P_FTRIPLEDOUBLE)); }
-bool IsPySingleQuoteStringState(int st) noexcept { +constexpr bool IsPySingleQuoteStringState(int st) noexcept { return ((st == SCE_P_CHARACTER) || (st == SCE_P_STRING) || (st == SCE_P_FCHARACTER) || (st == SCE_P_FSTRING)); }
-bool IsPyTripleQuoteStringState(int st) noexcept { +constexpr bool IsPyTripleQuoteStringState(int st) noexcept { return ((st == SCE_P_TRIPLE) || (st == SCE_P_TRIPLEDOUBLE) || (st == SCE_P_FTRIPLE) || (st == SCE_P_FTRIPLEDOUBLE)); } @@ -232,7 +232,7 @@ struct OptionsPython { bool foldCompact; bool unicodeIdentifiers;
- OptionsPython() { + OptionsPython() noexcept { whingeLevel = 0; base2or8Literals = true; stringsU = true; @@ -436,6 +436,8 @@ Sci_Position SCI_METHOD LexerPython::WordListSet(int n, const char *wl) { case 1: wordListN = &keywords2; break; + default: + break; } Sci_Position firstModification = -1; if (wordListN) { @@ -635,7 +637,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in style = SCE_P_WORD2; } } else { - int subStyle = classifierIdentifiers.ValueFor(s); + const int subStyle = classifierIdentifiers.ValueFor(s); if (subStyle >= 0) { style = subStyle; } @@ -895,8 +897,8 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i const int style = styler.StyleAt(lookAtPos) & 31; quote = options.foldQuotes && IsPyTripleQuoteStringState(style); } - const int quote_start = (quote && !prevQuote); - const int quote_continue = (quote && prevQuote); + const bool quote_start = (quote && !prevQuote); + const bool quote_continue = (quote && prevQuote); if (!quote || !prevQuote) indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; if (quote) @@ -921,8 +923,7 @@ void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, i int minCommentLevel = indentCurrentLevel; while (!quote && (lineNext < docLines) && - ((indentNext & SC_FOLDLEVELWHITEFLAG) || - (lineNext <= docLines && IsCommentLine(lineNext, styler)))) { + ((indentNext & SC_FOLDLEVELWHITEFLAG) || (IsCommentLine(lineNext, styler)))) {
if (IsCommentLine(lineNext, styler) && indentNext < minCommentLevel) { minCommentLevel = indentNext;
Modified: scintilla/lexilla/lexers/LexRust.cxx 12 lines changed, 5 insertions(+), 7 deletions(-) =================================================================== @@ -286,6 +286,8 @@ static void ScanNumber(Accessor& styler, Sci_Position& pos) { pos += 2; } else if (c == '6' && n == '4') { pos += 2; + } else if (styler.Match(pos, "128")) { + pos += 3; } else if (styler.Match(pos, "size")) { pos += 4; } else { @@ -524,7 +526,7 @@ static void ResumeBlockComment(Accessor &styler, Sci_Position& pos, Sci_Position level++; } } - else { + else if (pos < max) { pos++; } if (pos >= max) { @@ -557,12 +559,8 @@ static void ResumeLineComment(Accessor &styler, Sci_Position& pos, Sci_Position maybe_doc_comment = true; }
- while (pos < max && c != '\n') { - if (pos == styler.LineEnd(styler.GetLine(pos))) - styler.SetLineState(styler.GetLine(pos), 0); - pos++; - c = styler.SafeGetCharAt(pos, '\0'); - } + pos = styler.LineEnd(styler.GetLine(pos)); + styler.SetLineState(styler.GetLine(pos), SCE_RUST_DEFAULT);
if (state == DocComment || (state == UnknownComment && maybe_doc_comment)) styler.ColourTo(pos - 1, SCE_RUST_COMMENTLINEDOC);
Modified: scintilla/lexilla/lexlib/Accessor.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -23,7 +23,7 @@ class Accessor : public LexAccessor { PropSetSimple *pprops; Accessor(Scintilla::IDocument *pAccess_, PropSetSimple *pprops_); int GetPropertyInt(std::string_view key, int defaultValue=0) const; - int IndentAmount(Sci_Position line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); + int IndentAmount(Sci_Position line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = nullptr); };
}
Modified: scintilla/lexilla/lexlib/LexerBase.cxx 6 lines changed, 3 insertions(+), 3 deletions(-) =================================================================== @@ -31,15 +31,15 @@ LexerBase::LexerBase(const LexicalClass *lexClasses_, size_t nClasses_) : lexClasses(lexClasses_), nClasses(nClasses_) { for (int wl = 0; wl < numWordLists; wl++) keyWordLists[wl] = new WordList; - keyWordLists[numWordLists] = 0; + keyWordLists[numWordLists] = nullptr; }
LexerBase::~LexerBase() { for (int wl = 0; wl < numWordLists; wl++) { delete keyWordLists[wl]; - keyWordLists[wl] = 0; + keyWordLists[wl] = nullptr; } - keyWordLists[numWordLists] = 0; + keyWordLists[numWordLists] = nullptr; }
void SCI_METHOD LexerBase::Release() {
Modified: scintilla/lexilla/lexlib/WordList.cxx 8 lines changed, 4 insertions(+), 4 deletions(-) =================================================================== @@ -80,7 +80,7 @@ WordList::~WordList() { }
WordList::operator bool() const noexcept { - return len ? true : false; + return len != 0; }
bool WordList::operator!=(const WordList &other) const noexcept { @@ -144,7 +144,7 @@ bool WordList::Set(const char *s) { * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'. */ bool WordList::InList(const char *s) const noexcept { - if (0 == words) + if (!words) return false; const unsigned char firstChar = s[0]; int j = starts[firstChar]; @@ -186,7 +186,7 @@ bool WordList::InList(const char *s) const noexcept { * The marker is ~ in this case. */ bool WordList::InListAbbreviated(const char *s, const char marker) const noexcept { - if (0 == words) + if (!words) return false; const unsigned char firstChar = s[0]; int j = starts[firstChar]; @@ -240,7 +240,7 @@ bool WordList::InListAbbreviated(const char *s, const char marker) const noexcep * No multiple markers check is done and wont work. */ bool WordList::InListAbridged(const char *s, const char marker) const noexcept { - if (0 == words) + if (!words) return false; const unsigned char firstChar = s[0]; int j = starts[firstChar];
Modified: scintilla/lexilla/version.txt 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1 +1 @@ -512 +513
Modified: scintilla/src/CellBuffer.cxx 4 lines changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -37,7 +37,7 @@ struct CountWidths { // from the Base Multilingual Plane and those from other planes. Sci::Position countBasePlane; Sci::Position countOtherPlanes; - CountWidths(Sci::Position countBasePlane_=0, Sci::Position countOtherPlanes_=0) noexcept : + explicit CountWidths(Sci::Position countBasePlane_=0, Sci::Position countOtherPlanes_=0) noexcept : countBasePlane(countBasePlane_), countOtherPlanes(countOtherPlanes_) { } @@ -1286,7 +1286,7 @@ void CellBuffer::EndUndoAction() { }
void CellBuffer::AddUndoAction(Sci::Position token, bool mayCoalesce) { - bool startSequence; + bool startSequence = false; uh.AppendAction(ActionType::container, token, nullptr, 0, startSequence, mayCoalesce); }
Modified: scintilla/src/CharClassify.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -24,7 +24,7 @@ void CharClassify::SetDefaultCharClasses(bool includeWordClass) { for (int ch = 0; ch < maxChar; ch++) { if (ch == '\r' || ch == '\n') charClass[ch] = CharacterClass::newLine; - else if (ch < 0x20 || ch == ' ') + else if (IsControl(ch) || ch == ' ') charClass[ch] = CharacterClass::space; else if (includeWordClass && (ch >= 0x80 || IsAlphaNumeric(ch) || ch == '_')) charClass[ch] = CharacterClass::word;
Modified: scintilla/src/CharacterType.h 84 lines changed, 57 insertions(+), 27 deletions(-) =================================================================== @@ -12,14 +12,33 @@ namespace Scintilla::Internal {
// Functions for classifying characters
+/** + * Check if a character is a space. + * This is ASCII specific but is safe with chars >= 0x80. + */ constexpr bool IsASpace(int ch) noexcept { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); }
-constexpr bool IsASpaceOrTab(int ch) noexcept { +constexpr bool IsSpaceOrTab(int ch) noexcept { return (ch == ' ') || (ch == '\t'); }
+constexpr bool IsControl(int ch) noexcept { + return ((ch >= 0) && (ch <= 0x1F)) || (ch == 0x7F); +} + +constexpr bool IsEOLCharacter(int ch) noexcept { + return ch == '\r' || ch == '\n'; +} + +constexpr bool IsBreakSpace(int ch) noexcept { + // used for text breaking, treat C0 control character as space. + // by default C0 control character is handled as special representation, + // so not appears in normal text. 0x7F DEL is omitted to simplify the code. + return ch >= 0 && ch <= ' '; +} + constexpr bool IsADigit(int ch) noexcept { return (ch >= '0') && (ch <= '9'); } @@ -57,33 +76,44 @@ constexpr bool IsAlphaNumeric(int ch) noexcept { ((ch >= 'A') && (ch <= 'Z')); }
-/** - * Check if a character is a space. - * This is ASCII specific but is safe with chars >= 0x80. - */ -constexpr bool isspacechar(int ch) noexcept { - return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); -} - -constexpr bool iswordchar(int ch) noexcept { - return IsAlphaNumeric(ch) || ch == '.' || ch == '_'; -} - -constexpr bool iswordstart(int ch) noexcept { - return IsAlphaNumeric(ch) || ch == '_'; -} - -constexpr bool isoperator(int ch) noexcept { - if (IsAlphaNumeric(ch)) - return false; - if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || - ch == '(' || ch == ')' || ch == '-' || ch == '+' || - ch == '=' || ch == '|' || ch == '{' || ch == '}' || - ch == '[' || ch == ']' || ch == ':' || ch == ';' || - ch == '<' || ch == '>' || ch == ',' || ch == '/' || - ch == '?' || ch == '!' || ch == '.' || ch == '~') +constexpr bool IsPunctuation(int ch) noexcept { + switch (ch) { + case '!': + case '"': + case '#': + case '$': + case '%': + case '&': + case ''': + case '(': + case ')': + case '*': + case '+': + case ',': + case '-': + case '.': + case '/': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case '[': + case '\': + case ']': + case '^': + case '_': + case '`': + case '{': + case '|': + case '}': + case '~': return true; - return false; + default: + return false; + } }
// Simple case functions for ASCII supersets.
Modified: scintilla/src/ContractionState.cxx 4 lines changed, 1 insertions(+), 3 deletions(-) =================================================================== @@ -95,9 +95,7 @@ ContractionState<LINE>::ContractionState() noexcept : linesInDocument(1) { }
template <typename LINE> -ContractionState<LINE>::~ContractionState() { - Clear(); -} +ContractionState<LINE>::~ContractionState() = default;
template <typename LINE> void ContractionState<LINE>::EnsureData() {
Modified: scintilla/src/Document.cxx 188 lines changed, 82 insertions(+), 106 deletions(-) =================================================================== @@ -1127,53 +1127,74 @@ bool Document::IsDBCSDualByteAt(Sci::Position pos) const noexcept { && IsDBCSTrailByteNoExcept(cb.CharAt(pos + 1)); }
-static constexpr bool IsSpaceOrTab(int ch) noexcept { - return ch == ' ' || ch == '\t'; -} - -// Need to break text into segments near lengthSegment but taking into -// account the encoding to not break inside a UTF-8 or DBCS character -// and also trying to avoid breaking inside a pair of combining characters. +// Need to break text into segments near end but taking into account the +// encoding to not break inside a UTF-8 or DBCS character and also trying +// to avoid breaking inside a pair of combining characters, or inside +// ligatures. +// TODO: implement grapheme cluster boundaries, +// see https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries. +// // The segment length must always be long enough (more than 4 bytes) // so that there will be at least one whole character to make a segment. // For UTF-8, text must consist only of valid whole characters. // In preference order from best to worst: -// 1) Break after space -// 2) Break before punctuation -// 3) Break after whole character - -int Document::SafeSegment(const char *text, int length, int lengthSegment) const noexcept { - if (length <= lengthSegment) - return length; - int lastSpaceBreak = -1; - int lastPunctuationBreak = -1; - int lastEncodingAllowedBreak = 0; - for (int j=0; j < lengthSegment;) { - const unsigned char ch = text[j]; - if (j > 0) { - if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) { - lastSpaceBreak = j; +// 1) Break before or after spaces or controls +// 2) Break at word and punctuation boundary for better kerning and ligature support +// 3) Break after whole character, this may break combining characters + +size_t Document::SafeSegment(std::string_view text) const noexcept { + // check space first as most written language use spaces. + for (std::string_view::iterator it = text.end() - 1; it != text.begin(); --it) { + if (IsBreakSpace(*it)) { + return it - text.begin(); + } + } + + if (!dbcsCodePage || dbcsCodePage == CpUtf8) { + // backward iterate for UTF-8 and single byte encoding to find word and punctuation boundary. + std::string_view::iterator it = text.end() - 1; + const bool punctuation = IsPunctuation(*it); + do { + --it; + if (punctuation != IsPunctuation(*it)) { + return it - text.begin() + 1; } - if (ch < 'A') { - lastPunctuationBreak = j; + } while (it != text.begin()); + + it = text.end() - 1; + if (dbcsCodePage) { + // for UTF-8 go back to the start of last character. + for (int trail = 0; trail < UTF8MaxBytes - 1 && UTF8IsTrailByte(*it); trail++) { + --it; } } - lastEncodingAllowedBreak = j; + return it - text.begin(); + }
- if (dbcsCodePage == CpUtf8) { - j += UTF8BytesOfLead[ch]; - } else if (dbcsCodePage) { - j += IsDBCSLeadByteNoExcept(ch) ? 2 : 1; - } else { - j++; + { + // forward iterate for DBCS to find word and punctuation boundary. + size_t lastPunctuationBreak = 0; + size_t lastEncodingAllowedBreak = 0; + CharacterClass ccPrev = CharacterClass::space; + for (size_t j = 0; j < text.length();) { + const unsigned char ch = text[j]; + lastEncodingAllowedBreak = j++; + + CharacterClass cc = CharacterClass::word; + if (UTF8IsAscii(ch)) { + if (IsPunctuation(ch)) { + cc = CharacterClass::punctuation; + } + } else { + j += IsDBCSLeadByteNoExcept(ch); + } + if (cc != ccPrev) { + ccPrev = cc; + lastPunctuationBreak = lastEncodingAllowedBreak; + } } + return lastPunctuationBreak ? lastPunctuationBreak : lastEncodingAllowedBreak; } - if (lastSpaceBreak >= 0) { - return lastSpaceBreak; - } else if (lastPunctuationBreak >= 0) { - return lastPunctuationBreak; - } - return lastEncodingAllowedBreak; }
EncodingFamily Document::CodePageFamily() const noexcept { @@ -1218,7 +1239,7 @@ bool Document::DeleteChars(Sci::Position pos, Sci::Position len) { DocModification( ModificationFlags::BeforeDelete | ModificationFlags::User, pos, len, - 0, 0)); + 0, nullptr)); const Sci::Line prevLinesTotal = LinesTotal(); const bool startSavePoint = cb.IsSavePoint(); bool startSequence = false; @@ -2419,7 +2440,7 @@ Sci::Line Document::GetMaxLineState() const noexcept {
void SCI_METHOD Document::ChangeLexerState(Sci_Position start, Sci_Position end) { const DocModification mh(ModificationFlags::LexerState, start, - end-start, 0, 0, 0); + end-start, 0, nullptr, 0); NotifyModified(mh); }
@@ -2432,20 +2453,20 @@ StyledText Document::MarginStyledText(Sci::Line line) const noexcept { void Document::MarginSetText(Sci::Line line, const char *text) { Margins()->SetText(line, text); const DocModification mh(ModificationFlags::ChangeMargin, LineStart(line), - 0, 0, 0, line); + 0, 0, nullptr, line); NotifyModified(mh); }
void Document::MarginSetStyle(Sci::Line line, int style) { Margins()->SetStyle(line, style); NotifyModified(DocModification(ModificationFlags::ChangeMargin, LineStart(line), - 0, 0, 0, line)); + 0, 0, nullptr, line)); }
void Document::MarginSetStyles(Sci::Line line, const unsigned char *styles) { Margins()->SetStyles(line, styles); NotifyModified(DocModification(ModificationFlags::ChangeMargin, LineStart(line), - 0, 0, 0, line)); + 0, 0, nullptr, line)); }
void Document::MarginClearAll() { @@ -2468,7 +2489,7 @@ void Document::AnnotationSetText(Sci::Line line, const char *text) { Annotations()->SetText(line, text); const int linesAfter = AnnotationLines(line); DocModification mh(ModificationFlags::ChangeAnnotation, LineStart(line), - 0, 0, 0, line); + 0, 0, nullptr, line); mh.annotationLinesAdded = linesAfter - linesBefore; NotifyModified(mh); } @@ -2478,7 +2499,7 @@ void Document::AnnotationSetStyle(Sci::Line line, int style) { if (line >= 0 && line < LinesTotal()) { Annotations()->SetStyle(line, style); const DocModification mh(ModificationFlags::ChangeAnnotation, LineStart(line), - 0, 0, 0, line); + 0, 0, nullptr, line); NotifyModified(mh); } } @@ -2511,7 +2532,7 @@ void Document::EOLAnnotationSetText(Sci::Line line, const char *text) { if (line >= 0 && line < LinesTotal()) { EOLAnnotations()->SetText(line, text); const DocModification mh(ModificationFlags::ChangeEOLAnnotation, LineStart(line), - 0, 0, 0, line); + 0, 0, nullptr, line); NotifyModified(mh); } } @@ -2520,7 +2541,7 @@ void Document::EOLAnnotationSetStyle(Sci::Line line, int style) { if (line >= 0 && line < LinesTotal()) { EOLAnnotations()->SetStyle(line, style); const DocModification mh(ModificationFlags::ChangeEOLAnnotation, LineStart(line), - 0, 0, 0, line); + 0, 0, nullptr, line); NotifyModified(mh); } } @@ -2600,49 +2621,8 @@ void Document::NotifyModified(DocModification mh) { } }
-// Used for word part navigation. -static bool IsASCIIPunctuationCharacter(unsigned int ch) noexcept { - switch (ch) { - case '!': - case '"': - case '#': - case '$': - case '%': - case '&': - case ''': - case '(': - case ')': - case '*': - case '+': - case ',': - case '-': - case '.': - case '/': - case ':': - case ';': - case '<': - case '=': - case '>': - case '?': - case '@': - case '[': - case '\': - case ']': - case '^': - case '_': - case '`': - case '{': - case '|': - case '}': - case '~': - return true; - default: - return false; - } -} - bool Document::IsWordPartSeparator(unsigned int ch) const { - return (WordCharacterClass(ch) == CharacterClass::word) && IsASCIIPunctuationCharacter(ch); + return (WordCharacterClass(ch) == CharacterClass::word) && IsPunctuation(ch); }
Sci::Position Document::WordPartLeft(Sci::Position pos) const { @@ -2672,15 +2652,15 @@ Sci::Position Document::WordPartLeft(Sci::Position pos) const { pos -= CharacterBefore(pos).widthBytes; if (!IsADigit(CharacterAfter(pos).character)) pos += CharacterAfter(pos).widthBytes; - } else if (IsASCIIPunctuationCharacter(ceStart.character)) { - while (pos > 0 && IsASCIIPunctuationCharacter(CharacterAfter(pos).character)) + } else if (IsPunctuation(ceStart.character)) { + while (pos > 0 && IsPunctuation(CharacterAfter(pos).character)) pos -= CharacterBefore(pos).widthBytes; - if (!IsASCIIPunctuationCharacter(CharacterAfter(pos).character)) + if (!IsPunctuation(CharacterAfter(pos).character)) pos += CharacterAfter(pos).widthBytes; - } else if (isspacechar(ceStart.character)) { - while (pos > 0 && isspacechar(CharacterAfter(pos).character)) + } else if (IsASpace(ceStart.character)) { + while (pos > 0 && IsASpace(CharacterAfter(pos).character)) pos -= CharacterBefore(pos).widthBytes; - if (!isspacechar(CharacterAfter(pos).character)) + if (!IsASpace(CharacterAfter(pos).character)) pos += CharacterAfter(pos).widthBytes; } else if (!IsASCII(ceStart.character)) { while (pos > 0 && !IsASCII(CharacterAfter(pos).character)) @@ -2723,30 +2703,26 @@ Sci::Position Document::WordPartRight(Sci::Position pos) const { } else if (IsADigit(ceStart.character)) { while (pos < length && IsADigit(CharacterAfter(pos).character)) pos += CharacterAfter(pos).widthBytes; - } else if (IsASCIIPunctuationCharacter(ceStart.character)) { - while (pos < length && IsASCIIPunctuationCharacter(CharacterAfter(pos).character)) + } else if (IsPunctuation(ceStart.character)) { + while (pos < length && IsPunctuation(CharacterAfter(pos).character)) pos += CharacterAfter(pos).widthBytes; - } else if (isspacechar(ceStart.character)) { - while (pos < length && isspacechar(CharacterAfter(pos).character)) + } else if (IsASpace(ceStart.character)) { + while (pos < length && IsASpace(CharacterAfter(pos).character)) pos += CharacterAfter(pos).widthBytes; } else { pos += CharacterAfter(pos).widthBytes; } return pos; }
-static constexpr bool IsLineEndChar(char c) noexcept { - return (c == '\n' || c == '\r'); -} - Sci::Position Document::ExtendStyleRange(Sci::Position pos, int delta, bool singleLine) noexcept { - const int sStart = cb.StyleAt(pos); + const char sStart = cb.StyleAt(pos); if (delta < 0) { - while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) + while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsEOLCharacter(cb.CharAt(pos)))) pos--; pos++; } else { - while (pos < (LengthNoExcept()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) + while (pos < (LengthNoExcept()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsEOLCharacter(cb.CharAt(pos)))) pos++; } return pos; @@ -2986,7 +2962,7 @@ class UTF8Iterator { typedef wchar_t* pointer; typedef wchar_t& reference;
- UTF8Iterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept : + explicit UTF8Iterator(const Document *doc_=nullptr, Sci::Position position_=0) noexcept : doc(doc_), position(position_), characterIndex(0), lenBytes(0), lenCharacters(0), buffered{} { buffered[0] = 0; buffered[1] = 0;
Modified: scintilla/src/Document.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -352,7 +352,7 @@ class Document : PerLine, public Scintilla::IDocument, public Scintilla::ILoader bool IsDBCSTrailByteNoExcept(char ch) const noexcept; int DBCSDrawBytes(std::string_view text) const noexcept; bool IsDBCSDualByteAt(Sci::Position pos) const noexcept; - int SafeSegment(const char *text, int length, int lengthSegment) const noexcept; + size_t SafeSegment(std::string_view text) const noexcept; EncodingFamily CodePageFamily() const noexcept;
// Gateways to modifying document
Modified: scintilla/src/EditView.cxx 107 lines changed, 66 insertions(+), 41 deletions(-) =================================================================== @@ -368,12 +368,6 @@ inline char CaseForce(Style::CaseForce caseForce, char chDoc, char chPrevious) n } }
-constexpr bool IsControlCharacter(int ch) noexcept { - // iscntrl returns true for lots of chars > 127 which are displayable, - // currently only check C0 control characters. - return (ch >= 0 && ch < ' ') || (ch == 127); -} - bool ViewIsASCII(std::string_view text) { return std::all_of(text.cbegin(), text.cend(), IsASCII); } @@ -470,7 +464,7 @@ void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewSt ll->positions[0] = 0; bool lastSegItalics = false;
- BreakFinder bfLayout(ll, nullptr, Range(0, numCharsInLine), posLineStart, 0, false, model.pdoc, &model.reprs, nullptr); + BreakFinder bfLayout(ll, nullptr, Range(0, numCharsInLine), posLineStart, 0, BreakFinder::BreakFor::Text, model.pdoc, &model.reprs, nullptr); while (bfLayout.More()) {
const TextSegment ts = bfLayout.Next(); @@ -570,46 +564,55 @@ void EditView::LayoutLine(const EditModel &model, Surface *surface, const ViewSt ll->wrapIndent = vstyle.aveCharWidth; // Indent to show start visual ll->lines = 0; // Calculate line start positions based upon width. - Sci::Position lastGoodBreak = 0; Sci::Position lastLineStart = 0; - XYACCUMULATOR startOffset = 0; + XYACCUMULATOR startOffset = width; Sci::Position p = 0; - while (p < ll->numCharsInLine) { - if ((ll->positions[p + 1] - startOffset) >= width) { + const Wrap wrapState = vstyle.wrap.state; + const Sci::Position numCharsInLine = ll->numCharsInLine; + while (p < numCharsInLine) { + while (p < numCharsInLine && ll->positions[p + 1] < startOffset) { + p++; + } + if (p < numCharsInLine) { + // backtrack to find lastGoodBreak + Sci::Position lastGoodBreak = p; + if (p > 0) { + lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - posLineStart; + } + if (wrapState != Wrap::Char) { + Sci::Position pos = lastGoodBreak; + while (pos > lastLineStart) { + // style boundary and space + if (wrapState != Wrap::WhiteSpace && (ll->styles[pos - 1] != ll->styles[pos])) { + break; + } + if (IsBreakSpace(ll->chars[pos - 1]) && !IsBreakSpace(ll->chars[pos])) { + break; + } + pos = model.pdoc->MovePositionOutsideChar(pos + posLineStart - 1, -1) - posLineStart; + } + if (pos > lastLineStart) { + lastGoodBreak = pos; + } + } if (lastGoodBreak == lastLineStart) { // Try moving to start of last character if (p > 0) { - lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - - posLineStart; + lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - posLineStart; } if (lastGoodBreak == lastLineStart) { // Ensure at least one character on line. - lastGoodBreak = model.pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1) - - posLineStart; + lastGoodBreak = model.pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1) - posLineStart; } } lastLineStart = lastGoodBreak; ll->lines++; - ll->SetLineStart(ll->lines, static_cast<int>(lastGoodBreak)); - startOffset = ll->positions[lastGoodBreak]; + ll->SetLineStart(ll->lines, static_cast<int>(lastLineStart)); + startOffset = ll->positions[lastLineStart]; // take into account the space for start wrap mark and indent - startOffset -= ll->wrapIndent; - p = lastGoodBreak + 1; - continue; - } - if (p > 0) { - if (vstyle.wrap.state == Wrap::Char) { - lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - - posLineStart; - p = model.pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart; - continue; - } else if ((vstyle.wrap.state == Wrap::Word) && (ll->styles[p] != ll->styles[p - 1])) { - lastGoodBreak = p; - } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) { - lastGoodBreak = p; - } + startOffset += width - ll->wrapIndent; + p = lastLineStart + 1; } - p++; } ll->lines++; } @@ -1636,7 +1639,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } const bool caretBlinkState = (model.caret.active && model.caret.on) || (!additionalCaretsBlink && !mainCaret); const bool caretVisibleState = additionalCaretsVisible || mainCaret; - if ((xposCaret >= 0) && vsDraw.IsCaretVisible() && + if ((xposCaret >= 0) && vsDraw.IsCaretVisible(mainCaret) && (drawDrag || (caretBlinkState && caretVisibleState))) { bool canDrawBlockCaret = true; bool drawBlockCaret = false; @@ -1660,7 +1663,8 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt if (xposCaret > 0) caretWidthOffset = 0.51f; // Move back so overlaps both character cells. xposCaret += xStart; - const ViewStyle::CaretShape caretShape = drawDrag ? ViewStyle::CaretShape::line : vsDraw.CaretShapeForMode(model.inOverstrike); + const ViewStyle::CaretShape caretShape = drawDrag ? ViewStyle::CaretShape::line : + vsDraw.CaretShapeForMode(model.inOverstrike, mainCaret); if (drawDrag) { /* Dragging text, use a line caret */ rcCaret.left = std::round(xposCaret - caretWidthOffset); @@ -1673,7 +1677,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt } else if ((caretShape == ViewStyle::CaretShape::block) || imeCaretBlockOverride) { /* Block caret */ rcCaret.left = xposCaret; - if (canDrawBlockCaret && !(IsControlCharacter(ll->chars[offset]))) { + if (canDrawBlockCaret && !(IsControl(ll->chars[offset]))) { drawBlockCaret = true; rcCaret.right = xposCaret + widthOverstrikeCaret; } else { @@ -1733,6 +1737,21 @@ static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, c } }
+// On the curses platform, the terminal is drawing its own caret, so if the caret is within +// the main selection, do not draw the selection at that position. +// Use iDoc from DrawBackground and DrawForeground here because TextSegment has been adjusted +// such that, if the caret is inside the main selection, the beginning or end of that selection +// is at the end of a text segment. +// This function should only be called if iDoc is within the main selection. +static InSelection CharacterInCursesSelection(Sci::Position iDoc, const EditModel &model, const ViewStyle &vsDraw) { + const SelectionPosition &posCaret = model.sel.RangeMain().caret; + const bool caretAtStart = posCaret < model.sel.RangeMain().anchor && posCaret.Position() == iDoc; + const bool caretAtEnd = posCaret > model.sel.RangeMain().anchor && + vsDraw.DrawCaretInsideSelection(false, false) && + model.pdoc->MovePositionOutsideChar(posCaret.Position() - 1, -1) == iDoc; + return (caretAtStart || caretAtEnd) ? InSelection::inNone : InSelection::inMain; +} + void EditView::DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, Range lineRange, Sci::Position posLineStart, int xStart, int subLine, std::optional<ColourRGBA> background) const { @@ -1743,7 +1762,8 @@ void EditView::DrawBackground(Surface *surface, const EditModel &model, const Vi // Does not take margin into account but not significant const XYPOSITION xStartVisible = static_cast<XYPOSITION>(subLineStart-xStart);
- BreakFinder bfBack(ll, &model.sel, lineRange, posLineStart, xStartVisible, selBackDrawn, model.pdoc, &model.reprs, nullptr); + const BreakFinder::BreakFor breakFor = selBackDrawn ? BreakFinder::BreakFor::Selection : BreakFinder::BreakFor::Text; + BreakFinder bfBack(ll, &model.sel, lineRange, posLineStart, xStartVisible, breakFor, model.pdoc, &model.reprs, &vsDraw);
const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background;
@@ -1766,7 +1786,9 @@ void EditView::DrawBackground(Surface *surface, const EditModel &model, const Vi if (rcSegment.right > rcLine.right) rcSegment.right = rcLine.right;
- const InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + if (FlagSet(vsDraw.caret.style, CaretStyle::Curses) && (inSelection == InSelection::inMain)) + inSelection = CharacterInCursesSelection(iDoc, model, vsDraw); const bool inHotspot = model.hotspot.Valid() && model.hotspot.ContainsCharacter(iDoc); ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, inSelection, inHotspot, ll->styles[i], i); @@ -1959,8 +1981,9 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi const XYPOSITION xStartVisible = static_cast<XYPOSITION>(subLineStart-xStart);
// Foreground drawing loop - BreakFinder bfFore(ll, &model.sel, lineRange, posLineStart, xStartVisible, - (((phasesDraw == PhasesDraw::One) && selBackDrawn) || vsDraw.SelectionTextDrawn()), model.pdoc, &model.reprs, &vsDraw); + const BreakFinder::BreakFor breakFor = (((phasesDraw == PhasesDraw::One) && selBackDrawn) || vsDraw.SelectionTextDrawn()) + ? BreakFinder::BreakFor::ForegroundAndSelection : BreakFinder::BreakFor::Foreground; + BreakFinder bfFore(ll, &model.sel, lineRange, posLineStart, xStartVisible, breakFor, model.pdoc, &model.reprs, &vsDraw);
while (bfFore.More()) {
@@ -2010,7 +2033,9 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi } } } - const InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + InSelection inSelection = hideSelection ? InSelection::inNone : model.sel.CharacterInSelection(iDoc); + if (FlagSet(vsDraw.caret.style, CaretStyle::Curses) && (inSelection == InSelection::inMain)) + inSelection = CharacterInCursesSelection(iDoc, model, vsDraw); const std::optional<ColourRGBA> selectionFore = SelectionForeground(model, vsDraw, inSelection); if (selectionFore) { textFore = *selectionFore;
Modified: scintilla/src/Editor.cxx 12 lines changed, 6 insertions(+), 6 deletions(-) =================================================================== @@ -772,9 +772,9 @@ void Editor::MultipleSelectAdd(AddNumber addNumber) { searchRanges.push_back(rangeTarget); }
- for (std::vector<Range>::const_iterator it = searchRanges.begin(); it != searchRanges.end(); ++it) { - Sci::Position searchStart = it->start; - const Sci::Position searchEnd = it->end; + for (const Range range : searchRanges) { + Sci::Position searchStart = range.start; + const Sci::Position searchEnd = range.end; for (;;) { Sci::Position lengthFound = selectedText.length(); const Sci::Position pos = pdoc->FindText(searchStart, searchEnd, @@ -2193,10 +2193,10 @@ void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Posit sel.RangeMain().caret = RealizeVirtualSpace(sel.RangeMain().caret); const int xInsert = XFromPosition(sel.RangeMain().caret); bool prevCr = false; - while ((len > 0) && IsEOLChar(ptr[len-1])) + while ((len > 0) && IsEOLCharacter(ptr[len-1])) len--; for (Sci::Position i = 0; i < len; i++) { - if (IsEOLChar(ptr[i])) { + if (IsEOLCharacter(ptr[i])) { if ((ptr[i] == '\r') || (!prevCr)) line++; if (line >= pdoc->LinesTotal()) { @@ -7592,7 +7592,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { return vs.ElementColour(Element::Caret)->OpaqueRGB();
case Message::SetCaretStyle: - if (static_cast<CaretStyle>(wParam) <= (CaretStyle::Block | CaretStyle::OverstrikeBlock | CaretStyle::BlockAfter)) + if (static_cast<CaretStyle>(wParam) <= (CaretStyle::Block | CaretStyle::OverstrikeBlock | CaretStyle::Curses | CaretStyle::BlockAfter)) vs.caret.style = static_cast<CaretStyle>(wParam); else /* Default to the line caret */
Modified: scintilla/src/KeyMap.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -67,7 +67,7 @@ const std::map<KeyModifiers, Message> &KeyMap::GetKeyMap() const noexcept {
namespace {
-constexpr Keys Key(char ch) { +constexpr Keys Key(char ch) noexcept { return static_cast<Keys>(ch); }
Modified: scintilla/src/MarginView.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -87,7 +87,7 @@ void DrawWrapMarker(Surface *surface, PRectangle rcPlace, XYPOSITION yBase; int yDir; XYPOSITION halfWidth; - Point At(XYPOSITION xRelative, XYPOSITION yRelative) noexcept { + Point At(XYPOSITION xRelative, XYPOSITION yRelative) const noexcept { return Point(xBase + xDir * xRelative + halfWidth, yBase + yDir * yRelative + halfWidth); } };
Modified: scintilla/src/MarginView.h 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -36,7 +36,7 @@ class MarginView {
void DropGraphics() noexcept; void RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw); - void PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcMargin, const MarginStyle &marginStyle, + void PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOneMargin, const MarginStyle &marginStyle, const EditModel &model, const ViewStyle &vs); void PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, PRectangle rcMargin, const EditModel &model, const ViewStyle &vs);
Modified: scintilla/src/PerLine.cxx 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -102,7 +102,7 @@ void LineMarkers::Init() {
void LineMarkers::InsertLine(Sci::Line line) { if (markers.Length()) { - markers.Insert(line, 0); + markers.Insert(line, nullptr); } }
Modified: scintilla/src/PositionCache.cxx 98 lines changed, 55 insertions(+), 43 deletions(-) =================================================================== @@ -31,6 +31,7 @@ #include "Geometry.h" #include "Platform.h"
+#include "CharacterType.h" #include "CharacterCategoryMap.h" #include "Position.h" #include "UniqueString.h" @@ -547,10 +548,8 @@ namespace { constexpr unsigned int KeyFromString(std::string_view charBytes) noexcept { PLATFORM_ASSERT(charBytes.length() <= 4); unsigned int k=0; - for (size_t i=0; i < charBytes.length(); i++) { - k = k * 0x100; - const unsigned char uc = charBytes[i]; - k += uc; + for (const unsigned char uc : charBytes) { + k = k * 0x100 + uc; } return k; } @@ -562,16 +561,18 @@ constexpr unsigned int representationKeyCrLf = KeyFromString("\r\n"); void SpecialRepresentations::SetRepresentation(std::string_view charBytes, std::string_view value) { if ((charBytes.length() <= 4) && (value.length() <= Representation::maxLength)) { const unsigned int key = KeyFromString(charBytes); - const MapRepresentation::iterator it = mapReprs.find(key); - if (it == mapReprs.end()) { + const bool inserted = mapReprs.insert_or_assign(key, Representation(value)).second; + if (inserted) { // New entry so increment for first byte const unsigned char ucStart = charBytes.empty() ? 0 : charBytes[0]; startByteHasReprs[ucStart]++; + if (key > maxKey) { + maxKey = key; + } if (key == representationKeyCrLf) { crlf = true; } } - mapReprs[key] = Representation(value); } }
@@ -608,6 +609,9 @@ void SpecialRepresentations::ClearRepresentation(std::string_view charBytes) { mapReprs.erase(it); const unsigned char ucStart = charBytes.empty() ? 0 : charBytes[0]; startByteHasReprs[ucStart]--; + if (key == maxKey && startByteHasReprs[ucStart] == 0) { + maxKey = mapReprs.empty() ? 0 : mapReprs.crbegin()->first; + } if (key == representationKeyCrLf) { crlf = false; } @@ -616,7 +620,11 @@ void SpecialRepresentations::ClearRepresentation(std::string_view charBytes) { }
const Representation *SpecialRepresentations::GetRepresentation(std::string_view charBytes) const { - const MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes)); + const unsigned int key = KeyFromString(charBytes); + if (key > maxKey) { + return nullptr; + } + const MapRepresentation::const_iterator it = mapReprs.find(key); if (it != mapReprs.end()) { return &(it->second); } @@ -633,19 +641,11 @@ const Representation *SpecialRepresentations::RepresentationFromCharacter(std::s return nullptr; }
-bool SpecialRepresentations::Contains(std::string_view charBytes) const { - PLATFORM_ASSERT(charBytes.length() <= 4); - const unsigned char ucStart = charBytes.empty() ? 0 : charBytes[0]; - if (!startByteHasReprs[ucStart]) - return false; - const MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes)); - return it != mapReprs.end(); -} - void SpecialRepresentations::Clear() { mapReprs.clear(); - constexpr short none = 0; + constexpr unsigned short none = 0; std::fill(startByteHasReprs, std::end(startByteHasReprs), none); + maxKey = 0; crlf = false; }
@@ -662,7 +662,7 @@ void BreakFinder::Insert(Sci::Position val) { }
BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart_, - XYPOSITION xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw) : + XYPOSITION xStart, BreakFor breakFor, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw) : ll(ll_), lineRange(lineRange_), posLineStart(posLineStart_), @@ -683,7 +683,7 @@ BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lin nextBreak--; }
- if (breakForSelection) { + if (FlagSet(breakFor, BreakFor::Selection)) { const SelectionPosition posStart(posLineStart); const SelectionPosition posEnd(posLineStart + lineRange.end); const SelectionSegment segmentLine(posStart, posEnd); @@ -696,8 +696,23 @@ BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lin Insert(portion.end.Position() - posLineStart); } } + // On the curses platform, the terminal is drawing its own caret, so add breaks around the + // caret in the main selection in order to help prevent the selection from being drawn in + // the caret's cell. + if (FlagSet(pvsDraw->caret.style, CaretStyle::Curses) && !psel->RangeMain().Empty()) { + const Sci::Position caretPos = psel->RangeMain().caret.Position(); + const Sci::Position anchorPos = psel->RangeMain().anchor.Position(); + if (caretPos < anchorPos) { + const Sci::Position nextPos = pdoc->MovePositionOutsideChar(caretPos + 1, 1); + Insert(nextPos - posLineStart); + } else if (caretPos > anchorPos && pvsDraw->DrawCaretInsideSelection(false, false)) { + const Sci::Position prevPos = pdoc->MovePositionOutsideChar(caretPos - 1, -1); + if (prevPos > anchorPos) + Insert(prevPos - posLineStart); + } + } } - if (pvsDraw && pvsDraw->indicatorsSetFore) { + if (FlagSet(breakFor, BreakFor::Foreground) && pvsDraw->indicatorsSetFore) { for (const IDecoration *deco : pdoc->decorations->View()) { if (pvsDraw->indicators[deco->Indicator()].OverridesTextFore()) { Sci::Position startPos = deco->EndRun(posLineStart); @@ -713,12 +728,12 @@ BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lin saeNext = (!selAndEdge.empty()) ? selAndEdge[0] : -1; }
-BreakFinder::~BreakFinder() { -} +BreakFinder::~BreakFinder() noexcept = default;
TextSegment BreakFinder::Next() { - if (subBreak == -1) { + if (subBreak < 0) { const int prev = nextBreak; + const Representation *repr = nullptr; while (nextBreak < lineRange.end) { int charWidth = 1; const char * const chars = &ll->chars[nextBreak]; @@ -730,7 +745,7 @@ TextSegment BreakFinder::Next() { charWidth = pdoc->DBCSDrawBytes(std::string_view(chars, lineRange.end - nextBreak)); } } - const Representation *repr = nullptr; + repr = nullptr; if (preprs->MayContain(ch)) { // Special case \r\n line ends if there is a representation if (ch == '\r' && preprs->ContainsCrLf() && chars[1] == '\n') { @@ -752,35 +767,32 @@ TextSegment BreakFinder::Next() { } else { repr = nullptr; // Optimize -> should remember repr } - if ((nextBreak - prev) < lengthStartSubdivision) { - return TextSegment(prev, nextBreak - prev, repr); - } else { - break; - } + break; } } nextBreak += charWidth; } - if ((nextBreak - prev) < lengthStartSubdivision) { - return TextSegment(prev, nextBreak - prev); + + const int lengthSegment = nextBreak - prev; + if (lengthSegment < lengthStartSubdivision) { + return TextSegment(prev, lengthSegment, repr); } subBreak = prev; } + // Splitting up a long run from prev to nextBreak in lots of approximately lengthEachSubdivision. - // For very long runs add extra breaks after spaces or if no spaces before low punctuation. const int startSegment = subBreak; - if ((nextBreak - subBreak) <= lengthEachSubdivision) { - subBreak = -1; - return TextSegment(startSegment, nextBreak - startSegment); + const int remaining = nextBreak - startSegment; + int lengthSegment = remaining; + if (lengthSegment > lengthEachSubdivision) { + lengthSegment = static_cast<int>(pdoc->SafeSegment(std::string_view(&ll->chars[startSegment], lengthEachSubdivision))); + } + if (lengthSegment < remaining) { + subBreak += lengthSegment; } else { - subBreak += pdoc->SafeSegment(&ll->chars[subBreak], nextBreak-subBreak, lengthEachSubdivision); - if (subBreak >= nextBreak) { - subBreak = -1; - return TextSegment(startSegment, nextBreak - startSegment); - } else { - return TextSegment(startSegment, subBreak - startSegment); - } + subBreak = -1; } + return TextSegment(startSegment, lengthSegment); }
bool BreakFinder::More() const noexcept {
Modified: scintilla/src/PositionCache.h 24 lines changed, 11 insertions(+), 13 deletions(-) =================================================================== @@ -10,14 +10,6 @@
namespace Scintilla::Internal {
-inline constexpr bool IsEOLChar(int ch) noexcept { - return (ch == '\r') || (ch == '\n'); -} - -inline constexpr bool IsSpaceOrTab(int ch) noexcept { - return ch == ' ' || ch == '\t'; -} - /** * A point in document space. * Uses double for sufficient resolution in large (>20,000,000 line) documents. @@ -208,7 +200,8 @@ typedef std::map<unsigned int, Representation> MapRepresentation;
class SpecialRepresentations { MapRepresentation mapReprs; - short startByteHasReprs[0x100] {}; + unsigned short startByteHasReprs[0x100] {}; + unsigned int maxKey = 0; bool crlf = false; public: void SetRepresentation(std::string_view charBytes, std::string_view value); @@ -217,7 +210,6 @@ class SpecialRepresentations { void ClearRepresentation(std::string_view charBytes); const Representation *GetRepresentation(std::string_view charBytes) const; const Representation *RepresentationFromCharacter(std::string_view charBytes) const; - bool Contains(std::string_view charBytes) const; bool ContainsCrLf() const noexcept { return crlf; } @@ -250,7 +242,7 @@ class BreakFinder { int saeNext; int subBreak; const Document *pdoc; - EncodingFamily encodingFamily; + const EncodingFamily encodingFamily; const SpecialRepresentations *preprs; void Insert(Sci::Position val); public: @@ -259,14 +251,20 @@ class BreakFinder { enum { lengthStartSubdivision = 300 }; // Try to make each subdivided run lengthEachSubdivision or shorter. enum { lengthEachSubdivision = 100 }; + enum class BreakFor { + Text = 0, + Selection = 1, + Foreground = 2, + ForegroundAndSelection = 3, + }; BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, Sci::Position posLineStart_, - XYPOSITION xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw); + XYPOSITION xStart, BreakFor breakFor, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw); // Deleted so BreakFinder objects can not be copied. BreakFinder(const BreakFinder &) = delete; BreakFinder(BreakFinder &&) = delete; void operator=(const BreakFinder &) = delete; void operator=(BreakFinder &&) = delete; - ~BreakFinder(); + ~BreakFinder() noexcept; TextSegment Next(); bool More() const noexcept; };
Modified: scintilla/src/ViewStyle.cxx 32 lines changed, 13 insertions(+), 19 deletions(-) =================================================================== @@ -136,8 +136,6 @@ ViewStyle::ViewStyle(size_t stylesSize_) : Element::SelectionBack, Element::SelectionInactiveBack, }); - selection.layer = Layer::Base; - selection.eolFilled = false;
foldmarginColour.reset(); foldmarginHighlightColour.reset(); @@ -155,15 +153,9 @@ ViewStyle::ViewStyle(size_t stylesSize_) : Element::Caret, Element::CaretAdditional, }); - caret.style = CaretStyle::Line; - caret.width = 1;
elementColours.erase(Element::CaretLineBack); elementAllowsTranslucent.insert(Element::CaretLineBack); - caretLine.alwaysShow = false; - caretLine.subLine = false; - caretLine.layer = Layer::Base; - caretLine.frame = 0;
someStylesProtected = false; someStylesForceCase = false; @@ -210,12 +202,6 @@ ViewStyle::ViewStyle(size_t stylesSize_) : ctrlCharPadding = 3; // +3 For a blank on front and rounded edge each side lastSegItalicsOffset = 2;
- wrap.state = Wrap::None; - wrap.visualFlags = WrapVisualFlag::None; - wrap.visualFlagsLocation = WrapVisualLocation::Default; - wrap.visualStartIndent = 0; - wrap.indentMode = WrapIndentMode::Fixed; - localeName = localeNameDefault; }
@@ -661,26 +647,34 @@ bool ViewStyle::SetWrapIndentMode(WrapIndentMode wrapIndentMode_) noexcept {
bool ViewStyle::IsBlockCaretStyle() const noexcept { return ((caret.style & CaretStyle::InsMask) == CaretStyle::Block) || - FlagSet(caret.style, CaretStyle::OverstrikeBlock); + FlagSet(caret.style, CaretStyle::OverstrikeBlock) || + FlagSet(caret.style, CaretStyle::Curses); }
-bool ViewStyle::IsCaretVisible() const noexcept { - return caret.width > 0 && caret.style != CaretStyle::Invisible; +bool ViewStyle::IsCaretVisible(bool isMainSelection) const noexcept { + return caret.width > 0 && + ((caret.style & CaretStyle::InsMask) != CaretStyle::Invisible || + (FlagSet(caret.style, CaretStyle::Curses) && !isMainSelection)); // only draw additional selections in curses mode }
bool ViewStyle::DrawCaretInsideSelection(bool inOverstrike, bool imeCaretBlockOverride) const noexcept { if (FlagSet(caret.style, CaretStyle::BlockAfter)) return false; return ((caret.style & CaretStyle::InsMask) == CaretStyle::Block) || (inOverstrike && FlagSet(caret.style, CaretStyle::OverstrikeBlock)) || - imeCaretBlockOverride; + imeCaretBlockOverride || + FlagSet(caret.style, CaretStyle::Curses); }
-ViewStyle::CaretShape ViewStyle::CaretShapeForMode(bool inOverstrike) const noexcept { +ViewStyle::CaretShape ViewStyle::CaretShapeForMode(bool inOverstrike, bool isMainSelection) const noexcept { if (inOverstrike) { return (FlagSet(caret.style, CaretStyle::OverstrikeBlock)) ? CaretShape::block : CaretShape::bar; }
+ if (FlagSet(caret.style, CaretStyle::Curses) && !isMainSelection) { + return CaretShape::block; + } + const CaretStyle caretStyle = caret.style & CaretStyle::InsMask; return (caretStyle <= CaretStyle::Block) ? static_cast<CaretShape>(caretStyle) : CaretShape::line; }
Modified: scintilla/src/ViewStyle.h 38 lines changed, 19 insertions(+), 19 deletions(-) =================================================================== @@ -47,40 +47,40 @@ inline std::optional<ColourRGBA> OptionalColour(Scintilla::uptr_t wParam, Scinti
struct SelectionAppearance { // Whether to draw on base layer or over text - Scintilla::Layer layer; + Scintilla::Layer layer = Layer::Base; // Draw selection past line end characters up to right border - bool eolFilled; + bool eolFilled = false; };
struct CaretLineAppearance { // Whether to draw on base layer or over text - Scintilla::Layer layer; + Scintilla::Layer layer = Layer::Base; // Also show when non-focused - bool alwaysShow; + bool alwaysShow = false; // highlight sub line instead of whole line - bool subLine; + bool subLine = false; // Non-0: draw a rectangle around line instead of filling line. Value is pixel width of frame - int frame; + int frame = 0; };
struct CaretAppearance { // Line, block, over-strike bar ... - Scintilla::CaretStyle style; + Scintilla::CaretStyle style = CaretStyle::Line; // Width in pixels - int width; + int width = 1; };
struct WrapAppearance { // No wrapping, word, character, whitespace appearance - Scintilla::Wrap state; + Scintilla::Wrap state = Wrap::None; // Show indication of wrap at line end, line start, or in margin - Scintilla::WrapVisualFlag visualFlags; + Scintilla::WrapVisualFlag visualFlags = WrapVisualFlag::None; // Show indication near margin or near text - Scintilla::WrapVisualLocation visualFlagsLocation; + Scintilla::WrapVisualLocation visualFlagsLocation = WrapVisualLocation::Default; // How much indentation to show wrapping - int visualStartIndent; - // WrapIndentMode::Fixed, _SAME, _INDENT, _DEEPINDENT - Scintilla::WrapIndentMode indentMode; + int visualStartIndent = 0; + // WrapIndentMode::Fixed, Same, Indent, DeepIndent + Scintilla::WrapIndentMode indentMode = WrapIndentMode::Fixed; };
struct EdgeProperties { @@ -137,10 +137,10 @@ class ViewStyle { /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin int leftMarginWidth; ///< Spacing margin on left of text int rightMarginWidth; ///< Spacing margin on right of text - int maskInLine; ///< Mask for markers to be put into text because there is nowhere for them to go in margin - int maskDrawInText; ///< Mask for markers that always draw in text + int maskInLine = 0; ///< Mask for markers to be put into text because there is nowhere for them to go in margin + int maskDrawInText = 0; ///< Mask for markers that always draw in text std::vector<MarginStyle> ms; - int fixedColumnWidth; ///< Total width of margins + int fixedColumnWidth = 0; ///< Total width of margins bool marginInside; ///< true: margin included in text view, false: separate views int textStart; ///< Starting x position of text within the view int zoomLevel; @@ -235,9 +235,9 @@ class ViewStyle {
enum class CaretShape { invisible, line, block, bar }; bool IsBlockCaretStyle() const noexcept; - bool IsCaretVisible() const noexcept; + bool IsCaretVisible(bool isMainSelection) const noexcept; bool DrawCaretInsideSelection(bool inOverstrike, bool imeCaretBlockOverride) const noexcept; - CaretShape CaretShapeForMode(bool inOverstrike) const noexcept; + CaretShape CaretShapeForMode(bool inOverstrike, bool isMainSelection) const noexcept;
private: void AllocStyles(size_t sizeNew);
Modified: scintilla/src/XPM.cxx 29 lines changed, 10 insertions(+), 19 deletions(-) =================================================================== @@ -7,6 +7,7 @@
#include <cstdlib> #include <cstring> +#include <climits>
#include <stdexcept> #include <string_view> @@ -92,17 +93,14 @@ XPM::XPM(const char *const *linesForm) { Init(linesForm); }
-XPM::~XPM() { -} - void XPM::Init(const char *textForm) { // Test done is two parts to avoid possibility of overstepping the memory // if memcmp implemented strangely. Must be 4 bytes at least at destination. if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) { // Build the lines form out of the text form std::vector<const char *> linesForm = LinesFormFromTextForm(textForm); if (!linesForm.empty()) { - Init(&linesForm[0]); + Init(linesForm.data()); } } else { // It is really in line form @@ -146,7 +144,7 @@ void XPM::Init(const char *const *linesForm) { colourCodeTable[static_cast<unsigned char>(code)] = colour; }
- for (int y=0; y<height; y++) { + for (ptrdiff_t y=0; y<height; y++) { const char *lform = linesForm[y+nColours+1]; const size_t len = MeasureLength(lform); for (size_t x = 0; x<len; x++) @@ -241,19 +239,16 @@ RGBAImage::RGBAImage(const XPM &xpm) { } }
-RGBAImage::~RGBAImage() { -} - int RGBAImage::CountBytes() const noexcept { return width * height * 4; }
const unsigned char *RGBAImage::Pixels() const noexcept { - return &pixelBytes[0]; + return pixelBytes.data(); }
void RGBAImage::SetPixel(int x, int y, ColourRGBA colour) noexcept { - unsigned char *pixel = &pixelBytes[0] + (y * width + x) * 4; + unsigned char *pixel = pixelBytes.data() + (y * width + x) * 4; // RGBA pixel[0] = colour.GetRed(); pixel[1] = colour.GetGreen(); @@ -267,9 +262,9 @@ void RGBAImage::BGRAFromRGBA(unsigned char *pixelsBGRA, const unsigned char *pix 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 / 255; - pixelsBGRA[1] = pixelsRGBA[1] * alpha / 255; - pixelsBGRA[0] = pixelsRGBA[2] * alpha / 255; + pixelsBGRA[2] = pixelsRGBA[0] * alpha / UCHAR_MAX; + pixelsBGRA[1] = pixelsRGBA[1] * alpha / UCHAR_MAX; + pixelsBGRA[0] = pixelsRGBA[2] * alpha / UCHAR_MAX; pixelsBGRA[3] = alpha; pixelsRGBA += bytesPerPixel; pixelsBGRA += bytesPerPixel; @@ -279,10 +274,6 @@ void RGBAImage::BGRAFromRGBA(unsigned char *pixelsBGRA, const unsigned char *pix RGBAImageSet::RGBAImageSet() : height(-1), width(-1) { }
-RGBAImageSet::~RGBAImageSet() { - Clear(); -} - /// Remove all images. void RGBAImageSet::Clear() noexcept { images.clear(); @@ -307,7 +298,7 @@ RGBAImage *RGBAImageSet::Get(int ident) { }
/// Give the largest height of the set. -int RGBAImageSet::GetHeight() const { +int RGBAImageSet::GetHeight() const noexcept { if (height < 0) { for (const std::pair<const int, std::unique_ptr<RGBAImage>> &image : images) { if (height < image.second->GetHeight()) { @@ -319,7 +310,7 @@ int RGBAImageSet::GetHeight() const { }
/// Give the largest width of the set. -int RGBAImageSet::GetWidth() const { +int RGBAImageSet::GetWidth() const noexcept { if (width < 0) { for (const std::pair<const int, std::unique_ptr<RGBAImage>> &image : images) { if (width < image.second->GetWidth()) {
Modified: scintilla/src/XPM.h 20 lines changed, 2 insertions(+), 18 deletions(-) =================================================================== @@ -25,11 +25,6 @@ class XPM { public: explicit XPM(const char *textForm); explicit XPM(const char *const *linesForm); - XPM(const XPM &) = default; - XPM(XPM &&) noexcept = default; - XPM &operator=(const XPM &) = default; - XPM &operator=(XPM &&) noexcept = default; - ~XPM(); void Init(const char *textForm); void Init(const char *const *linesForm); /// Decompose image into runs and use FillRectangle for each run @@ -53,11 +48,6 @@ class RGBAImage { static constexpr size_t bytesPerPixel = 4; RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_); explicit RGBAImage(const XPM &xpm); - RGBAImage(const RGBAImage &) = default; - RGBAImage(RGBAImage &&) noexcept = default; - RGBAImage &operator=(const RGBAImage &) = default; - RGBAImage &operator=(RGBAImage &&) noexcept = default; - virtual ~RGBAImage(); int GetHeight() const noexcept { return height; } int GetWidth() const noexcept { return width; } float GetScale() const noexcept { return scale; } @@ -79,22 +69,16 @@ class RGBAImageSet { mutable int width; ///< Memorize largest width of the set. public: RGBAImageSet(); - // Deleted so RGBAImageSet objects can not be copied. - RGBAImageSet(const RGBAImageSet &) = delete; - RGBAImageSet(RGBAImageSet &&) = delete; - RGBAImageSet &operator=(const RGBAImageSet &) = delete; - RGBAImageSet &operator=(RGBAImageSet &&) = delete; - ~RGBAImageSet(); /// Remove all images. void Clear() noexcept; /// Add an image. void AddImage(int ident, std::unique_ptr<RGBAImage> image); /// Get image by id. RGBAImage *Get(int ident); /// Give the largest height of the set. - int GetHeight() const; + int GetHeight() const noexcept; /// Give the largest width of the set. - int GetWidth() const; + int GetWidth() const noexcept; };
}
Modified: scintilla/version.txt 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1 +1 @@ -513 +514
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).